Graphql-ruby basics

From wikinotes
Revision as of 13:40, 6 September 2021 by Will (talk | contribs) (→‎Schema)

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

Queries(objects)

field docs https://graphql-ruby.org/fields/introduction
field arg docs https://graphql-ruby.org/fields/arguments

TODO:

split this example into multiple examples to more clearly describe one concept at a time

Objects are described heirarchically starting with a single/root GraphApi::ObjectType which exposes other GraphApi::ObjectType objects as fields
This root object is assigned to the schema using it's method query(YourObject).

class MyGraph < GraphQL::Schema::ObjectType

  # ==========
  # user query
  # ==========
  field :user, User do |field|
    field.argument(:name, String, required: true, description: "...")
    field.argument(:family, FamilyType)
  end

  def user(name, family)
    User.find_by(
      firstname: name,
      lastname: family[:last_name],  # fields from input graphql types accessible as snake_cased hash-keys
    )
  end

  # =============
  # project query
  # =============
  field :projectDetails, ProjectDetailsType

  def project
    # you may return a hash with keys satisfying return-type
    { name: "myproject", foo: "bar" }
  end
end

class FamilyType
  field :lastName, String   # fields expected in camelCase
end

class User < GraphQL::Schema::ObjectType
  field # ...
end

class ProjectDetailsType < GraphQL::Schema::ObjectType
  field :name, String
  field :foo, String
end

Mutations

Mutations perform jobs with side-effects (like POST, PATCH, DELETE, ...)

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