Orbit Framework
An ultra-modern, asynchronous, cross-platform C++ Web Framework.
Loading...
Searching...
No Matches
GraphQL.hpp
Go to the documentation of this file.
1#pragma once
4#include <functional>
5#include <string>
6#include <orbit/http/json.hpp>
7
8namespace middleware {
9
15using GraphQLExecutor = std::function<nlohmann::json(const std::string& query, const std::string& operation_name, const nlohmann::json& variables)>;
16
24inline std::function<bool(http::HttpRequest&, std::shared_ptr<http::ResponseWriter>)> graphql(GraphQLExecutor executor) {
25 return [executor](http::HttpRequest& req, std::shared_ptr<http::ResponseWriter> res) -> bool {
26 std::string query;
27 std::string operation_name;
29
30 if (req.method == http::HttpMethod::POST) {
31 if (req.headers.count("Content-Type") && req.headers.at("Content-Type").find("application/json") != std::string::npos) {
32 auto body = req.json();
33 if (body.contains("query") && body["query"].is_string()) {
34 query = body["query"].get<std::string>();
35 }
36 if (body.contains("operationName") && body["operationName"].is_string()) {
37 operation_name = body["operationName"].get<std::string>();
38 }
39 if (body.contains("variables") && body["variables"].is_object()) {
40 variables = body["variables"];
41 }
42 } else if (req.headers.count("Content-Type") && req.headers.at("Content-Type").find("application/graphql") != std::string::npos) {
43 query = req.body;
44 }
45 } else if (req.method == http::HttpMethod::GET) {
46 // Parse from URL parameters
47 auto it_query = req.query.find("query");
48 if (it_query != req.query.end()) query = it_query->second;
49
50 auto it_op = req.query.find("operationName");
51 if (it_op != req.query.end()) operation_name = it_op->second;
52
53 auto it_vars = req.query.find("variables");
54 if (it_vars != req.query.end()) {
55 try {
56 variables = nlohmann::json::parse(it_vars->second);
57 } catch (...) {
58 // Ignore or handle invalid JSON variables in GET
59 }
60 }
61 }
62
63 if (query.empty()) {
64 http::HttpResponse response;
66 response.json(std::string("{\"errors\": [{\"message\": \"GraphQL query is missing\"}]}"));
67 res->send(std::move(response));
68 return false;
69 }
70
71 try {
72 nlohmann::json result = executor(query, operation_name, variables);
73 http::HttpResponse response;
75 response.json(std::string(result.dump()));
76 res->send(std::move(response));
77 } catch (const std::exception& e) {
78 http::HttpResponse response;
80 response.json(std::string("{\"errors\": [{\"message\": \"") + e.what() + "\"}]}");
81 res->send(std::move(response));
82 }
83
84 return false; // Stop middleware chain, response sent
85 };
86}
87
88} // namespace middleware
Represents an HTTP response to be sent to a client.
Definition HttpResponse.hpp:50
HttpResponse & json(const std::string &j) &
Sets the response body as JSON from a string.
Definition HttpResponse.hpp:123
HttpResponse & send(const std::string &b) &
Sets the response body as plain text.
Definition HttpResponse.hpp:116
HttpStatus status_code
Definition HttpResponse.hpp:53
a class to store JSON values
Definition json.hpp:19401
static basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition json.hpp:23317
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition json.hpp:20574
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition json.hpp:21046
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition json.hpp:20315
Definition Compress.hpp:4
std::function< bool(http::HttpRequest &, std::shared_ptr< http::ResponseWriter >)> graphql(GraphQLExecutor executor)
Creates a middleware handler for GraphQL endpoints. It parses the incoming GET or POST request accord...
Definition GraphQL.hpp:24
std::function< nlohmann::json(const std::string &query, const std::string &operation_name, const nlohmann::json &variables)> GraphQLExecutor
Signature for a GraphQL executor function. Takes the query string, operation name (optional),...
Definition GraphQL.hpp:15
basic_json<> json
default specialization
Definition json.hpp:3422
Represents an incoming HTTP request.
Definition HttpRequest.hpp:22
nlohmann::json json() const
Parses and returns the request body as a JSON object.
Definition HttpRequest.hpp:42
std::string_view body
Definition HttpRequest.hpp:28
std::unordered_map< std::string, std::string > query
Definition HttpRequest.hpp:25
HttpMethod method
Definition HttpRequest.hpp:23
std::unordered_map< std::string_view, std::string_view, utils::CaseInsensitiveHash, utils::CaseInsensitiveEqual > headers
Definition HttpRequest.hpp:27