2014-09-09 15 views
6

Tak naprawdę nie można nazwać zasobami zagnieżdżonymi z perspektywy odpoczynku, ale jestem zainteresowany tym, jak skonstruować klasę Jersey jako dostawcę odpoczynku, aby mógł odpowiedzieć do połączonych żądań.Zagnieżdżone zasoby w Jersey/JAX-RS do implementacji Przykład przekątnej

tzn. Jestem w porządku z podstawowymi/użytkownikami, jestem w porządku z/users/123, aby uzyskać konkretnego użytkownika, ale jak wtedy odejść do właściwości użytkownika ..../users/123/cars,/users/123/cars/23 itd.

Przepraszamy za brak informacji, ale widzieliśmy to jako przykład w dokumentacji przekroju dla Angular.

https://github.com/mgonto/restangular#production-apps-using-

restangular 

// Restangular returns promises 
Restangular.all('users').getList() // GET: /users 
.then(function(users) { 
    // returns a list of users 
    $scope.user = users[0]; // first Restangular obj in list: { id: 123 } 
}) 

// Later in the code... 

// Restangular objects are self-aware and know how to make their own RESTful requests 
$scope.user.getList('cars'); // GET: /users/123/cars 

// You can also use your own custom methods on Restangular objects 
$scope.user.sendMessage(); // POST: /users/123/sendMessage 

// Chain methods together to easily build complex requests 
$scope.user.one('messages', 123).one('from', 123).getList('unread'); 
// GET: /user/123/messages/123/from/123/unread 

Odpowiedz

8

myślę lokalizatory zasobów powinno załatwić sprawę. Zasadniczo przesyłają one żądanie do innego zasobu, który jest w stanie go wykorzystać.

W twoim przypadku będziesz mieć jeden zasób główny UserResource, który będzie obsługiwać użytkowników i sub-zasoby dla samochodów, wiadomości - CarsResource, MessagesResource.

Zasób root:

@Path("users") 
class UsersResource { 

    // GET: /users 
    @GET 
    @Path("{id}") 
    public User getById(@PathParam("id") long id) {...} 

    @Path("{id}/cars") 
    public CarResource getCarResource(@PathParam("id") long userId) { 
     return new CarResource(uesrId); 
    } 

    @Path("{id}/sendMessage") 
    public MessagesResource getMessagesResourceForSend(@PathParam("id") long userId) { 
     return new MessagesResource(userId); 
    } 

    @Path("{id}/messages") 
    public MessagesResource getMessagesResourceForRead(@PathParam("id") long userId) { 
     return new MessagesResource(userId); 
    } 
} 

Samochody i komunikaty zasoby:

class CarsResource { 
    long userId  

    // GET: /users/123/cars 
    @GET 
    public Car getAllCars() { 
     /*retrieve all cars for user userId*/ 
    } 

    // GET: /users/123/cars/3 
    @GET 
    @Path("{carId}") 
    public Car getById(@PathParam("carId") carId) { 
     /*retrieve car for id carId*/ 
    } 
} 

class MessagesResource { 
    long userId 

    // POST: /users/123/sendMessage 
    @POST   
    public void sendMessage(@FormParam("content") String content) { 
     /*send message to user userId*/ 
    } 

    // GET: /user/123/messages/123/from/123/unread 
    @GET 
    @Path("{id1}/from/{id2}/unread") 
    public void getUnread(@PathParam("id1") long id1, @PathParam("id2") long id2) { 
      /*return unread messages*/ 
    } 
} 

Sub-zasoby nie powinny być odnotowany z @Path na poziomie klasy i muszą być zarejestrowani w JAX -RS runtinme w klasie aplikacji

+0

Dzięki za odpowiedzi, pozwól mi zrobić trochę więcej dochodzenie w moim projekcie potem wrócę i zaakceptować jako odpowiedź, dzięki bardzo dużo. Nie jestem pewien, czy rozumiem, jak powraca funkcja CarResource jako odpowiedź w tym przypadku, kiedy to, czego chcę, to zbiór instancji Car ... ale tutaj zwracamy instancję CarResource. – smackenzie

+0

Tak, to jest sztuczka polegająca na tym, że zwrócenie instancji zasobu faktycznie wywołuje żądanie do zwróconego zasobu. możesz przeczytać dalsze informacje [tutaj] (https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e2176) –

0

oprócz odpowiedzi Thomasa Bartalosa, możliwe jest użycie parametru parametru ścieżki w pod-zasobach

@GET 
@Path("{id1}/from/{id2}/unread") 
public void getUnread(@PathParam("id") long userId,@PathParam("id1") long id1, @PathParam("id2") long id2) 
{ 
     /*return unread messages for user with userId*/ 
} 

Jest to przydatne w przypadku korzystania z fasoli bezstanowej, unika przekazywania parametru userId podczas instanciation.

Przykład: root resource:

@Path("users") 
@Stateless 
class UsersResource { 
    @Inject CarResource cr; 
    @Inject MessageResource mr; 
    // GET: /users 
    @GET 
    @Path("{id}") 
    public User getById(@PathParam("id") long id) {...} 

    @Path("{userId}/cars") 
    public CarResource getCarResource() { 
     return cr; 
    } 

    @Path("{userId}/sendMessage") 
    public MessagesResource getMessagesResourceForSend() { 
     return mr; 
    } 

    @Path("{userId}/messages") 
    public MessagesResource getMessagesResourceForRead() { 
     return mr; 
    } 
} 

sub zasoby:

@Stateless 
@Path("/") 
class CarsResource { 
    @GET 
    public Car getAllCars(@PathParam("userId") long userId) {//the path param is retrieved from parent path 
     /*retrieve all cars for user userId*/ 
    } 

    @GET 
    @Path("{carId}") 
    public Car getById(@PathParam("userId") long userId,@PathParam("carId") carId) { 
     /*retrieve car for id carId fr the user with userId*/ 
    } 
} 

@Stateless 
@Path("/") 
class MessagesResource { 
    @POST   
    public void sendMessage(@PathParam("userId") long userId,@FormParam("content") String content) { 
     /*send message to user userId*/ 
    } 

    @GET 
    @Path("{id1}/from/{id2}/unread") 
    public void getUnread(@PathParam("userId") long userId,@PathParam("id1") long id1, @PathParam("id2") long id2) { 
      /*return unread messages*/ 
    } 
}