This is just a quick tip on how to implement HttpPatch
method in C# and ASP.NET Web API. Unlike the PUT method, PATCH allows you to send only the field that you’re intending to modify, not the whole object.
For example, when you’re sending PUT request to a REST API, and you want to change someone’s last name in the employee database, you would send the whole employee entity which includes the person’s first name, date of birth, date of hire, position, address, etc. For PATCH, however, you would need to only send the last name field and the new value. It becomes clear, then, why you want to use PATCH instead of PUT – partial update means you don’t need to know the state of the whole entity; besides, it uses less bandwidth.
For this implementation, I am using a a Nuget Package called Microsoft.AspNetCore.JsonPatch
, so you need to install this to get this to work. The examples below were taken from my previous tutorial called Create a Simple Employee Database Management REST API.
There are thee general places you would implement this in your code if you are using the Repository Design pattern – IRepository
interface, your Repository
service, and your Controller
. So, let’s get started and discuss the IEmployeeRepository
interface first.
Content
Define Interface
First, we will define IEmployeeRepository
, our interface. We, then, define the UpdateEmployeePatchAsync
method.
Below is the interface declaration for the Patch interface. In reality, you will also have the Get, Post, Put, and Delete interfaces in this class, but I will only show the Patch stuff for demonstration purposes. Checkout my tutorial I mentioned above for the complete interface declaration.
public interface IEmployeeRepository
{
Task<Employee> UpdateEmployeePatchAsync(int id, JsonPatchDocument employee);
}
As you can see in the code above, this is a simple interface. This is going to be implemented as asynchronously, hence we use Task<object>
syntax. We also pass to it a JsonPatchDocument
parameter.
Implement Service
The EmployeeRepository
class implements the IEmployeeRepository
interface. EmployeeRepository actually represents our Employee entity service, which returns data to a controller. The implementation of the UpdateEmployeePatchAsync
method is shown below.
public class EmployeeRepository : IEmployeeRepository
{
public async Task<Employee> UpdateEmployeePatchAsync(int id, JsonPatchDocument employeeDocument)
{
var employeeQuery = await GetEmployeeByIdAsync(id);
if (employeeQuery == null)
{
return employeeQuery;
}
employeeDocument.ApplyTo(employeeQuery);
await _dbContext.SaveChangesAsync();
return employeeQuery;
}
}
The most important of this code is line 11. Here we use ApplyTo
method to apply the changes(i.e., employeeDocument
) that we made to the current database context(i.e., employeeQuery
).
Also take notice of the GetEmployeeByIdAsync(id)
method. This was a GET method to get a record based on the employee ID. I’m not going to show the implementation of this method, but you may check it out from the previous tutorial that I mentioned earlier.
Remember that the JsonPatchDocument
object is the JSON document that is coming from the client. This contains the whole employee object. Technically, this document is passed from the EmployeesController
, which we talk about next.
Again, this is just the Patch method I’m showing for demo purposes, so check out my previous tutorial I mentioned in my introduction for the complete list of methods and full source code.
Use Service in Controller
Finally, we need to use the EmployeeRepository
service inside our controller. So, this is what you do in the controller.
[Route("api/v2/[controller]")]
[ApiController]
public class EmployeesController : Controller
{
private readonly IEmployeeRepository _employeeRepository;
public EmployeesController(IEmployeeRepository employeeRepository)
{
_employeeRepository = employeeRepository;
}
// PATCH: api/v2/Employees/5
[HttpPatch("{id}")]
public async Task<IActionResult> PatchEmployee([FromRoute] int id, [FromBody] JsonPatchDocument employeeDocument)
{
var updatedEmployee = await _employeeRepository.UpdateEmployeePatchAsync(id, employeeDocument);
if (updatedEmployee == null)
{
return NotFound();
}
return Ok(updatedEmployee);
}
}
Again, there are other methods that I left out for demo purposes, so check out my previous tutorial called Create a Simple Employee Database Management REST API where this example was taken.
So, to explain the above code. First, inject the service into your constructor, on line 8. Then, you need to use the [HttpPatch]
attribute above the Patch method, on line 14. On line 15, you also need the JsonPatchDocument
object as parameter with the [FromBody]
attribute, because this is how you bind the value from the client. And then, we simply call UpdateEmployeePatchAsync
method of EmployeeRepository
on line 17.
And that’s pretty much it!.
How to send patch request from a client app
How do you exactly send a HTTP PATCH request from the client side? Now, that you know how to implement the PATCH request in your REST API application, you need to know how to send the PATCH request from a client application (or at least, how to test a REST API). Sending a PATCH request to a REST API application is quite straightforward. Assuming that you use a REST client, this is how the body of your request would look like:
[
{
"op": "replace",
"path": "LName",
"value": "Smith"
}
]
Simply put, the above JSON document says that you want to replace the field called “LName” with the new value, “Smith“.
For example, the PATCH request would look something like this:
After sending it, the response body is shown on the right with the updated field.
NOTE: As shown above, I used a REST/SOAP client extension for Google Chrome called Boomerang for testing.
Conclusion
HttpPatch
is a method in REST API that allows us to send only what needs to be changed in the database. In ASP.NET Core Web API this is accomplished by using the Microsoft.AspNetCore.JsonPatch
package, and using JsonPatchDocument
data type to bind the JSON document passed from the client.
The JsonPatchDocument does not have a type. I get error if I add the type like this. eg JsonPatchDocumet jsonPatchModel. How can I solve this issue.
Hi Vincent make sure you install the Microsoft.AspNetCore.JsonPatch package from Nuget.