RESTful without HTTP Verbs 
Tags: rest, http, httpverb
Published: 2018-01-09 16:56:37

---
title: RESTful without HTTP Verbs 
published: true
description: Thoughts about decoupling HTTP Verbs from a RESTful API for a closed-system app.
tags: REST, HTTP, HTTP verb
---

__Update 2__

From the comments below, several very interesting resources have surfaced. The most damning of these articles is an [nine-year-old bog entry](http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven) by Roy Fielding (father of REST). This quote appears:

>What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint? In other words, if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period. Is there some broken manual somewhere that needs to be fixed?

So, categorically, unless we are using HTTP to directly manage state - and not merely as a messaging layer - we are not RESTful.

Point taken.

Kudos to the comment from [Kasey Speakman](https://dev.to/kspeakman) which included the link to Martin Fowler's article on the [Richardson Maturity Model](https://martinfowler.com/articles/richardsonMaturityModel.html) (RMM) which lead to the Fielding entry.

Also thanks to all those with constructive comments that helped square away my understanding of a RESTful architecture. While I don't care for the coupling that comes from intertwining the app with the protocol used to communicate between client and server, its clear that decoupling those items _violates the intended definition of REST.

__Where to go from here?__

Not sure yet. I owe it to myself to take a look at the "HATEOAS (Hypertext As The Engine Of Application State)" mentioned in the Fowler article on RMM. I need to reconcile the dual role of HTTP to provide both transport and management of application state.

__/Update 2__

---------------

>_note bene: I'm really looking forward to comments that begin, "What about...," or "In addition, ..." as its a great benefit to enumerate additional considerations. Thanks_

# Context
We develop and operate a private web portal for clients. That portal allows clients to login, save information, license intellectual property, and generate highly customized,  print-ready PDFs for use in their business. As such, the API is not open and we do not integrate with other apps or services. The lack of such integration grossly simplifies what we need to do as it eliminates many of the normal benefits received by following the current convention. That said, ...

# Rejected Premise
A faithful RESTful implementation necessitates use of appropriate HTTP verbs.

# Initial Motivation
__update 1__
this motivation is no longer a concern. However, I'm not finished chewing on the bone I found.
__/update 1__

~~The reason for pursuing this line of thought at all was out of concern for reducing the amount of information exposed in server log files. So, it began 
more as a curiosity than as a possible solution to a specific problem. To that end, this reads better as _thinking out loud_ rather than a manifesto for revolution.~~

~~If I'm using the usual and customary RESTful implementation, the path (but naturally not the non-GET payloads) appears in the server logs. A reasonable application of knowledge and an exposure in authored or incorporated software could lead to a breach.~~

~~While I like the idea of being able to scrape server logs for intelligence, in practice I just don't do it. There are other, more intelligent means by which to gain that kind of insight regarding usage.~~ 

__~~Therefore, information is being exposed without offering any value in return for the perceived risk.~~__

# TL;DR

The client-side software and the server-side software don't _require_ the use of HTTP Verbs to communicate intent -- those two pieces can communicate with each other, provided the browser and web server can communicate.

ergo, we require only that the communications are successful; and ask the browser and web server (Apache, iis, nginx, etc) to provide the comm link or information about why the comm link is unavailable. _That's their job, let them do it. But don't ask them to take on responsibility for the entire solution._

The alternative: encapsulate solution-specific server-side response codes and data   within the payload.

To that end, we elect to simply prefer the POST method with a message header and message body to communicate intent currently conveyed via HTTP verbs. We accept use of the GET verb where we don't mind exposing our RESTful structure (...or wish to permit bookmarks or support caching).

The message header contains two field (hidden inputs, if you will):
* request_type : New | Create | Edit | Update | Show | List | Delete
* request_path :  /resource/id/resource2/id2/...

The message body contains all the usual suspects.

```
*---------------*
| request_type  |
| request_path  |
+---------------+
| field1        |
| field2        |
| ...           |
| fieldN        |
*---------------*
```

Solution-specific, server-side responses are provided with a response header and response body. The response header takes on the responsibility for conveying the status of the request (replacing use of HTTP status codes formerly used for this purpose) while the response body contains any requested data as per usual.

```
HTTP headers, ...
HTTP_STATUS: 200, 400, 404
data:
*------------------*
| response_status  |
+------------------+
| field1           |
| field2           |
| ...              |
| fieldN           |
*------------------*

```

I think this decouples the various browsers and web servers from my client code and server-side code. I still have to use POST and GET, but I _only_ have to use POST and GET. And GET could be optional and rare, since I still want to eliminate information from server logs. 

## Risks
+ __Caching__ will be affected by using POST where GET is a legitimate candidate; to be investigated
+ __Bookmarking__ will be affected by using POST where GET is a legitimate candidate; to be investigated
+ Currently accepted __principles__ will be violated by using POST where GET is a legitimate candidate; tradeoffs will be evaluated


# STL;BIC
(Still too long; but I'm curious)

Here's a thought process that was radial and branching in nature, but had to be tortured into a linear space, here.

## What good are you? 
I've spent a few years torturing our web app from a hacked solution towards a more  RESTful solution. I love the simplicity of the relative path address path and the nature of the seven operations - eight for us, since I've got a parking lot item to handle search as a first-class request.

But during that time, I've struggled with the implementation of HTTP verbs and REST. Put simply, HTML doesn't support use of all VERBs. Form methods may only be GET or POST and one can fairly ask why support GET. However, the PUT, PATCH, and DELETE options are not supported. 

Barring some unknown consideration, it makes sense to me that the HTML form spec allow for:
+ method=POST to create a resource
+ method=PATCH to update a resource
+ method=PUT to replace a resource
+ method=DELETE to delete resource 

...but that's not available to us. To overcome this limitation, browser vendors and javascript libraries would have to start moving in the same direction together (stop laughing).  I suppose its possible I'm expecting HTML to support something that it was never intended or anticipated to support - maybe the PATCH|PUT|DELETE ops are intended for server-to-server communications ?? Not sure. But I know I have use for them. They aren't there natively. The exercise to overcoming the native absence seems thankless and costly. 

...and even if we did attach some javascript and a library to manage ajax communications to change the method to an appropriate VERB, ...my apache server processes it as a POST request and the data must be obtained from the PHP::_POST array anyway. Which means I must infer from other information the POST|PUT|PATCH|DELETE operation (aside from some cases where the verb is preserved in the comms overhead).

So _what good are you?_ we jumped through some hoops only to have my intentions squashed on the server. No thanks. 

## HTTP Status Codes
Found this [resource](http://www.restapitutorial.com/lessons/httpmethods.html) which nicely captures the use of HTTP status codes to response to HTTP verbs. However, the vast majority have more to do with app response than web server communications response to the browser:

HTTP verb | status code | App Scope| Web Server Scope 
---: | :---: | :---: | :---:
POST (create) | 201 created | Yes | -
POST  | 404 not found| Maybe | Maybe
POST  | 409 conflict| Yes | -
GET (read) | 200 (OK) | Yes | -
GET  | 404  |  Maybe | Maybe
PUT (update/replace) | 200 | Yes | -
PUT  | 204 (no content) | Yes | -
PUT  | 404 | Maybe | Maybe
PUT  | 405 (method not allowed) | Yes | -
PATCH (update/modify) | 200 | Yes | -
PATCH  | 204 (no content) | Yes | -
PATCH  | 404 | Maybe | Maybe
PATCH  | 405 (method not allowed) | Yes | -
DELETE (delete) | 200 | Yes | -
DELETE | 404 | Maybe | Maybe
DELETE | 405 (method not allowed) | Yes | -

Instead of this mess, I'd rather just focus my communications between browser and web server on the 200 (OK), 400 (bad request), and 404 (not found) responses. Either communications was good and I ask the app to continue processing using the data returned, or the end point was not found (404) and we handle that response as appropriate.

The HTTP status codes can provide some guidance for _app return codes_ in that we may want a standardized response where

Stolen HTTP Status Code | means what it means
--- | ---
201 | success on creation of resource
204 | there is no content to be displayed
404 | bad resource id
405 | method not allowed
409 | resource already exists (duplicate?)
418 | in the event we ask a teapot to brew coffee

But, __these are returned in an app response header, not the HTTP response.__


## Client Side Hassle
This comes down to the incurred cost of developing or using a package to support AJAX communications that are formally correct but get tortured into a POST by the time the web server passes the request to server-side code. It may only become a personal preference to branch off a request header rather than a verb in the communications overhead. Either way, the detection work still needs to be done. But I feel better working off the request than the communications header.

## Server Side Hassle
...continuing, pulling my action detection out of the comms header and into a request header allows for separation of web server code from request code. That is, my server script end point merely has to pull the request header and body from the web server and feed it to the server-side code. Now, we could interpret the web server request and translate it for the server-side code, by why introduce that action at all ? Why not decouple altogether and simply state the action in a request header which passes untouched from the client-side to the server-side ?

## Boundary Crossing
Revisiting the whole use of HTTP status codes to tell me about something that happened in the server-side code (beyond the web server). Just as I dont want the server-side code using information from the comm header (GET|POST) to know what action to take (NEW|CREATE|EDIT|UPDATE|SHOW|LIST|DELETE), I don't want the client-side code to take app-related action based on information in the comm response. 

Why should the comm response be anything (for a web app) beyond 200, 400, 404 ? 

Now, in the event, the API is to be exposed for third-party usage that (historically) expects app-related responses from the comm layer, I get it. The legacy reasons for including those responses may be overwhelming.

I also expect this will have mocking/testing benefits although a proper decoupling of server side code may have accomplished this anyway, yielding no incremental benefit.

## KISS
Standardizing the request header and request body on both the server and client sides means only dealing with a single model for creating and responding to a request. Check.

Reducing the ajax communications to concerns related to GET, POST and the pass/fail nature of the communications link streamlines communications processing between client and server. Check.

Implementing a response body into the _data_ portion of a response complicates the client-side processing. A bit. Ugh.

## Server Logs
__update 1__
~~Oh, and I don't expose any of our structure in server logs. When the path goes into the payload instead of the URI, the structure is hidden. That may not have been a concern a decade ago, but I am beginning to think it should be more of a concern today. Just as we played fast and loose with all of early IoT toys around the house, we may be flirting with danger allowing our resource end points to appear in server logs.~~
__/update 1__

# Thanks
Thanks for taking the time to read this. And even more thanks if you choose to respond/comment with constructive criticism. Kudos.