Hacker News new | past | comments | ask | show | jobs | submit login

>- There's also the REST verb that is often super arbitrary. PUT vs POST vs PATCH... so many ways to do the same thing.

These have clearly defined caching and indempotency differences. They are not the same. I don't believe gRPC handles this or it looks like its experimental.




> These have clearly defined caching and indempotency differences. They are not the same.

Clearly defined...? Maybe?

I don't know of any popular HTTP proxies that rely on these definitions to automatically decide how to cache things, because people in the real world follow the definitions very loosely. GET is the only one that I've seen relied on, and it's still just a good bet, not a guarantee. Usually, you have to define which routes are cacheable and carefully configure the cache settings... in my experience, at least.

Maybe it's just my bad luck to have encountered all the ways these verbs aren't used consistently over the years. They're a hint towards what will happen... at best. In my experience, anything goes, no matter what the verb says.

I truly hope you've had a better experience, and that it's just me.

> I don't believe gRPC handles this or it looks like its experimental.

Which seems fine. We can't rely on HTTP verbs for state management because of how inconsistent implementations are, so I don't expect gRPC to do that either, but at least gRPC won't make you choose a random verb.


> Maybe it's just my bad luck to have encountered all the ways these verbs aren't used consistently over the years.

No, everyone has done that, especially everyone who's encountered almost any non-REST protocol over HTTP, which almost always ignore HTTP semantics (if you're lucky, they tunnel everything over POST.)

But whether other people use the consistently in their APIs is a very different issue than the claim that they are insufficiently clearly defined so that deciding what you should use in implementing an API that respects HTTP semantics (as REST over HTTP should).


Sure, I guess that's fair.

Consider that a route might start as an idempotent way to update a RESTful object, but then requirements change over time and that method call now has non-idempotent side effects, such as updating a counter, or sending an email notification. It may not be practical within this system to determine whether the object being PUT is truly identical to the state already in the system, given the high volume of API calls, or the distributed nature of the state. At that point, everyone sits at the table to discuss what color to paint the bike shed. Should we change the verb, breaking existing clients? Should we require two separate API calls in order to separate the additional behavior from the idempotent simplicity of the original PUT request, doubling our API request load and introducing a possible error wherein a client forgets to make (or errors out while making) the second API call? Oh, and by the way, all of the existing clients won't benefit from the new, desirable behavior.

Neither of those options sound great to the stakeholders, so then you end up with a non-idempotent PUT, through no fault of the original API design.

The verbs quickly lose their meaning, and it would be better to spend that time actually considering how the API should evolve instead of worrying about what verb is associated with it.

You're obviously entitled to your own opinion. I fully admit that I could be wrong in all of this, but this is how I currently feel.

My experiences with HTTP have convinced me that the verbs are an abstract idea at best -- and because of that, we would all be better off eliminating PUT and PATCH. POST can do everything that PUT and PATCH can do. PATCH isn't idempotent to begin with, and you can't rely on the PUT verb to really indicate that a route is truly idempotent and you can just retry it arbitrarily, unless the documentation says so... in which case, POST can also declare that it is idempotent. (which, yes, does sound kind of weird, but I've also seen that.)

gRPC does away with the verbs entirely, as far as the developer is concerned, and that seems good to me. When I'm using a library, the functions aren't labeled with POST, PATCH, etc. The relevant behaviors and guarantees are spelled out in the documentation. I would imagine gRPC is a lot like that. But, as I said in the beginning, I don't have any direct experience with gRPC... just a lot of gripes with the way that HTTP REST APIs work, and some optimism that gRPC would let people focus on the actual problems at play, instead of lots of random distractions. (The verbs were only one of several such distractions.)


> Consider that a route might start as an idempotent way to update a RESTful object, but then requirements change over time and that method call now has non-idempotent side effects, such as updating a counter, or sending an email notification.

Then...you stay with PUT because “Like the definition of safe, the idempotent property only applies to what has been requested by the user; a server is free to log each request separately, retain a revision control history, or implement other non-idempotent side effects for each idempotent request.” (RFC 7231, Sec. 4.2.2)

> My experiences with HTTP have convinced me that the verbs are an abstract idea at best

They are quite specific in their semantics (and not just things like the definitions of safe and idempotent, but specifically the semantics as to what each verb means the request is asking for with regard to the target resource.)

> and some optimism that gRPC would let people focus on the actual problems at play, instead of lots of random distractions. (The verbs were only one of several such distractions.)

I think gRPC is pretty universally superior to fake-REST, which is basically ad hoc RPC-over-HTTP, usually using JSON and with loose if any regard for HTTP semantics, and usually used for applications where an RPC approach is quite sensible.

I don't think it and REST even address approximately the same problem space.


That's because you are thinking that the representation of a resource is the resource.

"The map is not the territory".

A PUT is a way for the client to transfer its representation of a resource to the server. There's nothing that stops the server from changing the state of that resource independently and asynchronously.

> The verbs quickly lose their meaning

That's because people tend to think in terms of CRUD, POST is Create, GET is Read, PUT/PATCH are Update, DELETE is Delete.

But that's misinterpreting things:

POST is to transfer the state of a new resource that has been created by the client. That resource might be subject to a long running business process (eg a Sales Order). That Sales Order will change its state as it progresses through the business process.

GET is a way for a client to request the transfer of a server's representation of an existing resource. It should do a GET to synchronize it's understanding of the current state. Use of E-tags etc allow for caching and avoiding stale changes.

PUT/PATCH is a way for a client to transfer a change in the representation of a resource to the server. For example, changing the delivery address. Often though, these attributes should be resources in their own right (eg /order/id/delivery-instructions). There is nothing to stop an initial post of the Sales Order creating the subresources as part of the processing of the POST. If you use JSON API and/or JSON-LD etc, you can provide backwardly compatible extensions in a response that older clients will ignore and newer clients can use.

DELETE is a way for the client to say that as far as it is concerned, the resource no longer exists. In the Sales Order example, it could represent the cancellation of the order, but might be rejected by the server (eg if it has already been shipped), or it might trigger something else (eg a refund).

> gRPC does away with the verbs entirely

gRPC forces the protocol to be "verb first" and focus on defining the behavior of those verbs. For each one, it has to clarify the idempotency, the state of the things being changed, how to find out about those changes, the different process errors that can occur, etc etc.

The trouble with gRPC is that it throws away everything that was learned in the "SOAP wars" of the 2005-10 period, where "enterprise suppliers" were desperate to keep their moats by defining ever more complex protocols on top of RPC to cover up the cracks and problems. An example, WS-ADDRESS, a standard for naming things over an RPC pipe that replicates the entire URL definition, but over a layer of RPC that was being tunnelled through port 80. WS-SECURITY, which did what TLS and HTTP Authorization does, but again, over layers of RPC and XML over HTTP over SSL.

All of that crap was unnecessary but was created because the idea of dealing with the nouns instead of the verbs is harder, because you have to think through the processes and changes in terms of state machines and events, instead of imperative processing where state is distributed and indeterminate.

> gRPC would let people focus on the actual problems at play

gRPC exposes the random distractions of one side's internal processing activities instead of focusing on how the two sides of a process co-ordinate and co-operate.


I don’t know of any proxy in the wild that will cache anything other than GET or HEAD requests by default.


>GET is the only one that I've seen relied on

You're so quick to throw away a vastly used caching mechanism as if it's nothing.


GET was never the verb under discussion. I specifically listed PATCH, PUT, and POST as being effectively meaningless in practice. You can’t rely on APIs to do what the verbs say they will do.

I only called out GET to say that it is still only a good bet that it will do what it is supposed to do. It’s absolutely not guaranteed. You’ve never encountered GET web routes that mutate backend state? People rely on it —- but that doesn’t make it reliable.

“Throwing away” verbs like GET is not the same as throwing out caching. Please don’t twist my words into what they were not. In practice, you often still need to specify exactly which routes to cache, and how to cache them. Just using GET doesn’t magically make things cached, and you can just as easily cache non-GET routes once you’re specifying what to cache.

Caching can be done for anything. It isn’t some special feature of HTTP or REST APIs.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: