RESTful without HTTP Verbs

Cary Reams on January 09, 2018

Update 2 From the comments below, several very interesting resources have surfaced. The most damning of these articles is an nine-year-old bog e... [Read Full]
markdown guide
 

If your primary concern is information expose in server logs (why I’m not sure, but okay), reconfigure your server to log less information. Done. You don’t have to upend the entire HTTP philosophy just for that. A great benefit of a RESTful architecture is its standardization. You don’t have to reinvent the wheel and teach it to every new developer. If you’re vaguely familiar with RESTful conventions, a RESTful API is almost self-documenting. That can save a lot of headache down the line. Not to mention standard behavior of caching and such. You’re basically locking yourself out of the synergies of the existing RESTful paradigm which could enable you to develop and scale quickly.

 

Yep, I agree here. This seems like a lot of work to avoid an issue that should be solvable by a configuration change on your webserver.

 

Fair point on the destination server.
What about the hops between?
And to clarify, the question of server log content only began the thought process; it's not a motivating factor for making a change.

I would question why the little bit of information that may appear in server logs may in any way lead to breaches of any sort in the first place. If your security depends on the exact URL structure of your server being secret, your security is non-existent.

"Hops in between" for HTTP that matter at all to this discussion would only include SSL-terminating HTTP proxies, and they can log the fully payload if their operators so desired and there's nothing you could do about that. Presumably any such proxies would be fully trusted by either the server or the client or both. So for our purposes, intermediate hops are irrelevant.

Thought that encryption applied to the POST payload, but not the information appearing along with the URL (GET parameters?).

Encryption is only applicable in end-to-end scenarios, in which case intermediate hops are totally irrelevant - you either don't have them at all, or they're just TCP proxies / IP routers which see nothing but the TCP/IP headers.

If you have a ssl-terminating proxy (i.e., it intercepts your SSL traffic and re-encrypts it to relay it to the final destination) it can log everything.

There's nothing in between.

 

In other words:

  • an HTTP request goes through a bunch of infrastructure (browser, local cache, proxies, CDN, server-side cache, web server, application layer)
  • this involves a number of different products by different vendors
  • the one thing that binds those different products is the standardised behaviour of HTTP
  • that behaviour is what allows HTTP to scale enormously, specifically with regards to caching
  • you're proposing to discard all that and essentially invent your own protocol, discounting all the help you may get from all the existing infrastructure

You're only making your own life more difficult for little to no advantage that I can discern. Do not underestimate the advantage of a properly implemented HTTP API when you find that you need to start scaling up. It's not that easy to throw a CDN or additional servers into the mix when you've painted yourself into a corner with a custom protocol that is uncacheable/unproxiable/unwhateverable.

 

This is the type of "what about" comment I was hoping to get.

I think I've conflated the RESTful approach to utilizing the capabilities of HTTP with using HTTP verbs and status codes to satisfy the CRUD requirements of a web app.

I'm going to have to think about separating some concepts more clearly.

 

As a thought exercise, why should a RESTful architecture depend on HTTP ?

 

Sure, you could relegate HTTP to be a mere transport mechanism and implement your own "RESTful" protocol on top of that. Does that provide any advantage? Does it allow you to easily switch the transport layer to something else down the line? Is that a foreseeable requirement? Also see Inner-platform effect.

 

The guy who inherits this when you leave is going to ragequit.

 

Ha. Good point. When challenging assumptions, its always best to take the temperature of the room.

However, I still think its worth thinking about whether what we communicate is inseparable from how we communicate.

Could just tell them "it's RESTful, but the implementation is over here. We only use HTTP for communication."

She might still quit, but only roll her eyes on the way out.

 

It's possible to avoid using HTTP verbs, but I would not call this approach RESTful. Depending on the context it can be a good solution, but, probably, not a universal one. One problem that I see with this approach is the fact that to act on a request you need to parse the request body because the standard HTTP data does not provide enough information. For example, if you need to route some requests to a different backend using NGINX, you will have to parse the request body instead of using URL-based pattern matching.

Regarding the URLs in the logs, what about configuring your servers so that they don't log requests? And I don't see a big problem with it.

 

Fair criticism - as we currently implement RESTful solutions.

I came to question why a RESTful solution (the purview of the app) should depend on the communications protocol (HTTP).

Turning it inside out, what if the available HTTP status codes don't provide enough information on the nature of a response to provide an effective solution ?

or,

Why can't/shouldn't we have a RESTful solution without relying on HTTP ?

 

You can do it without relying on HTTP but you need to follow constraints: en.wikipedia.org/wiki/Representati... In your suggested approach, I see the following broken constraints: Cacheability (you can build your own without relying on HTTP though), Uniform interface (because when you GET a web page in the browser, you should be able to update it with a PUT back). You can achieve uniform interface but, then, I believe your client should not be the browser itself but something running inside the browser. But that's all vague anyway. More important is that you will be building a protocol on top of HTTP, you will not be able to use some the standard tools and conventions.

Thank you. This is precisely the kind of "what about" comment I was hoping to get

Several ideas working their way through my thoughts right now between your comment and David Zentgraf's, above.

 

I like this article, and I think you have made an important realization. In practice I -- along with most people -- have never done a Level 3 REST APIs, because they cost a lot to develop (for API consumers too). But going less than Level 3 does not provide the supposed benefits of a uniform interface. Nor does it even count as "REST" according to its creator. Yet obviously many people see the benefit of using some of the patterns from REST for specific benefits. Examples: content negotiation, hypermedia, scaleability from statelessness and/or cacheability.

I gave up on REST myself. I have taken to using HTTP as just a transport protocol. With a simple interpretation of the contents as a message. Instead of "media types", my client apps know how to work with "message types". These are business-level requests/responses, as opposed to "resources" (which a lot of people believe to be database tables). All messages are sent to a few well-known endpoints of the given API. This does not prevent the API from being scaleable or using content negotiation and hypermedia. But I am not required to use them either. I can start simple and layer on these complexities as the need arises. Since using this strategy, I run into far less situations where I am puzzled trying to figure out how to squeeze my use case into REST constraints. Instead, it's more about puzzling to understand the business's precise problem so I can determine the right messages to add.

 

Thanks.

The Fowler link lead to the Fielding link.

Results of those readings are included in my original post as "update 2".

Much appreciated.

 

Very nicely done.

I've implemented several REST API's with nearly POST only. And they are damn clean, you can easily generate SDK e.g. from type-safe C# to type-safe TypeScript and you can read it like you would a normal API.

My goal with REST API's is clean SDK, e.g.

In web server I have Namespace.SomeController.Save it will be: /Namespace/Some/Save/ and it will generate Namespace.Some.Save() function to TypeScript. Highly recommended.

You don't need to be verb purist (for some reasons you already covered), but key to me is to have unique url for all endpoints to keep it clean and easily generateable.

 

That isn't a REST API, by any measure of the word. It's a case of en.wikipedia.org/wiki/Remote_proce.... That's not to say that that's inherently bad (far from it), but to call it 'REST' it needs to at least have a reasonable amount of overlap with what is generally considered 'REST'.

code of conduct - report abuse