Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> POST - Asks the server to create a new resource

> PUT - Asks the server to edit/update an existing resource

Maybe I've been doing it wrong all these years but it seems to me that the guides flip-flops the responsibility of POST and PUT. My understanding is that POST should edit/modify while PUT creates/replaces a resource.



> My understanding is that POST should edit/modify while PUT creates/replaces a resource

The way I've been segmented them is based on idempotency.

If you repeat the same call multiple times, do you get the same result as if you just ran it once? Then PUT is appropriate.

But if you have side-effects like creating new resources, that would result in different action each time you make the call, then POST it is.

Idempotent methods include GET, HEAD, PUT and DELETE, the resource should always end up in the same state after calling them N times (barring errors/exceptions and such of course). I'm fairly I got this from when I initially read the specification, it's probably mentioned with a bit more grace in the HTTP/1.1 spec.


Are you mistaking POST for PATCH? What I've been working with is:

- POST creates

- PUT replaces (i.e. edit, but you need to provide the whole resource)

- PATCH edits (i.e. you can only provide some fields)

APIs rarely implement all these properly in practice but that's my understanding of the theory.


I remember getting an interview question wrong when I said "yeah a get is supposed to just respond with data but you're writing it, you can make it do whatever you want"


I mean most GET requests have at least one side effect: one or more cache writes.

I’ve also implemented some GET endpoints that are a GET but have a side effect of marking something as read. (Normally as a variant to an existing endpoint for sessioned user).

I would expect at a minimum though if you are doing writes during a GET it should be idempotent.


Well, caching a response to a GET request is always going to be subject to variables like Etag and other hashes of the request, time limits, etc. which all ensure that responses, even old responses, are never _wrong_, they're at worst _stale_.

That's different, and safer, than something like a "read" bit on an entity, presumably tracked in an application data layer. I don't think you can mark something as "read" in your application from a GET request. Even if your server sees the response to that GET request as successful, it doesn't necessarily mean that the requesting client actually successfully received the response. As one of infinitely many possible counter-examples, consider a middlebox between a client and your server, where one client request to the server may generate N requests from the middlebox to the server.


While you might technically correct about using a GET to mark a “read” bit as correct on some activity, in reality there’s a trade off to doing it in a PUT.

Let’s say you have some notification resource which is a link redirecting to the thing that triggered the notification. Ideally the notification will automatically be marked read after the user sees the thing they clicked.

My setting the read bit in the GET that makes the redirect you open up. 2 negative possibilities:

- if someone could guess the GUIDs of the notifications they could CSRF a users notifications as marked read. (Unlikely and low impact if it does occur). - Adds the potential that the client may not have loaded page after the redirect and seen the resource.

There is a UX tradeoff now though if we make this a separate PUT after the page loads:

- in a web application context the user will have to either enable JavaScript so the app can automatically mark this as read or have a separate form on every landing page to mark it as read.

Another alternative would be to make this a POST form to view the notification that redirects but you have in effect the same issue of the user maybe not loading the page after the redirect.

At the end of the day for something as minor as a notification being marked read (as a result of a user clicking directly on it), some idempotent modification can work out and be easy to implement.

Now to be clear I am referring to a purpose built endpoint for a web application.

We expose 1000s of truly restful endpoints that are used outside of a web context and something like this doesn’t really make sense for them.


You probably wouldn't use a PUT for anything like this, true. But if you're going to mark a message as "seen" in a way that would impact a UI widget like an "unread notifications" red dot, then you almost certainly want to make sure that the state-changing request for that message is a POST, not a GET.

There are just so many ways for GET requests to be delivered to a server (or load balancer, or IP, or domain, or...) multiple times for a given client request. That capability is built in to HTTP and exploited in more places than you can ever hope to account for, or even detect.


During any serious side effects with a GET is a bad idea because of xsrf anyways


This is indeed the standard, AFAIK. Not sure what resources mention otherwise but it seems like a lot, judging by the comments around


POST is a kitchen sink. It can do anything. If it creates it must return a 201 with the new resource's location, otherwise if it succeeds but does not create a new resource (just modifies one) then it must return 200.


PUT can create - depending on whether the resource name is client or server determined.


Somewhat agreed, I see them as:

PUT - is effectively an "upsert" at a specific url. Doesn't exist? Create it, does exist? replace it.

PATCH - update a resource with a diff, at a specific url.

POST - this is a RPC, in the case of a REST API it can be used to create a new resource where the "id" is not provided and set by the server, it then redirects to the new url.

POST can be used for any RPC endpoints, even as part of a REST api.


I thought the same, but apparently the article is correct

https://www.ietf.org/rfc/rfc2616.txt


Interesting. I guess I've been going off of RFC 7231

> The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.

https://www.ietf.org/rfc/rfc7231.txt


My rule of thumb: if you know the ID of the resource you’re creating, it’s a PUT. If the system generates the ID, then it’s a POST.


More generally the URI instead of the ID.


The I in URI, stands for Identifier...


I’ve always known it as stated in the article, and I’m pretty sure that’s right, though I’ve never noticed any functional difference between the two (aside from what any given API may enforce).


And also what if you have a huge nested query which is only reading the database but is difficult to pack into URL parmeters (too long for example and you hit a character limit)? POST with a json body instead of GET even though it's against RESTful principles?


This is one acceptable workaround. Generally having caching at this point is unnecessary, and it's probably a good idea or developers to pay special attention if doing this.

If you have a longer-running query you could alternatively construct a Query resource of some sort and then GET it until it's ready.




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

Search: