graphql setup
This commit is contained in:
3
Gemfile
3
Gemfile
@@ -35,6 +35,8 @@ gem "devise", "~> 4.8"
|
||||
gem "omniauth", "~> 1.9.1"
|
||||
gem "omniauth-google-oauth2", "~> 0.8.2"
|
||||
|
||||
gem "graphql", "~> 2.0"
|
||||
|
||||
group :development, :test do
|
||||
gem "dotenv-rails", "~> 2.7"
|
||||
gem "rspec-rails", "~> 5.1"
|
||||
@@ -48,6 +50,7 @@ group :development do
|
||||
gem "annotate", "~> 3.2"
|
||||
gem "rails-erd", "~> 1.7"
|
||||
gem "web-console"
|
||||
gem "graphql_playground-rails"
|
||||
end
|
||||
|
||||
group :test do
|
||||
|
||||
@@ -124,6 +124,12 @@ GEM
|
||||
formtastic_i18n (0.7.0)
|
||||
globalid (1.0.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)
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
@@ -340,6 +346,9 @@ DEPENDENCIES
|
||||
enumerize (~> 2.5)
|
||||
factory_bot_rails (~> 6.2)
|
||||
faker (~> 2.21)
|
||||
graphiql-rails
|
||||
graphql (~> 2.0)
|
||||
graphql_playground-rails
|
||||
image_processing (~> 1.2)
|
||||
importmap-rails
|
||||
jbuilder
|
||||
|
||||
50
app/controllers/graphql_controller.rb
Normal file
50
app/controllers/graphql_controller.rb
Normal 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
|
||||
0
app/graphql/mutations/.keep
Normal file
0
app/graphql/mutations/.keep
Normal file
8
app/graphql/mutations/base_mutation.rb
Normal file
8
app/graphql/mutations/base_mutation.rb
Normal 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
|
||||
37
app/graphql/progress_test_schema.rb
Normal file
37
app/graphql/progress_test_schema.rb
Normal 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
0
app/graphql/types/.keep
Normal file
4
app/graphql/types/base_argument.rb
Normal file
4
app/graphql/types/base_argument.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
module Types
|
||||
class BaseArgument < GraphQL::Schema::Argument
|
||||
end
|
||||
end
|
||||
6
app/graphql/types/base_connection.rb
Normal file
6
app/graphql/types/base_connection.rb
Normal 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
|
||||
6
app/graphql/types/base_edge.rb
Normal file
6
app/graphql/types/base_edge.rb
Normal 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
|
||||
4
app/graphql/types/base_enum.rb
Normal file
4
app/graphql/types/base_enum.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
module Types
|
||||
class BaseEnum < GraphQL::Schema::Enum
|
||||
end
|
||||
end
|
||||
5
app/graphql/types/base_field.rb
Normal file
5
app/graphql/types/base_field.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
module Types
|
||||
class BaseField < GraphQL::Schema::Field
|
||||
argument_class Types::BaseArgument
|
||||
end
|
||||
end
|
||||
5
app/graphql/types/base_input_object.rb
Normal file
5
app/graphql/types/base_input_object.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
module Types
|
||||
class BaseInputObject < GraphQL::Schema::InputObject
|
||||
argument_class Types::BaseArgument
|
||||
end
|
||||
end
|
||||
9
app/graphql/types/base_interface.rb
Normal file
9
app/graphql/types/base_interface.rb
Normal 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
|
||||
7
app/graphql/types/base_object.rb
Normal file
7
app/graphql/types/base_object.rb
Normal 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
|
||||
4
app/graphql/types/base_scalar.rb
Normal file
4
app/graphql/types/base_scalar.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
module Types
|
||||
class BaseScalar < GraphQL::Schema::Scalar
|
||||
end
|
||||
end
|
||||
6
app/graphql/types/base_union.rb
Normal file
6
app/graphql/types/base_union.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
module Types
|
||||
class BaseUnion < GraphQL::Schema::Union
|
||||
edge_type_class(Types::BaseEdge)
|
||||
connection_type_class(Types::BaseConnection)
|
||||
end
|
||||
end
|
||||
10
app/graphql/types/mutation_type.rb
Normal file
10
app/graphql/types/mutation_type.rb
Normal 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
|
||||
7
app/graphql/types/node_type.rb
Normal file
7
app/graphql/types/node_type.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
module Types
|
||||
module NodeType
|
||||
include Types::BaseInterface
|
||||
# Add the `id` field
|
||||
include GraphQL::Types::Relay::NodeBehaviors
|
||||
end
|
||||
end
|
||||
17
app/graphql/types/query_type.rb
Normal file
17
app/graphql/types/query_type.rb
Normal 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
|
||||
@@ -1,5 +1,10 @@
|
||||
Rails.application.routes.draw do
|
||||
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
|
||||
post "/graphql", to: "graphql#execute"
|
||||
|
||||
ActiveAdmin.routes(self)
|
||||
|
||||
if Rails.env.development?
|
||||
mount GraphqlPlayground::Rails::Engine, at: "/playground", graphql_path: "/graphql"
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user