Graphql-ruby basics

From wikinotes

Read graphql to get a general understanding of how graphql works before reading this.

Execute Queries

You can test queries without a webserver.

query = "query { projects(id: 1){ name id } }"
MySchema.execute(query)

Schema

  • schemas are assigned a root object for queries(queryable object), and optionally mutations(operations with side effects).
  • objects expose fields(objects) which can have arguments
  • fields/arguments (exposed methods) are written in snake_case, but converted to camelCase when used in queries.
class MySchema < GraphQL::Schema
  mutation(MutationRoot)  # fields on MyMutationType accessible to schema
  query(QueryRoot)        # fields on MyQueryType accessible to schema
  # ...
end

class QueryRoot < GraphQL::Schema::Object
end

class MutationRoot < GraphQL::Schema::Object
end

In graphql SDL.

printer = GraphQL::Schema::Printer.new(MySchema)
puts(printer.print_schema)
schema {
  query:    QueryRoot
  mutation: MutationRoot
}

type QueryRoot {}
type MutationRoot {}

Queries

Queries retrieve information without any side-effects.
They are exposed as fields on your QueryRoot object or objects nested under it.
Fields/Params are defined in snake_case, but in the SDL schema they are camelCase.

Field resolvers are used to produce the return-type for the field.
resolvers can be:

  • methods with same name as field
  • GraphQL::Schema::Resolver subclasses
require 'graphql'

class MySchema < GraphQL::Schema
  query(QueryRoot)
end

class QueryRoot < GraphQL::Schema::Object
  field :hello, String, null: false

  def hello
    return "Hi there!"
  end
end

As graphql SDL.

schema {
  query: QueryRoot
}

type QueryRoot {
  hello: String!
}

Perform Query

query { hello }

Mutations

Mutations perform tasks with side-effects.

require 'graphql'

class MySchema < GraphQL::Schema
  mutation(MutationRoot)
end

class MutationRoot < GraphQL::Schema::Object
  field :my_mutation, mutation: MyMutation
end

class MyMutation < GraphQL::Schema::RelayClassicMutation
  field :foo, String, null: false  # exposes attribute 'foo', of type String, non-nullable
  field :bar, String, null: true

  argument :id, Integer, description: '...'

  # method that runs when mutation is executed
  def resolve(id)
    return { foo: "abc", bar: "def" }  # returns all fields defined on class
  end
end

As graphql SDL.

schema {
  mutation: MutationRoot
}

type MutationRoot {
  myMutation(id: Integer!): MyMutationPayload
}

type MyMutationPayload {
  foo: String!
  bar: String
}

Execute mutation

mutation {
  myMutation(id: 100) {
    foo
    bar
  }
}