On Mon, Jun 7, 2010 at 2:49 PM, danomano <dshopkins_at_earthlink.net> wrote:
>
> I have a requirement to implement an api as follows:
>
> PUT
> ../resource/<id>
> <body is payload>
>
> Result: new resource is created (error is resource already exists)
>
> PUT
> ../resource/<id>?someField=abc
> <NO BODY>
>
> Result: update the resource such that someField = abc.
>
> I tried mapping this as follows:
> @PUT
> @Path("/{resourceId}")
> public void createOrUpdate(Resource resource,
> @PathParam("resourceId") String resourceId,
> @QueryParam("someField") Long someField);
>
> however this only appears to work if the Resource payload is present, i.e.
> if I do an HTTP PUT, without a payload the method is never invoked.
>
> I tried mapping as well to 2 seperate methods, one with payload (minus the
> queyParam), and one without the playload but with the queryParam, but that
> was ambigious for jersey..so that didn't work)
>
> Is this mapping not possible?
> (and yes I argued the user should be forced to issue put-update calls with
> the payload rather then the queryparam..but got overruled).
>
> Any advice? (Am I going be stuck with using servlets as my
> interface?..yuk..I could inject an empty <Resource/> I suppose with a
> servletFilter..)
Several things to think about:
(1) Per RFC 2616 Section 9.4[1], a PUT with no body violates the HTTP spec,
so it's hard to be sympathetic with a complaint that a framework
like JAX-RS doesn't support that use case.
(2) Even if you moved the "someField=abc" into the body, using
PUT for partial updates also violates the intent of PUT as defined
in HTTP. For partial updates, consider using the PATCH method,
which was recently standardized[2]. (You'll have to define your
own annotation for it with current versions of JAX-RS, but its easy).
(3) In RFC 2616, Section 9.1, requirements for idempotent requests
are described -- in particular, the fact that an idempotent can be
repeated by the client with no negative side effects. The problem
with using PUT for resource creation is that PUT is required to be
idempotent, so it is difficult to enforce this requirement unless there
is some unique identifier within the resource body that will cause
a duplicate create request to get caught, and thus avoid creating
two or more records. POST is generally easier to deal with in this
regard, although you still need to figure out what happens when a
client, say, doesn't receive any response to an initial POST and
therefore tries it again. (This, by the way, is why browsers warn you
when you use the back arrow and then try to submit a form using
POST again.)
[1]
http://www.ietf.org/rfc/rfc2616.txt
[2]
http://www.ietf.org/rfc/rfc5789.txt
>
> thanx
> Dan
Craig