Class: ElasticGraph::Rack::GraphQLEndpoint

Inherits:
Object
  • Object
show all
Defined in:
elasticgraph-rack/lib/elastic_graph/rack/graphql_endpoint.rb

Overview

A simple Rack wrapper around an ElasticGraph GraphQL endpoint. This can be used for local development, mounted in a Rails application, or run in any other Rack-compatible context.

Examples:

Simple config.ru to run an ElasticGraph endpoint as a Rack application

require "elastic_graph/graphql"
require "elastic_graph/rack/graphql_endpoint"

graphql = ElasticGraph::GraphQL.from_yaml_file("config/settings/development.yaml")
run ElasticGraph::Rack::GraphQLEndpoint.new(graphql)

Instance Method Summary collapse

Constructor Details

#initialize(graphql) ⇒ GraphQLEndpoint

Returns a new instance of GraphQLEndpoint.

Parameters:

  • graphql (ElasticGraph::GraphQL)

    ElasticGraph GraphQL instance



26
27
28
29
# File 'elasticgraph-rack/lib/elastic_graph/rack/graphql_endpoint.rb', line 26

def initialize(graphql)
  @logger = graphql.logger
  @graphql_http_endpoint = graphql.graphql_http_endpoint
end

Instance Method Details

#call(env) ⇒ Array(Integer, Hash<String, String>, Array<String>)

Responds to a Rack request.

Parameters:

  • env (Hash<String, Object>)

    Rack env

Returns:

  • (Array(Integer, Hash<String, String>, Array<String>))


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'elasticgraph-rack/lib/elastic_graph/rack/graphql_endpoint.rb', line 35

def call(env)
  rack_request = ::Rack::Request.new(env)

  # Rack doesn't provide a nice method to provide all HTTP headers. In general,
  # HTTP headers are prefixed with `HTTP_` as per https://stackoverflow.com/a/6318491/16481862,
  # but `Content-Type`, as a "standard" header, isn't exposed that way, sadly.
  headers = env
    .select { |k, v| k.start_with?("HTTP_") }
    .to_h { |k, v| [k.delete_prefix("HTTP_"), v] }
    .merge("Content-Type" => rack_request.content_type)

  request = GraphQL::HTTPRequest.new(
    http_method: rack_request.request_method.downcase.to_sym,
    url: rack_request.url,
    headers: headers,
    body: rack_request.body&.read
  )

  response = @graphql_http_endpoint.process(request)

  [response.status_code, response.headers.transform_keys(&:downcase), [response.body]]
rescue => e
  raise if ENV["RACK_ENV"] == "test"

  @logger.error "Got an exception: #{e.class.name}: #{e.message}\n\n#{e.backtrace.join("\n")}"
  error = {message: e.message, exception_class: e.class, backtrace: e.backtrace}
  [500, {"content-type" => "application/json"}, [::JSON.generate(errors: [error])]]
end