graphql setup

This commit is contained in:
João Geonizeli
2022-07-21 10:55:38 -03:00
parent 705a465292
commit 0681e5f766
21 changed files with 202 additions and 0 deletions

View File

@@ -35,6 +35,8 @@ gem "devise", "~> 4.8"
gem "omniauth", "~> 1.9.1" gem "omniauth", "~> 1.9.1"
gem "omniauth-google-oauth2", "~> 0.8.2" gem "omniauth-google-oauth2", "~> 0.8.2"
gem "graphql", "~> 2.0"
group :development, :test do group :development, :test do
gem "dotenv-rails", "~> 2.7" gem "dotenv-rails", "~> 2.7"
gem "rspec-rails", "~> 5.1" gem "rspec-rails", "~> 5.1"
@@ -48,6 +50,7 @@ group :development do
gem "annotate", "~> 3.2" gem "annotate", "~> 3.2"
gem "rails-erd", "~> 1.7" gem "rails-erd", "~> 1.7"
gem "web-console" gem "web-console"
gem "graphql_playground-rails"
end end
group :test do group :test do

View File

@@ -124,6 +124,12 @@ GEM
formtastic_i18n (0.7.0) formtastic_i18n (0.7.0)
globalid (1.0.0) globalid (1.0.0)
activesupport (>= 5.0) activesupport (>= 5.0)
graphiql-rails (1.8.0)
railties
sprockets-rails
graphql (2.0.12)
graphql_playground-rails (2.1.0)
rails (>= 5.1.0)
has_scope (0.8.0) has_scope (0.8.0)
actionpack (>= 5.2) actionpack (>= 5.2)
activesupport (>= 5.2) activesupport (>= 5.2)
@@ -340,6 +346,9 @@ DEPENDENCIES
enumerize (~> 2.5) enumerize (~> 2.5)
factory_bot_rails (~> 6.2) factory_bot_rails (~> 6.2)
faker (~> 2.21) faker (~> 2.21)
graphiql-rails
graphql (~> 2.0)
graphql_playground-rails
image_processing (~> 1.2) image_processing (~> 1.2)
importmap-rails importmap-rails
jbuilder jbuilder

View File

@@ -0,0 +1,50 @@
class GraphqlController < ApplicationController
# If accessing from outside this domain, nullify the session
# This allows for outside API access while preventing CSRF attacks,
# but you'll have to authenticate your user separately
# protect_from_forgery with: :null_session
def execute
variables = prepare_variables(params[:variables])
query = params[:query]
operation_name = params[:operationName]
context = {
# Query context goes here, for example:
# current_user: current_user,
}
result = ProgressTestSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
render json: result
rescue StandardError => e
raise e unless Rails.env.development?
handle_error_in_development(e)
end
private
# Handle variables in form data, JSON body, or a blank value
def prepare_variables(variables_param)
case variables_param
when String
if variables_param.present?
JSON.parse(variables_param) || {}
else
{}
end
when Hash
variables_param
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
def handle_error_in_development(e)
logger.error e.message
logger.error e.backtrace.join("\n")
render json: { errors: [{ message: e.message, backtrace: e.backtrace }], data: {} }, status: 500
end
end

View File

View File

@@ -0,0 +1,8 @@
module Mutations
class BaseMutation < GraphQL::Schema::RelayClassicMutation
argument_class Types::BaseArgument
field_class Types::BaseField
input_object_class Types::BaseInputObject
object_class Types::BaseObject
end
end

View File

@@ -0,0 +1,37 @@
class ProgressTestSchema < GraphQL::Schema
mutation(Types::MutationType)
query(Types::QueryType)
# For batch-loading (see https://graphql-ruby.org/dataloader/overview.html)
use GraphQL::Dataloader
# GraphQL-Ruby calls this when something goes wrong while running a query:
def self.type_error(err, context)
# if err.is_a?(GraphQL::InvalidNullError)
# # report to your bug tracker here
# return nil
# end
super
end
# Union and Interface Resolution
def self.resolve_type(abstract_type, obj, ctx)
# TODO: Implement this method
# to return the correct GraphQL object type for `obj`
raise(GraphQL::RequiredImplementationMissingError)
end
# Relay-style Object Identification:
# Return a string UUID for `object`
def self.id_from_object(object, type_definition, query_ctx)
# For example, use Rails' GlobalID library (https://github.com/rails/globalid):
object.to_gid_param
end
# Given a string UUID, find the object
def self.object_from_id(global_id, query_ctx)
# For example, use Rails' GlobalID library (https://github.com/rails/globalid):
GlobalID.find(global_id)
end
end

0
app/graphql/types/.keep Normal file
View File

View File

@@ -0,0 +1,4 @@
module Types
class BaseArgument < GraphQL::Schema::Argument
end
end

View File

@@ -0,0 +1,6 @@
module Types
class BaseConnection < Types::BaseObject
# add `nodes` and `pageInfo` fields, as well as `edge_type(...)` and `node_nullable(...)` overrides
include GraphQL::Types::Relay::ConnectionBehaviors
end
end

View File

@@ -0,0 +1,6 @@
module Types
class BaseEdge < Types::BaseObject
# add `node` and `cursor` fields, as well as `node_type(...)` override
include GraphQL::Types::Relay::EdgeBehaviors
end
end

View File

@@ -0,0 +1,4 @@
module Types
class BaseEnum < GraphQL::Schema::Enum
end
end

View File

@@ -0,0 +1,5 @@
module Types
class BaseField < GraphQL::Schema::Field
argument_class Types::BaseArgument
end
end

View File

@@ -0,0 +1,5 @@
module Types
class BaseInputObject < GraphQL::Schema::InputObject
argument_class Types::BaseArgument
end
end

View File

@@ -0,0 +1,9 @@
module Types
module BaseInterface
include GraphQL::Schema::Interface
edge_type_class(Types::BaseEdge)
connection_type_class(Types::BaseConnection)
field_class Types::BaseField
end
end

View File

@@ -0,0 +1,7 @@
module Types
class BaseObject < GraphQL::Schema::Object
edge_type_class(Types::BaseEdge)
connection_type_class(Types::BaseConnection)
field_class Types::BaseField
end
end

View File

@@ -0,0 +1,4 @@
module Types
class BaseScalar < GraphQL::Schema::Scalar
end
end

View File

@@ -0,0 +1,6 @@
module Types
class BaseUnion < GraphQL::Schema::Union
edge_type_class(Types::BaseEdge)
connection_type_class(Types::BaseConnection)
end
end

View File

@@ -0,0 +1,10 @@
module Types
class MutationType < Types::BaseObject
# TODO: remove me
field :test_field, String, null: false,
description: "An example field added by the generator"
def test_field
"Hello World"
end
end
end

View File

@@ -0,0 +1,7 @@
module Types
module NodeType
include Types::BaseInterface
# Add the `id` field
include GraphQL::Types::Relay::NodeBehaviors
end
end

View File

@@ -0,0 +1,17 @@
module Types
class QueryType < Types::BaseObject
# Add `node(id: ID!) and `nodes(ids: [ID!]!)`
include GraphQL::Types::Relay::HasNodeField
include GraphQL::Types::Relay::HasNodesField
# Add root-level fields here.
# They will be entry points for queries on your schema.
# TODO: remove me
field :test_field, String, null: false,
description: "An example field added by the generator"
def test_field
"Hello World!"
end
end
end

View File

@@ -1,5 +1,10 @@
Rails.application.routes.draw do Rails.application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' } devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
post "/graphql", to: "graphql#execute"
ActiveAdmin.routes(self) ActiveAdmin.routes(self)
if Rails.env.development?
mount GraphqlPlayground::Rails::Engine, at: "/playground", graphql_path: "/graphql"
end
end end