2014-10-09 35 views
7

Próbuję zrozumieć, jak tworzyć i modyfikować linki w Spring HATEOAS.Jak umieszczać i umieszczać linki w Spring HATEOAS

Załóżmy na przykład, że mam dwie kolekcje, jedną w api/users i drugą w api/event. Chciałbym powiązać użytkownika api/user/56 z zdarzeniem api/event/21. Dla argumentów jest to wiele-do-wielu - użytkownik może uczestniczyć w wielu wydarzeniach, wydarzenie może mieć wielu użytkowników.

Jak rozumiem, spokojny sposób robienia tego polega na użyciu identyfikatorów URI jako kluczy podstawowych, więc mógłbym opublikować następujące informacje na temat api/user/56/events;

{ 
    attends: "http://localhost:9090/api/event/21" 
} 

punkt końcowy następnie musi być zdolne do analizowania tego adresu URL i wyodrębniania identyfikatora (w tym przypadku 21) i sterownikiem (EventController.class), tak że można utrzymywać ten.

Pytanie 1: Czy jest to właściwy sposób radzenia sobie z relacjami w Spring Hateoas w zakresie API REST?

Pytanie 2: W jaki sposób mogę rozwiązać ten URL w kontroler do użytkowym uchwytem na danych (na przykład odniesienie do odpowiedniego kontrolera/metody, klucz podstawowy, etc)

Badań

Urządzenie RestTemplate może być używane do żądania danych ze sterownika wewnątrz metody mapowania żądań, tak jak to;

RestTemplate restTemplate = new RestTemplate(); 
ResponseEntity<EventResource> response = restTemplate.getForEntity(attendsUrl, EventResource.class); 
EventResource eventResource = response.getBody(); 

Jednak nie wierzę, że eventResource powinny pole Id powrócić jako część danych - to nie jest bardzo spokojny i to będzie narażony na API. Jednym z podejść jest posiadanie parametru "includePK = true", ale znowu nie jest to właściwe - po prostu ukrywa problem. Co więcej, idea serwera, który wysyła żądania do własnego API w ten sposób, wydaje się obwodowa.

Aktualizacja

Jest kwestią otwartą, za to tutaj https://github.com/spring-projects/spring-hateoas/issues/292. Opierając się luźno na niektórych komentarzach (przez użytkownika kevinconaway) z tego wydania stworzyłem szybką klasę utylizacji, która oferuje łatwe rozwiązanie tutaj: SpringHateoasUtils. Rozwiązanie sprowadza się do;

String mapping = DISCOVERER.getMapping(targetClass, targetMethod); 
UriTemplate template = new UriTemplate(mapping); 
//values is key/value map of parameters that the referenced method accepts 
Map<String, String> values = uriTemplate.match(uri); 

SpringHateoasUtils czyni to nieco ładniejsze, ale to nadal czuje się, że powinna być cechą. Będę starał się o coś napisać w tym wiosennym kodzie - kiedy będzie jasne, co się z tym stanie, odpowiem na to pytanie.

+0

Można by zakładać 'http: // localhost: 9090/api/wydarzenie/21' tylko. Spring HATEOAS nie pomaga Ci wyłuskać adresu URL.Jest przeznaczony tylko dla odpowiedzi, a nie dla żądań. Możesz rzucić okiem na [Spring Data REST] (http://projects.spring.io/spring-data-rest/) – zeroflagL

+0

Pracując z Spring HATEOAS przez kilka miesięcy zdecydowanie nie wydaje się, aby właściwie wspierać REST, więc musiałem wdrożyć podobne obejścia do tego, co opisujesz. –

Odpowiedz

1

Spójrz na odpowiedź tutaj:

POSTing a @OneToMany sub-resource association in Spring Data REST

Pytanie 1) Tak to jest jak umieszczać linki/Stosunki. Z identyfikatorami URI.

Pytanie 2) Identyfikator URI zasobu faktycznie IS jego identyfikator z perspektywy klienta. Serwer wewnętrznie automatycznie rozwiązuje ten URI do rzeczywistego przykład model z

org.springframework.data.rest.core.UriToEntityConverter.convert(...)

+0

To jest pytanie o Spring Hateoas - chociaż Spring Data Rest pozwala na ograniczone wykorzystanie linków, Spring Data Rest nie zapewnia sposobu implementacji własnej funkcjonalności obsługi linków. –

+0

Hello Andrew! Czy obejrzałeś opublikowany link? Zajęło mi trochę czasu, aby zrozumieć subtelne różnice. Ale w międzyczasie dowiedziałem się, jak zarchiwizować to, co próbujesz zrobić: Spring Data HATEOAS pozwala na "tworzenie" linków między podmiotami poprzez umieszczanie tekstu/listy uri, np. w następujący sposób: 'curl -X PUT -H" ContentType: text/uri-list "http: // localhost: 8080/api/myEntitty/1' z łączem uri jako ładunkiem' http: // localhost: 8080/api/myLinkedChildEntity/4711' Jeśli potrzebujesz więcej dostępu niskiego poziomu, zawsze możesz zaimplementować swój własny @RestController w czasie odpoczynku wiosennego – Robert