Re: REST "create if not exists"
mike amundsen <[email protected]>
| Newsgroups | gmane.comp.web.services.rest |
|---|---|
| Message-ID | <CAPW_8m7m6Ud_4oA5F4r_gfc7qkiWEWPhQKgaQGbYcTVKVGc=uQ@mail.gmail.com> |
François
First, I highly recommend you check out the "RESTful Web Services
Cookbook"[1]. It's full of very solid examples of solving problems /w HTTP.
Second, you have quite a bit in this message and I'll only address some
top-level items here.
Third, FWIW, all your Qs seem to be related to the HTTP protocol, not
Fielding's REST style; not a probem, just an observation.
- "We want to allow the registration of filters."
Your example of creating filters looks fine here.
- "But if I (or someone else) do it again, I'll end up with another
{filter-id}, e.g. 123457. Then we'll have two resources with the exact same
meaning and content."
And why is this a problem? does it crash your server? cause you to run out
of storage? return bad results? cause business rules to go awry? I suspect
you want to _optimize-out_ this seeming duplication. FWIW, I find it quite
difficult to _prevent_ duplication in a distributed system and I only
attempt it when it will crash the system or cause incorrect results. If two
of the thousands of users I have in my system both store the same filter,
results, list of groceries to purchase this weekend, I rarely care.
I think most of the rest of your post here is dedicated to attempting
something incredibly creative in order to prevent something extremely
common<g>.
[1] http://shop.oreilly.com/product/9780596801694.do
mca
http://amundsen.com/blog/
http://twitter.com@mamund
http://mamund.com/foaf.rdf#me
On Sat, Jun 2, 2012 at 3:50 PM, francoisverry <[email protected]> wrote:
>
>
> Hello
>
> I'm new to REST, and I'm trying to integrate it in my company. We
> currently are trying to design a multi-criteria search engine with REST
> principles. I use as a reference the O'Reilly "RESTful Web Services".
>
> I don't know if the following problem has been discussed somewhere, but
> I've been unable to find anything that matches it. If you happen to know
> resources that could help me, please let me know.
>
> In a multi-critera search engine, we have two types of resources :
> "Results" and "Filters". Results are items searched for, and Filters are
> sets of criteria which allows us to isolate a subset of Results.
>
> For example :
>
> GET /results returns the total number of results
> GET /results/{result-id} returns one specific result
> GET /filters returns a specification on criteria usage (eg. an empty
> <form>)
> GET /filters/{filter-id} returns one specific filter (eg. a filled
> <form>)
> GET /filters/{filter-id}/results returns the total number of results
> matching the filter, and links to the corresponding /results/{result-id}
>
> We want to allow the registration of filters. Imagine a filter as the
> composition of 3 criteria, c1, c2 and c3. My first thought was to register
> a filter through a POST request.
>
> Request :
>
> POST /filters HTTP/1.1
>
> c1=foo&c2=bar&c3=baz
>
> Response :
>
> HTTP/1.1 201 Created
> Location: /filters/123456
>
> But if I (or someone else) do it again, I'll end up with another
> {filter-id}, e.g. 123457. Then we'll have two resources with the exact same
> meaning and content.
>
> If I want to use one URI for one criteria set, PUT seems more appropriate.
> The thing is, the {filter-id} is assigned "randomly" by the server. As a
> client, I can't guess nor force it. From there, I see the following
> solutions, neither I find satisfying :
>
> 1/ I try to map artificially my URIs to the criteria set. I could use a
> hash of the representation. e.g. :
>
> Request :
>
> PUT /filters/53c11504ba50e14b60407b13a72c0e53 HTTP/1.1
>
> c1=foo&c2=bar&c3=baz
>
> Response :
>
> HTTP/1.1 200 OK
>
> <form method="PUT" action="/filters/53c11504ba50e14b60407b13a72c0e53">
> <input name="c1" value="foo" />
> <input name="c2" value="bar" />
> <input name="c3" value="baz" />
> <input type="submit" />
> </form>
>
> The problem is : it is artificial. If my criteria set changes, or if its
> representation changes, I could end up with conflicts or doubles.
>
> 2/ I trick the client into believing it actually created something new,
> whether or not it has. This means, even if /filters/123456 already exists,
> my server will answer it to anyone POSTing the "c1=foo&c2=bar&c3=baz"
> content.
>
> The problem is : it's a fraud. Only the initial POST really "appends"
> something.
>
> 3/ I answer the second-and-further POST requests with a "409 Conflict"
> answer, and the correct location.
>
> The problem is : it is not actually an error. The client doesn't care to
> register something, it just has no way to know wheter or not the resource
> he is looking for already exists.
>
> 4/ I do a preliminary check
>
> Request :
>
> GET /filters?c1=foo&c2=bar&c3=baz HTTP/1.1
>
> Response :
>
> HTTP/1.1 301 Moved Permanently
> Location: /filters/123456
>
> The problem is : If the resource doesn't exists at that time, I'll be
> willing to create it. If I do, nothing ensures me that someone hasn't
> created it inbetween. Then, if I want to put aside a location for my
> resource, it implies my GET isn't safe anymore.
>
> 5/ The last option I see is that the URI should contains the whole content
> of the resource, as it is its "natural" identifier. This is especially
> difficult if I have a large set of criteria, and if their values are
> complex. This is why we use ids in the first place.
>
> Thanks in advance for your help
>
> François
>
>
>
>