Class: Tina4::GraphQL

Inherits:
Object
  • Object
show all
Defined in:
lib/tina4/graphql.rb

Overview

─── Main GraphQL class ──────────────────────────────────────────────

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(schema = nil) ⇒ GraphQL

Returns a new instance of GraphQL.



755
756
757
758
# File 'lib/tina4/graphql.rb', line 755

def initialize(schema = nil)
  @schema = schema || GraphQLSchema.new
  @executor = GraphQLExecutor.new(@schema)
end

Instance Attribute Details

#schemaObject (readonly)

Return schema as GraphQL SDL string.



772
773
774
# File 'lib/tina4/graphql.rb', line 772

def schema
  @schema
end

Instance Method Details

#execute(query, variables: {}, context: {}, operation_name: nil) ⇒ Object

Execute a query string directly



761
762
763
764
765
766
767
768
769
# File 'lib/tina4/graphql.rb', line 761

def execute(query, variables: {}, context: {}, operation_name: nil)
  parser = GraphQLParser.new(query)
  document = parser.parse
  @executor.execute(document, variables: variables, context: context, operation_name: operation_name)
rescue GraphQLError => e
  { "data" => nil, "errors" => [{ "message" => e.message }] }
rescue => e
  { "data" => nil, "errors" => [{ "message" => "Internal error: #{e.message}" }] }
end

#handle_request(body, context: {}) ⇒ Object

Handle an HTTP request body (JSON string)



808
809
810
811
812
813
814
815
816
817
# File 'lib/tina4/graphql.rb', line 808

def handle_request(body, context: {})
  payload = JSON.parse(body)
  query = payload["query"] || ""
  variables = payload["variables"] || {}
  op_name = payload["operationName"]

  execute(query, variables: variables, context: context, operation_name: op_name)
rescue JSON::ParserError
  { "data" => nil, "errors" => [{ "message" => "Invalid JSON in request body" }] }
end

#introspectObject

Return schema metadata for debugging.



801
802
803
804
805
# File 'lib/tina4/graphql.rb', line 801

def introspect
  queries = @schema.queries.transform_values { |v| { type: v[:type], args: v[:args] || {} } }
  mutations = @schema.mutations.transform_values { |v| { type: v[:type], args: v[:args] || {} } }
  { types: @schema.types.keys, queries: queries, mutations: mutations }
end

#register_route(path = "/graphql") ⇒ Object

── Route Registration ─────────────────────────────────────────────Register a POST /graphql route in the Tina4 router.

gql = Tina4::GraphQL.new(schema)
gql.register_route           # POST /graphql
gql.register_route("/api/graphql")  # custom path


826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
# File 'lib/tina4/graphql.rb', line 826

def register_route(path = "/graphql")
  graphql = self
  Tina4.post path, auth: false do |request, response|
    body = request.body
    result = graphql.handle_request(body, context: { request: request })
    response.json(result)
  end

  # Optional: GET for GraphiQL/introspection
  Tina4.get path, auth: false do |request, response|
    query = request.params["query"]
    if query
      variables = request.params["variables"]
      variables = JSON.parse(variables) if variables.is_a?(String) && !variables.empty?
      result = graphql.execute(query, variables: variables || {}, context: { request: request })
      response.json(result)
    else
      response.html(graphiql_html(path))
    end
  end
end