How to deal with multiple sub resources in JAX-RS?
<p>I have a JAX-RS REST API with several sub resources e.g. </p>

<p><code>users/{user_id}/posts/{post_id}/comments/{comment_id}</code>. The resources are divided into individual classes (<code>UsersResource</code>, <code>UserResource</code>, <code>PostsResource</code>, etc.) and accessed via sub resource locators. Each resource uses a correlating service (<code>UserService</code>, <code>PostService</code>, <code>CommentService</code>) to access the database.</p>

<p>How would I go about realising this? I tried to search for an example but was only able to find very basic ones.</p>

<p>I already implemented several approaches but they all "feel" wrong.</p>

<p>One was to inject all services in the root resource and pass them along. But it seems wasteful to instantiate all services although only the first might be needed.</p>

<p>Another was to make all resources <code>@RequestScoped</code> and inject the subsequent resource so the right service can be injected at the right place. But I would need to inject the sub resource in advance even if I didn't need it and I wouldn't be able to pass parameters along.</p>

<p>My current approach fails at not being able to inject the service inside my sub resource. (see below)</p>

<p><code>root resource (resources/users)</code></p>

<pre><code>@RequestScoped
@Path("users")
public class UsersResource() {

    @Inject
    private UserService service;

    @Path("{user_id}")
    public UserResource getUserResource(@Context ResourceContext context, @PathParam("user_id") Long id) {
        User entity = this.service.find(id);

        if (entity == null)
            throw new WebApplicationException(Response.status(Status.NOT_FOUND).build());

        return context.initResource(new UserResource(entity, this.service));
    }
}
</code></pre>

<p><code>user sub resource (resources/users/{user_id})</code></p>

<pre><code>public class UserResource() {

    private User entity;
    private UserService service;

    public UserResource(User entity, UserService service) {
        this.entity = entity;
        this.service = service;
    }

    @GET
    public Response doGet() {
        return Response.ok(entity).build();
    }

    @Path("posts")
    public TodosResource getPostsResource(@Context ResourceContext context) {
        return context.initResource(new PostsResource(entity));
    }
}
</code></pre>

<p><code>posts sub resource (resources/users/{user_id}/posts)</code></p>

<pre><code>public class PostsResource() {

    @Inject // can't inject here
    private PostService service;

    private User user;

    public PostsResource(User user) {
        this.user = user;
    }

    @POST
    public Response doPost(@Context UriInfo info, Post post) {
        post.setUser(this.user);
        Post entity = this.service.persist(post);
        URI uri = info.getAbsolutePathBuilder().path("/" + entity.getId()).build();

        return Response.created(uri).entity(entity).build();
    }

    @Path("{post_id}")
    public PostResource getpostResource(@Context ResourceContext context, @PathParam("post_id") Long id) {
        Post entity = this.service.find(id);

        if (entity == null)
            throw new WebApplicationException(Response.status(Status.NOT_FOUND).build());

        return context.initResource(new PostResource(entity));
    }
</code></pre>

<p>service example</p>

<pre><code>@Stateless
public class UserService {

    @PersistenceContext
    private EntityManager em;

    (...)
}
</code></pre>