If-None-Match on POST

1,009 views
Skip to first unread message

erewhon

unread,
Dec 11, 2013, 9:23:03 PM12/11/13
to api-...@googlegroups.com
Hey,

We have a collections resource that returns an ETag.  You can POST to this resource to add items to the collection.  We currently reject requests with a 400 if the client submits a POST with an If-None-Match header, but it turns out there are clients that do exactly this.  Nothing in the spec says you *can't* supply If-None-Match in POST, but I'm not sure I'm comfortable relaxing our API for a non-critical client use case.

Thoughts?


Jon Moore

unread,
Dec 12, 2013, 5:30:38 AM12/12/13
to api-...@googlegroups.com
Seems like a legitimate use case, though: it can help avoid double-posting something to the collection. In particular, this allows a client to retry a POST where the network connection got interrupted without having to re-GET the collection to see if the first attempt went through or not (although it will then still need to do so if you return a 412).

Jon
........
Jon Moore
--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/groups/opt_out.

erewhon

unread,
Dec 12, 2013, 9:04:35 AM12/12/13
to api-...@googlegroups.com
I agree that seems like a good use case, but wouldn't you want to use "If-Match" rather than "If-None-Match" to assert that you (the client) knows the current state of the resource and that the POST should only occur if the resource hasn't changed?  I can see the use case for "If-None-Match: *" where we're saying "if any resource exists here, do not perform this POST".

I'm also wondering, perhaps more generally, whether returning an error code is wrong or too restrictive.  I want to be informative to the client "hey, that ETag is not used/allowed for POST operations on this resource".  At least one client we came across is populating If-None-Match headers in POST operations, which I think is weird.

Steve Klabnik

unread,
Dec 12, 2013, 12:21:15 PM12/12/13
to api-...@googlegroups.com
When in doubt, Check the RFC:

It is also used to prevent a method (e.g. PUT)
from inadvertently modifying an existing resource when the client
believes that the resource does not exist.

http://tools.ietf.org/html/rfc2616#section-14.26

And

If-None-Match can also be used with a value of "*" to prevent an
unsafe request method (e.g., PUT) from inadvertently modifying an
existing representation of the target resource when the client
believes that the resource does not have a current representation
(Section 4.2.1 of [Part2]). This is a variation on the "lost update"
problem that might arise if more than one client attempts to create
an initial representation for the target resource.

http://tools.ietf.org/search/draft-ietf-httpbis-p4-conditional-25#section-3.2

It doesn't say anything about POST, but seems pretty legit to me, and
it's not specifically disallowed either.

erewhon

unread,
Dec 12, 2013, 2:26:02 PM12/12/13
to api-...@googlegroups.com
Yeah for sure, I've gone over that section of the RFC, but think about the case where you specify the following in a POST:

If-None-Match: abcd1234

Why would you ever want to do this?  I suppose in some very strange edge case you might want to tell the server "only apply this POST operation if something *has* changed".  Weird.

Anyway, I suppose the right thing to do here would be to relax the API and ignore the If-None-Match header rather than responding with an error?

K

Jon Moore

unread,
Dec 12, 2013, 5:56:11 PM12/12/13
to api-...@googlegroups.com, api-...@googlegroups.com
Yes, I agree that this is a "weird" request (I see that I read your post too quickly at first vis-a-vis If-Match vs. If-None-Match). That said, I think there are a couple of viable choices:

1. Continue with a 400 as you currently have. If you support If-Match but would not support an unconditional request this is a good bet, as a POST with 'If-None-Match: "abc"' is pretty darn close to an unconditional POST most of the time.

2. Simply implement the semantics of the request as specified, as these *are* well defined by the spec and the logic isn't that much harder to implement if you are supporting If-Match anyway. If you are allowing unconditional POSTs this is what I'd probably do.

I do *not* think you should just ignore the header, though, as I think that could break the client's intentions, however weird they might be.

Jon

........
Jon Moore
--
Reply all
Reply to author
Forward
0 new messages