Mutation
Preparation
To support mutations with GraphQL, we need to create a struct to serve as the root, as for queries.
#![allow(unused)] fn main() { // src/schema.rs ... pub(crate) struct QueryRoot; + pub(crate) struct MutationRoot; ... }
#![allow(unused)] fn main() { // src/main.rs ... - use async_graphql::{EmptyMutation, EmptySubscription, Schema}; + use async_graphql::{EmptySubscription, Schema}; ... - type SchemaType = Schema<QueryRoot, EmptyMutation, EmptySubscription>; + type SchemaType = Schema<QueryRoot, MutationRoot, EmptySubscription>; ... #[launch] async fn rocket() -> _ { let db = match set_up_db().await { Ok(db) => db, Err(err) => panic!("{}", err), }; - let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription) + let schema = Schema::build(QueryRoot, MutationRoot, EmptySubscription) .data(db) // Add the database connection to the GraphQL global context .finish(); ... }
Define resolvers
Define the mutation resolvers just like the ones for queries:
#![allow(unused)] fn main() { // src/schema.rs ... #[Object] impl MutationRoot { // For inserting a bakery async fn add_bakery(&self, ctx: &Context<'_>, name: String) -> Result<bakery::Model, DbErr> { let db = ctx.data::<DatabaseConnection>().unwrap(); let res = Bakery::insert(bakery::ActiveModel { name: ActiveValue::Set(name), profit_margin: ActiveValue::Set(0.0), ..Default::default() }) .exec(db) .await?; Bakery::find_by_id(res.last_insert_id) .one(db) .await .map(|b| b.unwrap()) } // For inserting a chef async fn add_chef( &self, ctx: &Context<'_>, name: String, bakery_id: i32, ) -> Result<chef::Model, DbErr> { let db = ctx.data::<DatabaseConnection>().unwrap(); let res = Chef::insert(chef::ActiveModel { name: ActiveValue::Set(name), bakery_id: ActiveValue::Set(bakery_id), ..Default::default() }) .exec(db) .await?; Chef::find_by_id(res.last_insert_id) .one(db) .await .map(|b| b.unwrap()) } } }
Examples:
GraphQL Request:
mutation {
addChefy(name: "Excellent Bakery") {
id,
name,
profitMargin
}
}
Response:
{
"data": {
"addChefy": {
"id": 4,
"name": "Excellent Bakery",
"profitMargin": 0
}
}
}
GraphQL Request:
mutation {
addChef(name: "Chris", bakeryId: 1) {
id,
name,
bakery {
chefs {
name
}
}
}
}
Response:
{
"data": {
"addChef": {
"id": 3,
"name": "Chris",
"bakery": {
"chefs": [
{
"name": "Sanford"
},
{
"name": "Billy"
},
{
"name": "Chris"
}
]
}
}
}
}