GraphQL with .NET Core (Part - VI: Queries & Mutations)
Code samples used in this blog series have been updated to latest version of .NET Core (5.0.4) and GraphQL-Dotnet (4.2.0). Follow this link to get the updated samples.
Queries
We've come to the point, where you should have a good understanding of GraphQL Queries already. Few things you should keep in mind though,
- A query should never change the value of a field. In other words, it should always fetch and never modify
- Queries are executed in parallel. This is a huge improvement over REST APIs as you will see in the example below.
We can query for the store name and an item in parallel as follows,
In REST, we would had to make two separate calls to achieve that scenario.
There are three types of operations you can do with GraphQL
i.e. Query, Mutation and Subscription. It's good to specify an explicit name for whatever operation you are doing. It is very helpful for debugging and server-side logging. In general, we set the operation name after query
, mutation
or subscription
keywords. For example,
query GameByTagQuery($tag: String!){
item(tag: $tag){
title
price
}
}
Mutations
We've been dealing with data fetching so far. But how do you cause side effects on the server-side data? GraphQL
mutation is just the thing you are looking for here. Side effects can be anything ranging from a data insertion, patching, deletion or update
A mutation type also extends from ObjectGraphType
. Following createItem
field creates an item on the server side and returns it.
Notice, we have a new ItemInputType
as query argument. Previously, in Part-V, we had an example where we worked with a scaler type argument. But for passing a complex type as arguments, we have to work differently. Hence, come a new type i.e. InputObjectType
. I've created a new ItemInputType
and extend it from InputObjectGraphType
,
Following code is from DataStore
; it uses a static list so that the newly added item stays on to the Items
collection,
Notice, we have returned the same item to the createItem
field so that we can query nested fields of it. Why so? Because it is the preferred way.
Just like in queries, if the mutation field returns an object type, you can ask for nested fields. This can be useful for fetching the new state of an object after an update. - GraphQL Org.
Before we can run our application, a couple of DI registrations are needed for ItemInputType
and InventoryMutation
,
Last but not least is, you have to register your schema with the newly created mutation object as following,
Now, you can run a mutation within the in-browser IDE with a syntax like following,
mutation {
createItem(item: {tag: "cnc", title: "Command & Conquer: Red Alert 3", price: 9.99}) {
tag
title
price
}
}
It will add the item passed within the item
argument and return the tag
, title
and price
of that newly added item,
You can also use variables to pass in the item argument via the Query Variables
window,