Class: ElasticGraph::GraphQL::HTTPEndpoint
- Inherits:
-
Object
- Object
- ElasticGraph::GraphQL::HTTPEndpoint
- Defined in:
- lib/elastic_graph/graphql/http_endpoint.rb
Overview
Handles HTTP concerns for when ElasticGraph is served via HTTP. The logic here is based on the graphql.org recommendations:
graphql.org/learn/serving-over-http/#http-methods-headers-and-body
As that recommends, we support queries in 3 different HTTP forms:
-
A standard POST request as application/json with query/operationName/variables in the body.
-
A GET request with ‘query`, `operationName` and `variables` query params in the URL.
-
A POST as application/graphql with a query string in the body.
Note that this is designed to be agnostic to what the calling HTTP context is (for example, AWS Lambda, or Rails, or Rack…). Instead, this uses simple Request/Response value objects that the calling context can easily translate to/from to use this in any HTTP context.
Constant Summary collapse
- APPLICATION_JSON =
"application/json"- APPLICATION_GRAPHQL =
"application/graphql"
Instance Method Summary collapse
-
#initialize(query_executor:, monotonic_clock:, client_resolver:) ⇒ HTTPEndpoint
constructor
A new instance of HTTPEndpoint.
-
#process(request, max_timeout_in_ms: nil, start_time_in_ms: @monotonic_clock.now_in_ms) ⇒ Object
Processes the given HTTP request, returning an HTTP response.
Constructor Details
#initialize(query_executor:, monotonic_clock:, client_resolver:) ⇒ HTTPEndpoint
Returns a new instance of HTTPEndpoint.
34 35 36 37 38 |
# File 'lib/elastic_graph/graphql/http_endpoint.rb', line 34 def initialize(query_executor:, monotonic_clock:, client_resolver:) @query_executor = query_executor @monotonic_clock = monotonic_clock @client_resolver = client_resolver end |
Instance Method Details
#process(request, max_timeout_in_ms: nil, start_time_in_ms: @monotonic_clock.now_in_ms) ⇒ Object
Processes the given HTTP request, returning an HTTP response.
‘max_timeout_in_ms` is not a property of the HTTP request (the calling application will determine it instead!) so it is a separate argument.
Note that this method does not convert exceptions to 500 responses. It’s up to the calling application to do that if it wants to (and to determine how much of the exception to return in the HTTP response…).
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/elastic_graph/graphql/http_endpoint.rb', line 48 def process(request, max_timeout_in_ms: nil, start_time_in_ms: @monotonic_clock.now_in_ms) client_or_response = @client_resolver.resolve(request) return client_or_response if client_or_response.is_a?(HTTPResponse) with_parsed_request(request, max_timeout_in_ms: max_timeout_in_ms) do |parsed| result = @query_executor.execute( parsed.query_string, variables: parsed.variables, operation_name: parsed.operation_name, client: client_or_response, timeout_in_ms: parsed.timeout_in_ms, context: parsed.context, start_time_in_ms: start_time_in_ms ) HTTPResponse.json(200, result.to_h) end rescue RequestExceededDeadlineError HTTPResponse.error(504, "Search exceeded requested timeout.") end |