Files
grecia/app/controllers/graphql_controller.rb
Finn Heemeyer c984e666ff 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
2022-06-01 11:41:09 +02:00

62 lines
1.8 KiB
Ruby

class GraphqlController < ApplicationController
include FeatureFlags
feature_flag :graphql_api
skip_before_action :verify_authenticity_token
skip_authorization_check
class QueryStringError < StandardError; end
def execute
begin
raise GraphqlController::QueryStringError if query_string.nil?
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 ArgumentError => e
render json: { message: e.message }, status: :bad_request
end
end
private
def query_string
if request.headers["CONTENT_TYPE"] == "application/graphql"
request.body.string
else
params[:query]
end
end
# 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
raise ArgumentError, "Unexpected parameter: #{variables_param}"
end
end
end