Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Last active January 5, 2017 13:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/d9448f17e73787de6fad5242d1437704 to your computer and use it in GitHub Desktop.
Save JoshCheek/d9448f17e73787de6fad5242d1437704 to your computer and use it in GitHub Desktop.
GraphQL with an update (mutation)
require 'graphql'
Post = Struct.new :id, :title, :body, :comments
PostType = GraphQL::ObjectType.define do
name "Post"
description "A blog post"
field :id, !types.Int # the bang means "non nullable"
field :title, !types.String
field :body, !types.String
field :comments, types[!types.String]
end
# Object to define the queries a user can make
QueryRoot = GraphQL::ObjectType.define do
name "Query"
description "The query root of this schema"
# they can query for a post
field :post do
# it returns a post, as defined earlier
type PostType
# they need to include the id of the post they want to query for
argument :id, !types.Int
resolve ->(obj, args, ctx) {
# you might put a SQL or ActiveRecord query in here
args.to_h # => {"id"=>123}
Post.new args[:id], 'a', 'b', ["a"]
}
end
end
# Object to define the mutations. I think we need to distinguish these from
# the queries above because doing this over the web may require mapping its
# semantics to HTTP/REST, eg GET and POST have different server behaviour
MutationRoot = GraphQL::ObjectType.define do
name 'Mutation'
field :createPost, PostType do
argument :title, !types.String
argument :body, !types.String
argument :comments, types[!types.String]
resolve -> (obj, args, ctx) {
# here you would update a database or something
args.to_h # => {"title"=>"testTitle", "body"=>"testBody", "comments"=>["comment1", "comment2"]}
Post.new rand(1000), args[:title], args[:body], args[:comments]
}
end
end
# This composes all the other pieces, we do all queries through it
Schema = GraphQL::Schema.define do
query QueryRoot
mutation MutationRoot
end
require 'pp'
# An example of a query, guessing you'd get this from the body of an HTTP request,
# IDK the mime type
Schema.execute '{
# This next line is valid ruby and means the same thing (ask for the post with an id of 1)
post(id: 123)
# This tells it what we want back, it has to be a subset of what\'s available
{ id
title
}
}' # => {"data"=>{"post"=>{"id"=>123, "title"=>"a"}}}
# This one creates a post, again prob from an HTTP request or a websocket or smth
# there's probably a way to pass the args externally so you don't have to worry
# about escaping, but I haven't looked it up
Schema.execute '
mutation {
# The post data I\'m creating
createPost(
title: "testTitle",
body: "testBody",
comments: ["comment1", "comment2"]
)
# The fields I want sent back
{ id
title
body
comments
}
}
'
# => {"data"=>
# {"createPost"=>
# {"id"=>282,
# "title"=>"testTitle",
# "body"=>"testBody",
# "comments"=>["comment1", "comment2"]}}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment