I have written my fair share of RESTful API but am no expert by any measure. I had never given enough thought about the HTTP Verbs I should be using (like, PUT, POST, PATCH) while writing API. If a resource had to be created, I would automatically go for POST (_never considered the idempoten_cy angle at all) and if a resource had to be modified, I would go for PATCH.

On one of my API assignments, I decided to make a very conscious and deliberated choice of the verbs I will be using; and an API in particular got me thinking.

I had to write an API to modify a resource and this resource happened to have nested resources and numerous attributes. I soon realized that it wasn’t so straight forward to create an elegant PATCH API due to the sheer number of attributes on this resource that can potentially get modified (Why did you design a resource with so many attributes in the first place? you might ask. But that is a topic for another day)

So, coming back to the task in hand, I was aware of only two choices to go about writing a PATCH call. Either, send just the attributes requiring modifications to the API (Approach 1) or end the entire resource to API after making changes to the necessary attributes at consumers’ end (Approach 2). We will examine both the approaches in the context of the below two classes (Employee and Address)

    public class Employee  
    {  
        public int EmployeeId {get; set;}  
        public string EmployeeName {get; set;}  
        public Address EmployeeAddress {get; set;}  
        public string WorkLocation {get; set;}  
        public List<string> PreferredWorkLocations {get; set;}

    }

    public class EmployeeAddress  
    {  
        public string HouseNumber {get; set;}  
        public string AddressLine1 {get; set;}  
        public string AddressLine2 {get; set;}  
    }

Approach 1: The consumer of the PATCH API will send the entire resource, after changing a few select attribute that need to be modified. At the API end, the PATCH payload will be handed over to the repository layer which would then update the entire resource to the database. Other than some basic validations, no additional work is needed at the API end. A sample PATCH call (almost a PUT) would look like below

    **api/ModifyEmployee/{empId}  
    **{  
    "EmployeeName" : "ename",  
    "EmployeeAddress" : {  
                "HouseNumber" : "F32",  
                "AddressLine1" : "Addr1",  
                "AddressLine2" : "Addr2"  
                },  
    "WorkLocation" : "Brazil",  
    "PreferredWorkLocations" : \["Brazil","France"\]  
    }

Downside: the consumer has to build the entire object even if only a single attribute requires modification. Also note that, there is no way of knowing if just the “houseNumber” has changed or any other / all the attributes of Employee has changed. So, all the attributes’ values need to be copied back to a new object object to be persisted in the database.

Approach 2: The consumer of the API will send only the attribute that had to be modified. A sample PATCH for modifying the work location will look like below:

    **api/ModifyEmployeeWorkLocation/{empId}  
    **{  
    "WorkLocation" : "Brazil"  
    }

Downside: the onus of constructing an object that can be handed over to the repository layer falls on the API service layer (an object mapper need to be used here)

Further, this approach might necessitates that a new API be created of each combination of possible modifications in the resource attributes. Consider if I have to update the Employee Address I will have to have another method like api/ModifyEmployeeAddress/{empId}. If the class has many attributes that could be modified this can lead to explosion of PATCH methods.

JSON Patch

Neither of the approaches appealed to me. This is when I stumbled upon JSON PATCH. Honestly, I had never heard of JSON Patch before and wanted to give it a shot as I thought it would address the downsides mentioned above.

What I like the most about JSON Patch was that as a consumer I don’t have to send the entire object as payload for the PATCH call, I can just mention what operation (add / remove / replace / copy) I want to perform on which resource attribute / subset of attributes. Also, at the API end, I there is not need to have multiple methods for each type of modifications and there is no need to manually copy over the incoming values to a new object that the repository will understand and persist

Using JSON Patch, these call can be as simple as below

    **\[    
        {**  
            "**value**": "address line one",  
            "**path**": "/address/addressLine1",  
            "**op**": "replace"  
        **}  
    \]**

The advantage of using JSON Patch is that you don’t have to reconstruct the object at your API end. You can use a middle-ware like NewtonsoftJsonPatch and simply use ApplyTo method to construct the object for persistence / further processing.

    public async Task<IActionResult> UpdateEmployee(\[FromBody\] **JsonPatchDocument<Employee>** patchDoc, int empId)  
    {  
        if (patchDoc != null)  
        {  
            var emp = await <yourCache>.GetAsync<Employee>("cacheKey");

            if (emp == null)   
            {  
                emp = await yourService.GetEmployeeData(empId);  
            }

            **patchDoc.ApplyTo(emp, ModelState);**

            //call repository to update.   
            \_ = await yourService.UpdateAsync(emp);

            return new ObjectResult(emp);  
        }  
        else  
        {  
            return BadRequest(ModelState);  
        }  
    }

The ApplyTo method will take care of copying (or performing any operation based on the value supplied in “op” attribute of the PATCH call) the new values to the existing object. This eliminates the need to do this mapping and copying manually using a mapper.

Another plus is that you don’t have to have multiple PATCH calls for each of the attributes, you can club multiple modification requests in the same PATCH call like below. Please note that you have to use /- notation to add to a list.

    \[  
    {  
            "value": "new work Location",  
            "path": "/preferredWorkLocations/-",  
            "op": "add"  
    },  
    {  
            "value": "address line one",  
            "path": "/address/addressLine1",  
            "op": "replace"  
    }  
    \]

You may refer to the below link for detailed information on how to use JSON Patch in ASP.NET Core.

JsonPatch in ASP.NET Core web API
_By Tom Dykstra and Kirk Larkin This article explains how to handle JSON Patch requests in an ASP.NET Core web API. To…_docs.microsoft.com

So, that’s how I embraced JSON Patch.

Cheers!