Ruby graphql-ruby: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
[[graphql]] gem for ruby. | [[graphql]] gem for ruby. | ||
{{ | {{ TODO | | ||
needs revisiting }} | needs revisiting }} | ||
Revision as of 03:37, 3 September 2021
graphql gem for ruby.
TODO:
needs revisiting
Documentation
wiki graphql docs https://graphql-ruby.org/guides API docs https://graphql-ruby.org/api-doc/1.12.8/ github https://github.com/rmosolgo/graphql-ruby homepage https://graphql-ruby.org/
Basics
Read graphql to get a general understanding of how graphql works before reading this.
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(MyMutationType) # fields on MyMutationType accessible to schema query(MyQueryType) # fields on MyQueryType accessible to schema # ... end class MyQueryType end class MyMutationType endQueries(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 otherGraphApi::ObjectType
objects as fields
This root object is assigned to the schema using it's methodquery(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 endMutations
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
Syntax
Objects
Fields with Arguments
class User < GraphQL::Schema::Object field :id, Integer # name, returntype field :age, Integer # name, returntype end class MyGraph < GraphQL::Schema::Object field :user, User, do |field| field.argument(:id, Integer, required: true) end endMutations
Mutations are graphql fields that trigger side effects.
- mutations return a hash, that contains all of the fields defined on it.
- mutations may optionally accept arguments
class MyMutation < GraphQL::Schema::RelayClassicMutation argument :username, String, required: true field :message, String, null: true # returns string, allows null field :errors, [String], null, false # returns list of strings, disallows null def resolve(username) # do thing that produces side effect { message: "Hello #{username}", errors: [] } end end class MyMutationRoot < GraphQL::Schema::RelayClassicMutation field :mymutation, mutation: MyMutation # TODO: needs arg?? end class MyGraph < GraphQL::Schema mutation(MyMutationRoot) endConnections
Connections between nodes are expressed as edges.
Edges can be abstracted as connections to support query params, filters, pagination, etc.
See https://graphql-ruby.org/relay/connections.html
# Defines a `ClassType`, with the connection `StudentType`. class ClassType < GraphQL::Schema::Object field :students, StudentConnectionType, connection: true, description: "Students that belong to a class" end class StudentConnectionType < GraphQL::Types::Relay::BaseConnection edge_type StudentEdgeType end class StudentEdgeType < GraphQL::Types::Relay::BaseEdge node_type StudentType end class StudentType < GraphQL::Schema::Object field :id, Integer field :age, Integer field :username, String end