users@jersey.java.net

[Jersey] Re: URI to Resource mapping

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Wed, 22 Aug 2012 12:13:34 +0200

On Aug 17, 2012, at 4:37 PM, franck102_at_yahoo.com wrote:

> Hi,
>
> I am new to Jersey, and struggling to come up with the correct design
> patterns for my resource hierarchy, especially w.r.t subresources,
> injection and URIs.
>
> I have a fairly simple multi-level hierarchy, let's say bookstore -
> sections - books and unique IDs for sections & books:
> /bookstore/sections/adventure
> /bookstore/sections/adventure/books/some-book-id
>
> I have three specific questions:
>
> 1. I have a sections resource locator in the bookstore resource with an
> "sectionID" path param. I have found various versions on the web of the
> proper code to instantiate the subresource so that it can benefit from
> injection; including a post mentioning having to use a Scope of
> "prototype" if more then one subresource is to be instantiated in the
> request. Most of the posts are pretty old, so I am unclear as to
> whether they are still valid? Is this pattern the recommended approach:
>
> @Path("sections/{sectionId}")
> public SectionResource getSection(@PathParam("sectionId") String
> sectionId)
> {
> SectionResource res =
>
> _resourceContext.getResource(SectionResource.class);
> res.setId(sectionId);
> return res;
> }
> Is there any way to have the sectionId injected (to avoid the setId
> call)?

Yes, the story is still valid - you should use an injectable ResourceContext instance to get an instantiated and fully injected resource instance. This means that you may use the @PathParam directly in your SectionResource to inject the "sectionId" value:

@Path("bookstore")
public class BookStore {
    @Path("sections/{sectionId}")
    public SectionResource getSectionResource(@Context ResourceContext rc) {
        return rc.getResource(SectionResource.class);
    }
}

public class SectionResource {
    @GET
    public get(@PathParam("sectionId") sectionId) { ... }
}

> I can't find any documentation about a prototype scope, what is the
> story there?

I'm not sure I understand what you mean.

>
> 2. When processing a PUT of a property on a book (e.g. genre) I need to
> access the book's section model. Would
> ResourceContext.matchResource(".../bookstore/sections/adventure")
> return a SectionResource properly initialized for "adventure"? i.e.
> will it call my locator and set the sectionId?
> Knowing that the book is a subresource of its section, is there a
> better way to access the parent resource (other than an explicit
> setSection in the book's locator)?

Yes. ...why don't you just try it out? :)

>
> 3. Each book holds a URI to an author resource that lives under
> /bookstore/authors/some-author.
> When receiving a PUT request to update the author of a book, can I use
> ResourceContext.matchResource(<supplied author URI>) to validate that
> the author exists?

Yes.

Marek

>
> Any help will be greatly appreciated!
> Thanks