Skip to content

Commit 0930a0e

Browse files
authored
[feature] 915 - Update mutations slides (#222)
Update query and mutation slides
1 parent f0f8e93 commit 0930a0e

File tree

1 file changed

+69
-74
lines changed

1 file changed

+69
-74
lines changed

slides/graphql.markdown

Lines changed: 69 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -683,18 +683,30 @@ You can get an access to field arguments in resolver using second argument (args
683683

684684
#### Inside the `query type` you describe the fields which are actually could be fetched from server
685685

686+
`app/graphql/types/query_type.rb`
687+
686688
```ruby
687-
# app/graphql/types/guery_type.rb
688-
Types::QueryType = GraphQL::ObjectType.define do
689-
name "Query"
689+
class Types::QueryType < GraphQL::Schema::Object
690+
field :product,
691+
resolver: Resolvers::Product,
692+
description: 'Fetch a product'
693+
end
694+
```
690695

691-
field :products, [Types::ProductType] do
692-
resolve -> (obj, args, ctx) { Product.all }
693-
end
696+
`app/graphql/resolvers/product.rb`
697+
698+
```ruby
699+
class Resolvers::Product < GraphQL::Schema::Resolver
700+
type Types::ProductType, null: false
701+
702+
argument :id, ID, required: false
703+
704+
def resolve(id: nil)
705+
Product.find(id)
694706
end
695-
```
707+
end
696708

697-
#### In our case we allow client to fetch all products
709+
```
698710

699711
#### `Attention!` Query fields resolvers should always return the instance of object or an collection of objects the field type expects or nil if allowed.
700712

@@ -704,54 +716,73 @@ You can get an access to field arguments in resolver using second argument (args
704716

705717
```graphql
706718
query {
707-
products {
719+
product(id: 10) {
708720
id
709-
title
710-
price
721+
name
711722
}
712723
}
713724
```
714725

715726
```json
716727
{
717728
"data": {
718-
"products": [
719-
{
720-
"id:": "uniqueProductId",
721-
"title": "Sandwitch",
722-
"price": 1.0
723-
},
724-
...
725-
]
729+
"product": {
730+
"id": 10,
731+
"name": "..."
732+
}
726733
}
727734
}
735+
728736
```
729737

730738
---
731739

732740
## Mutations
733741

734-
### Mutations are queries with side effects. Mutations are used to mutate your data. In order to use mutations you need to define a mutation root type that allows for defining fields that can mutate your data.
742+
#### Mutations are queries with side effects. Mutations are used to mutate your data. In order to use mutations you need to define a mutation root type that allows for defining fields that can mutate your data.
735743

736-
### Then add your mutations here:
744+
`app/graphql/types/mutation_type.rb`
737745

738746
```ruby
739-
# app/graphql/types/mutation_type.rb
740-
Types::MutationType = GraphQL::ObjectType.define do
741-
name "Mutation"
747+
class Types::MutationType < ::Types::Base::Object
748+
description '...'
742749

743-
field :addTask, Types::TaskType do
744-
description "Adds a task to list"
750+
field :product_create, mutation: Mutations::Product::Create
751+
end
752+
```
745753

746-
argument :todoListId, !types.ID
747-
argument :title, !types.String
754+
`app/graphql/mutations/product/create.rb`
748755

749-
resolve ->(obj, args, ctx) {
750-
todo_list = TodoList.find(args["todoListId"])
751-
todo_list.tasks.create!(title: args["title"])
752-
}
753-
end
756+
```ruby
757+
class Mutations::Product::Create < GraphQL::Schema::Mutation
758+
description '...'
759+
760+
type Types::ProductType
761+
762+
argument :input, Types::Inputs::ProductCreateInput, required: true
763+
764+
def resolve(input:)
765+
# here you will create product with data in input
754766
end
767+
end
768+
```
769+
770+
--
771+
772+
### Also you create input object, that you will pass from the outside
773+
774+
`app/graphql/types/inputs/product_create_input.rb`
775+
776+
```ruby
777+
class Types::Inputs::ProductCreateInput < GraphQL::Schema::InputObject
778+
graphql_name 'ProductCreateInput'
779+
description 'Input for product creation'
780+
781+
argument :name, String, required: true,
782+
description: 'Name',
783+
prepare: ->(name, _ctx) { name.strip }
784+
end
785+
755786
```
756787

757788
--
@@ -760,63 +791,27 @@ The mutation query would look like:
760791

761792
```graphql
762793
mutation {
763-
addTask(todoListId: 1, title: "Title") {
794+
productCreate(input: { name: 'Test' }) {
764795
id
765-
title
796+
name
766797
}
767798
}
799+
768800
```
769801

770802
And response:
771803

772804
```json
773805
{
774806
"data": {
775-
"addTask": {
807+
"productCreate": {
776808
"id": 10,
777-
"title": "Title"
809+
"name": "Title"
778810
}
779811
}
780812
}
781813
```
782814

783-
--
784-
785-
### Complex resolvers with arguments
786-
787-
#### If you have complex mutations with lots of arguments and business logic its better to refactor them this way:
788-
789-
```ruby
790-
# app/graphql/resolvers/add_task.rb
791-
class Resolvers::AddTask < GraphQL::Function
792-
# arguments passed as "args"
793-
argument :todoListId, !types.ID
794-
argument :title, !types.String
795-
796-
# return type from the mutation
797-
type Types::TaskType
798-
799-
# the mutation method
800-
# _obj - is parent object, which in this case is nil
801-
# args - are the arguments passed
802-
# _ctx - is the GraphQL context (which would be discussed later)
803-
def call(_obj, args, _ctx)
804-
todo_list = TodoList.find(args["todoListId"])
805-
todo_list.tasks.create!(title: args["title"])
806-
end
807-
end
808-
```
809-
810-
#### Then you can use it as field function in mutation query:
811-
812-
```ruby
813-
Types::MutationType = GraphQL::ObjectType.define do
814-
name 'Mutation'
815-
816-
field :addTask, function: Resolvers::AddTask.new
817-
end
818-
```
819-
820815
---
821816

822817
## Error Handling

0 commit comments

Comments
 (0)