users@jersey.java.net

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

From: Arul Dhesiaseelan <arul_at_fluxcorp.com>
Date: Mon, 03 Nov 2008 11:01:41 -0700

Thanks Paul.

I assume in pattern 2 you meant PUT would return 201 (for add) and PUT
would return 200 (for update), right?

Another design question: Does sub-resource locators really makes sense
in pattern 1, I see it is useful in pattern 2?

If I choose pattern 2 to implement my use case, I can use the below
approach in my parent resource, which helps me to chain resources:

@Path("/root")
public class RootResource {
  @Path("/users/{id}")
  public UserResource getUserResource(@PathParam("id")long id) {
    return new UserResource(uriInfo, request, root, id);
  }
  @Path("/roles/{id}")
  public RoleResource getRoleResource(@PathParam("id")long id) {
    return new RoleResource(uriInfo, request, root, id);
  }
}

I don't think it is possible to have sub-resource locators in pattern 1?
If this is the case, how can I chain the resources if I choose to
implement this pattern?

Thanks again for the RESTful design tips.

-Arul

Paul Sandoz wrote:
> 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
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>