TQ
dev.com

Blog about software development

Subscribe

RESTful incrementing using PATCH

03 Feb 2017 - by 'Maurits van der Schee'

How should a RESTful JSON-based API handle counters (atomic increments)? In this post I'll try to describe the considerations and do an implementation suggestion using the "PATCH" HTTP method.

Atomic increments

When counting events, such as people visiting a web page, it may be cheaper to increment a counter than to insert a log record. But when dealing with many increments per second you cannot simply read a value in one call and then write the incremented value back in the next call. The concurrent updates would cause issues and increments would get lost. This is the problem I am trying to solve.

Choosing a method to (ab)use

In my quest for the most appropriate method for incrementing values I have ran into the various methods (or verbs) described in HTTP, the concept of "safe" and "idempotent" requests, the "PATCH" method and the "JSON PATCH" standard for updating an existing JSON HTTP resource. That last one sounded very promising, and even has an operation named "add", but unfortunately that is for adding elements to a JSON array and not for incrementing counters.

Official HTTP 1.1 methods

The following HTTP methods are allowed in RFC 2616 (the HTTP 1.1 standard):

None of the above seem very suitable for an "increment" command.

Safe methods

RFC 2616 & 7231 say that GET and HEAD methods should not take other action than retrieval of information and can therefor be considered "safe". Other methods, such as POST, PUT and DELETE take actions other than retrieval and should be considered "unsafe".

Idempotent methods

Also defined in RFC 2616 & 7231 is that a request is "idempotent" when the result of multiple identical invocations is the same as that of a single invocation. The methods GET, HEAD, PUT and DELETE, but also OPTIONS and TRACE, share this property, while POST and PATCH do not.

PUT vs. PATCH

RFC 5789 describes that the extension method PATCH should be used to modify an existing HTTP resource as opposed to PUT, which is for replacement of a document.

JSON Patch

RFC 6902 describes the use of the extension method PATCH to send a JSON document describing operations to apply to an existing JSON document (HTTP resource).

PATCH as increment method

Creating a RESTful JSON API involves mapping the HTTP standard to SQL and this is not easy. In order to facilitate incrementing, you could allow back-references or commands in posted JSON documents (or post values). Another option is to use the PATCH verb for this purpose. This means you can no longer use that for partial updates, so you would have to allow those for the PUT method (a common violation of the standard).

Using PATCH to increment is simple, which is good, but has the downside you cannot easily express other operations. You can, however, vary what PATCH does based on the type of the field. You may want PATCH to "concatenate" to a string or blob typed field while you would "increment" a numeric or date typed field (using seconds). I implemented PATCH as increment for numeric fields in my (pragmatic) API project PHP-CRUD-API.

Links