Add new GraphQL types, schema (with fields) & base mutation
The current consul GraphQL API has two problems. 1) It uses some unnecessary complicated magic to automatically create the GraphQL types and querys using an `api.yml` file. This approach is over-engineered, complex and has no benefits. It's just harder to understand the code for people which are not familiar with the project (like me, lol). 2) It uses a deprecated DSL [1] that is soon going to be removed from `graphql-ruby` completely. We are already seeing deprecation warning because of this (see References). There was one problem. I wanted to create the API so that it is fully backwards compatible with the old one, BUT the old one uses field names which are directly derived from the ruby code, which results in snake_case field names - not the GraphQL way. When I'm using the graphql-ruby Class-based syntax, it automatically creates the fields in camelCase, which breaks backwards-compatibility. So I've added deprecated snake_case field names to keep it backwards-compatible. [1] https://graphql-ruby.org/schema/class_based_api.html
This commit is contained in:
committed by
Javi Martín
parent
5c6ab81c38
commit
c984e666ff
@@ -6,52 +6,56 @@ class GraphqlController < ApplicationController
|
||||
skip_before_action :verify_authenticity_token
|
||||
skip_authorization_check
|
||||
|
||||
class QueryStringError < StandardError
|
||||
end
|
||||
class QueryStringError < StandardError; end
|
||||
|
||||
def query
|
||||
def execute
|
||||
begin
|
||||
if query_string.nil? then raise GraphqlController::QueryStringError end
|
||||
raise GraphqlController::QueryStringError if query_string.nil?
|
||||
|
||||
response = consul_schema.execute query_string, variables: query_variables
|
||||
render json: response, status: :ok
|
||||
result = ConsulSchema.execute(query_string,
|
||||
variables: prepare_variables,
|
||||
context: {},
|
||||
operation_name: params[:operationName]
|
||||
)
|
||||
render json: result
|
||||
rescue GraphqlController::QueryStringError
|
||||
render json: { message: "Query string not present" }, status: :bad_request
|
||||
rescue JSON::ParserError
|
||||
render json: { message: "Error parsing JSON" }, status: :bad_request
|
||||
rescue GraphQL::ParseError
|
||||
render json: { message: "Query string is not valid JSON" }, status: :bad_request
|
||||
rescue
|
||||
unless Rails.env.production? then raise end
|
||||
rescue ArgumentError => e
|
||||
render json: { message: e.message }, status: :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def consul_schema
|
||||
api_types = GraphQL::ApiTypesCreator.create
|
||||
query_type = GraphQL::QueryTypeCreator.create(api_types)
|
||||
|
||||
GraphQL::Schema.define do
|
||||
query query_type
|
||||
max_depth 8
|
||||
max_complexity 2500
|
||||
end
|
||||
end
|
||||
|
||||
def query_string
|
||||
if request.headers["CONTENT_TYPE"] == "application/graphql"
|
||||
request.body.string # request.body.class => StringIO
|
||||
request.body.string
|
||||
else
|
||||
params[:query]
|
||||
end
|
||||
end
|
||||
|
||||
def query_variables
|
||||
if params[:variables].blank? || params[:variables] == "null"
|
||||
# Handle variables in URL query string and JSON body
|
||||
def prepare_variables
|
||||
case variables_param = params[:variables]
|
||||
# URL query string
|
||||
when String
|
||||
if variables_param.present?
|
||||
JSON.parse(variables_param) || {}
|
||||
else
|
||||
{}
|
||||
end
|
||||
# JSON object in request body gets converted to ActionController::Parameters
|
||||
when ActionController::Parameters
|
||||
variables_param.to_unsafe_hash # GraphQL-Ruby will validate name and type of incoming variables.
|
||||
when nil
|
||||
{}
|
||||
else
|
||||
JSON.parse(params[:variables])
|
||||
raise ArgumentError, "Unexpected parameter: #{variables_param}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user