Conditional data update in RESTful web services

In the previous two sections, we learned how to leverage HTTP caching features to optimize read operations (the HTTP GET type) in RESTful web APIs. In this section, we will discuss how to leverage these features during the entity updates in these APIs (the HTTP POST or PUT request types). Conditional updates help you to avoid performing modifications on the stale representation of resources, thereby avoiding the overwriting of changes performed by other users of the system on the same resource. You can perform conditional updates by using either of the following approaches:

  • Comparing the last modified date of the resource: When a client sends a modified resource to the server via the PUT or POST method, the request also carries the If-Modified-Since HTTP header field with the value set to the last modified date of the resource. The server can evaluate the If-Modified-Since header field to see whether it matches with the time stamp on the resource residing on the server.
  • Comparing Etag of the resource: If the modified date is not precise enough to decide the freshness of the resource, you can use ETag. In this case, the PUT or POST request from the client carries the If-None-Match header field with the value set to that of the ETag header sent by the server when the resource was last retrieved. The server can evaluate the value of the If-None-Match header field present in the HTTP request header to see whether it matches with the current ETag of the resource on the server.

If the validation check fails for the preceding two cases, the server will return an error response code of 412 (precondition failed). The client can take appropriate action on the basis of the status code received as part of the response. If all checks go through, the update succeeds on the server. The following code snippet illustrates how you can use the last modified date or the ETag header present in the request for performing the conditional updates on a resource:

@PUT 
@Path("etag/departments/{id}") 
@Consumes(MediaType.APPLICATION_JSON) 
public Response edit(@PathParam("id") Short deptId,  
    @Context Request request, Department entity) { 
 
    //Reads latest Department object from DB and generates ETag 
    Department detEntityInDB = finDepartmentEntity(deptId); 
    //You can use a better algorithm for getting ETag in real life 
    EntityTag etag = new  
        EntityTag(Integer.toString(detEntityInDB.hashCode())); 
 
    //Evaluates request preconditions on the basis of the passed-in value. 
    //A client may pass either ETag or last modified date  
    //in the request. 
    // evaluatePreconditions() returns null if the  
    //preconditions are met or a ResponseBuilder is set with  
    //the appropriate status if the preconditions are not met. 
    Response.ResponseBuilder builder =  
        request.evaluatePreconditions( 
            detEntityInDB.getModifiedDate(), etag); 
    // Client is not up to date (send back 412) 
    if (builder != null) { 
        return builder.status( 
            Response.Status.PRECONDITION_FAILED).build(); 
    } 
    updateDepartmentEntity(entity); 
 
    EntityTag newEtag = new  
        EntityTag(Integer.toString(entity.hashCode())); 
    builder = Response.noContent(); 
    builder.lastModified(entity.getModifiedDate()); 
    builder.tag(newEtag); 
    return builder.build(); 
} 
The ETag and Last-Modified entity tags in the HTTP header can be used for reducing the network usage of the REST APIs by introducing the conditional retrieval of the resources on the server. You may also find it useful for concurrency control for the REST APIs by introducing conditional updates on the server.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.222.185