Use Flux Standard Actions for HTTP PATCH

The canonical way to RESTfully apply a set of changes to a resource is through the use of the HTTP PATCH method.

Although a lot has been said about how to use other HTTP verbs, the community has written comparatively less about
PATCH for probably these two reasons:

  1. It didn’t make it into the HTTP/1.1 spec. It wasn’t until 2010 that PATCH was solidified into an RFC, so many APIs and frameworks had to be updated to accommodate for the newcomer. For example, AngularJS didn’t support it for nearly 4 years!
  2. The spec goes through a lot of effort defining what to say, but not how to say it.

The Head-In-Sand Approach To RFC Authorship

A key point in the spec was underscoring the difference between PUT and PATCH. Specifically, PUT payloads include a snapshot of the whole resource’s new identity, while PATCH must contain instructions on how to modify the server’s existing version of the resource.

Side note: Anyone who says PATCH payloads are supposed to be a snippet of the resource’s modifications is wrong, and apparently also an idiot.

The spec reasons that since a resource can be anything, the onus is on the information architect to define some sort of custom DSL to tell the server what to do:

It is expected that different patch document formats will be appropriate for different types of resources…Therefore, there is no single default patch document format that implementations are required to support.

This unopinionated stance was meant to empower the server programmers to implement the most appropriate patch format for each resource type. The idea was that given the freedom to do so, everybody would do it right, every time.

Of course that didn’t happen.

Same Same, But Different

The ambiguity in the spec has led to wildly different (and of course, incompatible) implementations across each server, even when the resource types are identical.

Every blogging CMS API can implement a perfectly RESTful endpoint for updating a blog post with PATCH, but each one of them will do it an unnecessarily different way because there’s no standard, no best practices that describe a good way to represent atomically updating a resource over HTTP.

What application developers really need is a common way to structure a HTTP PATCH request. This will pave the way for reducing implementation fragmentation, which will lead to:

  • Greater skills transference: easier to switch from one project to another without having to learn more unique implementations.
  • Increased certifiability: easier to confirm that the work is correct.
  • Better resource allocation: no need to design a new patch format, existing implementations can be reused.

So what would put us on the right track towards more unified HTTP PATCHes? There’s a few options:

  1. Use JSON Patch
  2. Get together and come up with something new
  3. Re-purpose some existing standard or format

While JSON Patch is an IETF standard specifically designed to be the missing piece of the standards-based puzzle, it has a few issues:

  • Its standard is not versioned. Any upgradable technology does badly without versions.
  • It doesn’t specify how errors should be communicated outside of HTTP response codes. See HTTP Status Codes Are Not Enough.
  • Adoption rate is very low. This means low community critiques, tutorials and support. This also leads to poor tooling.
  • The baffling JSON Pointer-based path property that treats JSON structures like pseudo-URLs instead of regular dot- and square-bracket-based notation.

It seems like continuing with JSON Patch (option 1) as it currently is will not be good enough.

However, coming up with something brand new is a very high-cost task, especially considering the long tail of significant adoption. It’s likely that without the required order of magnitude improvement, we should move onwards from option 2 and decline to build yet another solution from the ground up.

Personally, I believe the case is strong for the community to evaluate the plausibility of re-purposing an existing format. One such option I think is worth investigating is the JS-based Flux Standard Action.

The Case For FSAs

Flux Standard Actions would be a good starting point for a standardised HTTP PATCH payload for several reasons.

It’s Open Source And Actively Maintained

The spec’s canonical home is on GitHub, where the web community can rally around and contribute meaningful discussion, without needing a position at WHATWG or the IETF.

Since it is actively maintained, problems are rectified quickly and improvements are implemented in short cycles.

The Standard Is Versioned

This increases the strength of the API’s contract and allows developers to sidestep the disadvantages of using non-versioned mutating standards.

It’s A Standard

Though there are pitfalls to designing a standard, the concept still allows for an authority to determine what is correct, and encourage programmers to build their systems in a common way. Roy Fielding actually noted during the development of RFC 5789 that it takes too long for individual entities to come to an agreement on best practice.

Side note: if Github Flavored Markdown is considered
a standard, then FSA’s spec is too.

It’s Already Popular

FSAs are the de-facto method of dispatching requests to change a resource in React-land.

And, the number of React users grows, the FSA community gains a lot of support, resources and more.

It’s Simple

The spec is very small and requires only a few minutes to read the entire thing. Compare it with RFC 5789, it’s associated errata and other supplementary resources (including the mandatory RFC 6902) and you’ll find that gravitating towards the simple option is preferable.

The Tooling Is Better

There already exists a number of resources for working with FSAs quickly and efficiently. This lets the community leverage the best work and help get things done more effectively.

The Payload Scales Both Ways

Very tiny instructions need only one property: type. This means that if the server knows what to do with a resource given very simple instructions, the client can send minimal data.

On the other hand if you need a very complicated PATCH, the payload field can be as large as is appropriate for your task.

Errors Are A First-Class Concept

Most of an API’s code goes to handling errors because there’s only one successful path, and a basically unlimited number of error paths.

Incidentally, this is the reason why headphones spend more time tangled than straight.

FSAs make sure that any client consuming your API will always know when an error occurs, and will get good information to debug it. Combine this with a great error standard and any developer consuming your API will almost enjoy receiving errors.

In Conclusion

Since incompatible implementations and fragmentation really sucks, the web community needs to gather its collective will and wisdom and move towards unified, common ways to do things.

The more we do the same stuff the same way, the better we’ll all be for it. Using Flux Standard Actions as the payload in HTTP PATCH requests could be the right way to go.

Leave a Reply

Your email address will not be published. Required fields are marked *