users@jersey.java.net

Re: [Jersey] best practice for generating unique id in the resources

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 03 Nov 2008 18:06:48 +0100

Hi Arul,

There is no really need to have a GET request to return an id, it is
redundant. There are then two very common patterns for creation of a
new resource:

1) The server is in control of the URI space.
      The client sends a POST request and a 201 is returned with the
URI that points to the newly created resource.

2) The client is in control of the URI space.
      The client sends a PUT request and a 201 is returned if the
resource identified by the request UR is created
      otherwise a 200 is returned (assuming success).


A example of 1) is:

> POST /collection

< 201 Created
< Location: /collection/1234


An example if 2) is:

> PUT /collection/1234

< 201 Created
< Location: /collection/1234


Ask the question: is the client or the server in control of the URI
space for creation of the resource?

For 1) there are also techniques for the client to hint to the server
the URI might be (AtomPub uses a slug header).

Paul.

On Nov 3, 2008, at 5:38 PM, Arul Dhesiaseelan wrote:

> Thanks Jeff and Paul for helping me out.
>
> May be I took a bad example to explain my use case. Let me try again
> explaining my requirement again.
>
> In our system, we have set of JPA entities (users, roles, etc). We
> have a Java API for end users to operate on these entities (addUser,
> addRole, etc). But, we do not expose the "id" (primary key) of these
> entities to the Java API. We are designing Rest API to be used by
> web front end. Rest API would be using Java API to operate on these
> entities (CRUD). Whenever, web users create "user" entity, we invoke
> UserResource which in turn calls the Java API to persist the user
> entity. The only unique piece of information for this entity is
> "username".
>
> The first option I had in mind was to stub the "id" using an atomic
> counter on the server-side (IdGenResource). These "ids" does not
> match with the database "id" associated with the entity, but it is
> just used to construct the unique URI.
>
> Request:
> GET /id HTTP/1.1
> Response:
> HTTP 200 OK 1234
>
> Request:
> POST /users/1234 HTTP/1.1
> Content-type: xxx
> Content-length: nnn
>
> ... etc ...
>
> Response:
> HTTP 201 Created
> Location: /users/1234
>
> I am not sure if this approach could be used to detect if a resource
> was created then deleted as per Paul's suggestion. But, this
> approach calls for an extra GET.
>
> Other option is to use the username as part of the URI:
>
> Request:
>
> POST /users/aruld HTTP/1.1
> Content-type: xxx
> Content-length: nnn
>
> ... etc ...
>
> Response:
> HTTP 201 Created
> Location: /users/aruld
>
>
> Appreciate your inputs on the pros and cons of these approaches. Is
> there any other better Restful approaches to be considered in
> designing URIs?
>
> Thanks!
> Arul
>
>
> Paul Sandoz wrote:
>>
>> On Nov 1, 2008, at 4:18 AM, Jeff Schmidt wrote:
>>
>>> Hi Arul:
>>>
>>> I think you want to do this:
>>>
>>> @POST
>>> @Consumes("application/xml")
>>> @Produces("application/xml")
>>> public Response addCustomer(Customer customer) {
>>> long customerId = 1234L; //Wherever this comes from (DB
>>> sequence, atomic counter etc.).
>>
>> If one utilizes an incremental counter then it is possible to
>> detect if a resource was created then deleted and thus distinguish
>> between 404 (Not Found) and 410 (Gone).
>>
>> An alternative is to use a UUID. Java has support for type 4 UUIDs
>> (random ones) but this may result in collisions...
>>
>> Paul.
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>