
Over years working on development, I always had a doubt with the usage of the PATCH method.
On this article I’m going to show an example on the C# .NET Core perspective.
But first, a summary of it:
In ASP.NET Core, a PATCH endpoint is used to apply partial modifications to a resource. It is part of the HTTP/1.1 specification and is particularly useful in RESTful APIs when you want to update only specific fields of a resource rather than sending the entire resource representation.
Basically:
PUT updates an entire resource (replacing it), example:
{ “name”: “John Doe”, “age”: 22, “country”: “BR” }
If you make a PUT to update only the age setting 25 your object should look like this:
{ “name”: “”, “age”: 25, “country”: “” }
So update the entire resource
PATCH is used for partial updates
Key Characteristics of PATCH in NET Core:
- Partial Updates: Unlike PUT, which typically requires a complete representation of the resource, PATCH allows you to send only the fields that need to be updated. This can reduce the amount of data sent over the network.
- Request Format: The request body for a PATCH operation usually contains a JSON object that specifies the fields to be updated and their new values. The format can vary; for example, you might use JSON Merge Patch or JSON Patch.
- Method Implementation: In ASP.NET Core, you can implement a PATCH endpoint using the
[HttpPatch]
attribute in your controller. This helps define a method that will handle incoming PATCH requests. - Routing: The PATCH endpoint typically maps to a specific resource, allowing clients to target a specific item for modification.
This method is really powerful as it can handle multiple operations (insert and remove too).
Code example
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private static List<Product> Products = new List<Product>
{
new Product { Id = 1, Name = "Product 1", Price = 10.0M },
new Product { Id = 2, Name = "Product 2", Price = 20.0M }
};
[HttpPatch("{id}")]
public IActionResult PatchProduct(int id, [FromBody] JsonPatchDocument<Product> patchDoc)
{
if (patchDoc == null)
{
return BadRequest();
}
var product = Products.FirstOrDefault(p => p.Id == id);
if (product == null)
{
return NotFound();
}
patchDoc.ApplyTo(product, ModelState);
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
return NoContent();
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
Explanation of the Example:
PATCH endpoint expect to follow a certain structure. I’m going to cover operations to Add and Remove.
How’s the expected payload
- If you want to UPDATE a field for a certain object
[
{ "op": "replace", "path": "/Name", "value": "Updated Product Name" },
{ "op": "replace", "path": "/Price", "value": 19.99 }
]
- If you want to ADD a new product
[ { “op”: “add”, “path”: “/Name”, “value”: “This is a new product” } ]
- If you want to remove a property
[ { “op”: “remove”, “path”: “/Price” } ]
You can execute this code and see the results.
Conclusion
It’s not often I see developers using almost 100% of the time PUT instead of PATCH.
I hope this article finds helpful.