2012-01-11 6 views
6

Zakładam, że mam dwa zasoby najwyższego poziomu: Foo i Bar. Teraz Foo muszą być połączone z niektórymi z Bar. W klasie Java może to wyglądać mniej więcej tak:Projektowanie interfejsu REST API: łączenie zasobów

public class Foo { 

    Set<Bar> bars; 
} 

public class Bar { … } 

Chciałbym kształtować reprezentację XML Foo aby coś takiego:

GET /foos/1 

<foo> 
    … 
    <atom:link rel="self" href="/foos/1" /> 
    <atom:link rel="bars" href="/foos/1/bars" /> 
</foo> 

Więc dość dużo wystawiać wszystkie Barprzypisany do Foo jako zasób zagnieżdżony. Oznacza to, że zasoby mają indywidualny cykl życia (agregacja zamiast kompozycji). Zasób zagnieżdżony może wtedy wystawiać wszystkich połączonych Bar coś takiego:

GET /foos/1/bars 

<bars> 
    <atom:link rel="bar" href="/foos/1/bars/1" /> 
    <atom:link rel="bar" href="/foos/1/bars/2" /> 
</bars> 

Alteratively mogłem Inline kolekcję w <foo> elementem góry. Jednak wciąż mam kilka pytań: podczas gdy to pozwala mi ładnie usunąć Bar z Foo przez wywołanie żądania do np. DELETE/foos/1/bars/1, ale w jaki sposób przypisałbym wtedy Bar do Foo? Zakładając, że klient będzie uzyskanie dostępu /bars:

GET /bars 

<bars> 
    <bar> 
    … 
    <atom:link rel="self" href="/bars/4711" /> 
    </bar> 
</bars> 

i decydując chce przypisać /bars/1 do /foo/1/bars. Myślałem o zgłoszeniu POST do /foo/1/bars, ale nie byłem pewien, co przesłać. Element link wskazuje na zasób Bar, taki jak poniższy?

POST /foos/1/bars 

<atom:link href="/bars/4711" /> 

Wydaje się to całkiem w porządku, ponieważ klienci wciąż nie będą musieli tworzyć adresów URL i nadal będziemy spełniać ograniczenia REST. Jednak wydaje się nieco dziwne, jeśli chodzi o linki do serwera. Czy istnieje lepsze rozwiązanie tego scenariusza?

+1

Bez wahania przyjmuję POSTing link do ustalenia związku między dwoma zasobami. Niektórzy uważają, że powinieneś pobrać zasób, a następnie POST, aby był on samopisujący, ale nie jestem przekonany, że jest to konieczne. –

+0

To też uważam za powód, dla którego tworzysz niepotrzebną rozmowę, i b) nie potrzebujesz rzeczywistej potrzeby, aby rzeczywiście utworzyć link. –

Odpowiedz

4

Myślę o tym w kategoriach zasobów rozumianych przez serwer, a nie reprezentacji XML, które płyną w odpowiedzi na (powiedzmy) żądanie GET. Mam usługi RESTful, które zwracają JSON lub XML, lub potencjalnie inne reprezentacje.

Tak zgadzam się z komentarz lub oddanie do

/foos/{fooId}/bars 

określić zarówno pełną listę barów lub dodanie kilku barów.

Format przesyłanego ładunku może być dowolny, niezależnie od tego, jaki jest naturalny, zserializowany formularz dla typu mediów, z których korzysta użytkownik. W moim przypadku jest to często ciąg znaków JSON, więc w mojej implementacji usługi deserializowałaby się i wyświetlała tablicę referencyjnych ciągów URL odsyłania.

Jeśli Twój

<atom:link href="/bars/4711" /> 

również deserialise ładnie to ja nie widzę problemu, jeśli formularz odcinkach jest trochę, hm, ozdobnych.

Podsumowanie: rób to, co naturalne dla twojego serializera (de).

+0

Właściwie nie uważam, że rzeczywiste przedstawienie ma tutaj znaczenie. To samo pytanie pojawiłoby się, gdybym używał JSON. Po prostu wybrałem XML jako przykład, ponieważ istnieje standardowy element 'link' i będę musiał wymyślić coś sam w JSON. Dzięki za odpowiedź! –

+0

cóż reprezentacja w twoim przypadku ma słowa atom: link, i myślałem, że to jest powodem twojej troski. Unikalny identyfikator, taki jak "/ bars/4711", wydaje mi się dość niekontrowersyjny - musisz mieć jakiś identyfikator, prawda? – djna

+0

W porządku, powodem dla mnie może być nieco dziwne, że wysłałem linki z serwera do klienta tylko do tej pory, aby umożliwić klientowi nawigowanie po zasobach. Nigdy nie musiałem WYJŚĆ linku z powrotem i utknęło w nim poczucie, że klient będzie musiał podać adres URL, a tym samym złamać zasady REST. Ale tak naprawdę odkrywa to z góry, więc powinienem czuć się dobrze. –