Projektuję pragmatyczny interfejs API REST i trochę utknąłem na tym, jak najlepiej dodawać istniejące elementy do kolekcji. Mój model domeny obejmuje projekt, który ma zbiór witryn. Jest to ścisła relacja wiele do wielu i nie muszę tworzyć encji, która jawnie modeluje relację (tj. ProjectSite).
Mój interfejs API pozwoli konsumentom dodać istniejącą witrynę do projektu. Rozłącza mnie to, że jedyne dane, których naprawdę potrzebuję, to ProjectId i SiteId. Mój początkowy pomysł brzmiał:
1. POST myapi/projects/{projectId}/sites/{siteId}
Ale myślałem również
2. POST myapi/projects/{projectId}/sites
z jednostką witryny wysłaną jako treść JSON.
Opcja 1 jest prosta i działa, ale nie wydaje się całkiem właściwa, i mam inne relacje, które nie mogą podążać za tym wzorem, więc dodaje niespójności do mojego interfejsu API.
Opcja 2 wydaje się lepsza, ale prowadzi do dwóch obaw:
- Czy powinienem utworzyć witrynę, czy zgłosić wyjątek, jeśli zostanie opublikowana nowa witryna (SiteId = 0)?
- Ponieważ do utworzenia relacji potrzebuję tylko ProjectId i SiteId, witryna może zostać opublikowana z błędnymi lub brakującymi danymi dla innych właściwości.
Trzecią opcją jest zapewnienie prostego punktu końcowego wyłącznie do tworzenia i usuwania relacji. Ten punkt końcowy oczekiwałby ładunku JSON zawierającego tylko ProjectId i SiteId.
Co myślisz?
źródło
Odpowiedzi:
POST jest czasownikiem „dołączającym”, a także czasownikiem „przetwarzającym”. PUT jest czasownikiem „twórz / aktualizuj” (dla znanych identyfikatorów) i prawie wygląda tutaj właściwy wybór, ponieważ znany jest pełny docelowy identyfikator URI.
projectId
isiteId
już istnieją, więc nie trzeba „POST do kolekcji”, aby utworzyć nowy identyfikator.Problem z PUT polega na tym, że ciało musi reprezentować zasób, który umieszczasz. Ale tutaj chodzi o dołączenie do zasobu kolekcji „projekt / witryny”, a nie o aktualizację zasobu Witryna.
Co się stanie, jeśli ktoś UMIESZCZY pełną reprezentację JSON istniejącej witryny? Czy należy zaktualizować kolekcję i obiekt? Możesz to wesprzeć, ale wygląda na to, że nie o to chodzi. Jak powiedziałeś,
Zamiast tego postaram się wysłać test POST
siteId
do kolekcji i polegać na „dołączaniu” i „przetwarzaniu” natury testu POST:Ponieważ modyfikujesz zasób zbioru witryn, a nie zasób witryny , to jest to odpowiedni identyfikator URI. POST potrafi „dołączyć / przetworzyć” i dodać element o tym identyfikatorze do zbioru witryn projektu.
To wciąż pozostawia drzwi do tworzenia zupełnie nowych stron dla projektu poprzez rozwinięcie JSON i pominięcie identyfikatora. „Brak identyfikatora” == „Utwórz od zera”. Ale jeśli identyfikator URI kolekcji otrzyma identyfikator i nic więcej, jasne jest, co musi się stać.
Interesujące pytanie. :)
źródło
POST
zamiastPUT
lubPATCH
tutaj jest to, że nie masz całejSite
encji do umieszczenia wsites
zasobie. Masz tylko identyfikator, który wymaga przetworzenia, aby dodać go do kolekcji.Używamy tej
Patch
metody do takich rzeczy. Co chcesz zrobić, to zmodyfikować istniejący projekt, aby dodać do niego witrynę.Więc coś takiego działałoby
z jednostką Witryny jako JSON / JSONArray w treści żądania.
W ten sposób możesz użyć tego samego adresu URL, aby w razie potrzeby zmodyfikować różne części projektu - kod w implementacji musi być wystarczająco inteligentny, aby poradzić sobie z tą częściową modyfikacją zasobu.
źródło
{"sites": [], "other-stuff": {}}
, możesz następnie rozgałęzić swój kod, aby bardzo łatwo obsługiwać wszystkie te „podwiązki”. To naprawdę zależy od konkretnego problemu, ale nadal polecam użycie PATCH, ponieważ jest on zaprojektowany specjalnie do tego rodzaju rzeczy.PATCH
spodziewałby się również, że pełny byt zostanie tutaj przekazany jako jego wartość, a nie identyfikator wskazujący na jakiś byt?