takarajapaneseramen.com

Mastering GraphQL Mutations with Hot Chocolate in .NET

Written on

Chapter 1: Understanding GraphQL Mutations

In this guide, we'll delve into the concept of mutations in GraphQL. While we have extensively discussed data retrieval, the mechanisms for modifying or removing data have yet to be addressed. Grasping mutations is vital for anyone looking to fully understand GraphQL's capabilities.

This article continues from our prior discussion. If you wish to follow along with the code, I highly suggest referring back to the previous piece. It's also accurate to think of mutations as part of CRUD operations.

Although mutations are structurally similar to queries, their primary function is to facilitate data modifications—be it creating, updating, or deleting records. Essentially, a mutation takes in data that is then processed, often involving database interactions.

Creating a New Todo

To start, we will create a file named Mutation.cs within the service directory. Since mutations need to process data, it's essential to establish the structure of the input.

Moreover, returning information from the creation endpoint can be advantageous for users who may not know the details of the newly created record, like its ID. Therefore, it's beneficial to return this information.

public record AddTodoInput(string Label, string Status);

public class AddTodoPayload

{

public AddTodoPayload(Todo todo)

{

Todo = todo;

}

public Todo Todo { get; }

}

Next, let’s define the mutation itself. Here, the first parameter represents the incoming data, while the second is the database context, which is automatically provided.

Within the mutation, we will create a Todo object and save it into the database, ensuring to return the relevant data afterward.

public class Mutation

{

public async Task<AddTodoPayload> AddTodoAsync(AddTodoInput input, ApplicationDbContext db)

{

Todo todo = new()

{

Label = input.Label,

Status = input.Status,

};

db.Todos.Add(todo);

await db.SaveChangesAsync();

return new AddTodoPayload(todo);

}

}

Now, let's test the functionality. When we run the application, we will observe how the input is structured. First, we must type 'input' followed by the data.

Fantastic! We can now not only retrieve data but also create it. The next phase involves updating existing records.

Updating a Todo

Let’s proceed similarly for updates. Suppose we only want to allow changes to the status of a todo rather than modifying the entire record. With this requirement in mind, let’s implement the necessary modifications.

public record UpdateTodoInput(int Id, string Status);

public class UpdateTodoPayload

{

public UpdateTodoPayload(Todo? todo, bool updated)

{

Todo = todo;

Success = updated;

}

public Todo? Todo { get; }

public bool Success { get; }

}

It's important to note that to update specific entries, we need to verify how many are affected. A zero count may indicate an invalid ID. The frontend could submit either a valid or invalid ID, and we must handle both cases.

public async Task<UpdateTodoPayload> UpdateTodoAsync(UpdateTodoInput input, ApplicationDbContext db)

{

var todo = await db.Todos.FindAsync(input.Id);

var affectedRows = 0;

if (todo is not null)

{

todo.Status = input.Status;

affectedRows = await db.SaveChangesAsync();

}

return new UpdateTodoPayload(todo, affectedRows == 1);

}

Now, let’s verify that everything functions correctly. First, we will observe the current todos. At present, there are four items. We will proceed to update the todo with ID 4 to reflect the 'done' status.

The mutation will closely resemble the one used to create a new todo. From the response, we can confirm that the status has been updated to 'done'. To ensure accuracy, we can rerun the GetTodos query.

Deleting a Todo

As anticipated, the next step involves deletion. What input do we require? You guessed it—just the ID of the todo.

public record DeleteTodoInput(int Id);

public class DeleteTodoPayload

{

public DeleteTodoPayload(bool deleted)

{

Success = deleted;

}

public bool Success { get; }

}

What’s our approach here? First, we need to locate the todo object. If we successfully find it, we can remove it from the database. Once again, the SaveChangesAsync method will indicate how many records were affected. If it returns 1, this confirms the frontend provided the correct ID, and the record exists.

public async Task<DeleteTodoPayload> DeleteTodoAsync(DeleteTodoInput input, ApplicationDbContext db)

{

var todo = await db.Todos.FindAsync(input.Id);

var affectedRows = 0;

if (todo is not null)

{

db.Todos.Remove(todo);

affectedRows = await db.SaveChangesAsync();

}

return new DeleteTodoPayload(affectedRows == 1);

}

Before proceeding with any deletions, let’s examine the current data. We will invoke the GetTodos query to check the existing records. As noted, the status was correctly modified in the previous step.

Now, we are ready to execute the mutation to delete the todo with ID 4. It’s done! To confirm the deletion, we can run the GetTodos query one last time. It works flawlessly. Excellent work!

If you found this article helpful and wish to join our growing community, please hit the follow button! Let's embark on this journey of knowledge together. Your thoughts and feedback are always appreciated, so feel free to share!

Stackademic

Thank you for reading to the end. Before you go, consider supporting the writer by clapping and following! 👏 Connect with us on X | LinkedIn | YouTube | Discord. Explore our other platforms: In Plain English | CoFeed | Venture.

Chapter 2: Video Resources

Learn how to add mutations to a Hot Chocolate 13 GraphQL API in this informative video.

Discover how to implement mutations in a .NET GraphQL API using Hot Chocolate in this detailed tutorial.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Unraveling the 1952 UFO Sightings: A Scientific Perspective

A detailed analysis of the 1952 Washington DC UFO sightings and their implications for understanding extraterrestrial phenomena.

Mastering Conversations: 5 Common Mistakes to Avoid

Discover five common conversational mistakes and learn how to enhance your communication skills for more meaningful connections.

Climate Crisis and Technological Breakthroughs: A Dual Perspective

An exploration of the escalating climate crisis and innovative solutions.

From Lab to Startup: The Chemistry Behind Nitron's Success

Explore the journey of Nitron, a sports drink startup, highlighting key lessons in entrepreneurship drawn from chemistry.

Gardening with Butterflies: My Journey as a Milkweed Enthusiast

Discover my passion for gardening and butterfly conservation through milkweed cultivation and its significance in supporting monarch butterflies.

Unlocking the Power of Metacognition for Lifelong Learning

Discover how metacognition enhances learning outcomes and personal growth through awareness and self-regulation.

How to Break Free from the PKM Cycle of Procrastination and Start Creating Meaningful Notes

Discover how to escape the procrastination trap in personal knowledge management and start creating impactful notes effectively.

Navigating the AI Landscape: A Comprehensive Guide for Enthusiasts

Explore the essentials of AI, including its key players, technologies, and transformative potential across various industries.