A collection of utilities for building GraphQL APIs.
Add this line to your application's Gemfile:
gem 'graphql-extras'
And then execute:
$ bundle
The graphql
gem will generate a controller for you with a bunch of boilerplate. This module will encapsulate that boilerplate:
class GraphqlController < ApplicationController
include GraphQL::Extras::Controller
def execute
graphql(schema: MySchema, context: { current_user: current_user })
end
end
This is a subclass of GraphQL::Batch::Loader
that performs eager loading of Active Record associations.
loader = GraphQL::Extras::Batch::AssociationLoader.for(:blog)
loader.load(Post.first)
loader.load_many(Post.all)
This includes a set of convenience methods for query batching.
class Post < GraphQL::Schema::Object
include GraphQL::Extras::Batch::Resolver
field :blog, BlogType, resolve: association(:blog), null: false
field :comments, [CommentType], resolve: association(:comments, preload: { comments: :user }), null: false
field :blog_title, String, null: false
def blog_title
association(object, :blog).then(&:title)
end
end
In your base classes, you should include the GraphQL::Extras::Types
.
class BaseObject < GraphQL::Schema::Object
include GraphQL::Extras::Types
end
class BaseInputObject < GraphQL::Schema::InputObject
include GraphQL::Extras::Types
end
This scalar takes a Date
and transmits it as a string, using ISO 8601 format.
field :birthday, Date, required: true
This scalar takes a DateTime
and transmits it as a string, using ISO 8601 format.
field :created_at, DateTime, required: true
Note: This is just an alias for the ISO8601DateTime
type that is included in the graphql
gem.
This scalar takes a BigDecimal
and transmits it as a string.
field :weight, BigDecimal, required: true
This scalar is used for accepting file uploads.
field :image, Upload, required: true
It achieves this by passing in all file upload parameters through context. This will work out of the box if you're using GraphQL::Extras::Controller
.
Here's an example using CURL:
$ curl -X POST \
-F query='mutation { uploadFile(image: "image") }' \
-F [email protected] \
localhost:3000/graphql
Take note of the correspondence between the value "image"
and the additional HTTP parameter called -F [email protected]
.
See apollo-link-upload for the client-side implementation.
Add the following to your rails_helper.rb
(or spec_helper.rb
).
require "graphql/extras/rspec"
Now, you can run tests like so:
RSpec.describe "hello" do
let(:context) { { name: "Ray" } }
let(:schema) { use_schema(Schema, context: context) }
let(:queries) { graphql_fixture("hello.graphql") }
it "allows easily executing queries" do
result = schema.execute(queries.hello)
expect(result).to be_successful_query
expect(result['data']['hello']).to eq("world")
end
end
The graphql_fixture
method assumes that your queries live in spec/fixtures/graphql
. You can change this assumption with the following configuration:
RSpec.configure do |config|
config.graphql_fixture_path = '/path/to/queries'
end
To install dependencies:
$ bundle install
To run the test suite:
$ bundle exec rspec
Bug reports and pull requests are welcome on GitHub at https://github.com/rzane/graphql-extras.