Myślę, że możesz użyć metody POST lub PATCH, aby sobie z tym poradzić, ponieważ zazwyczaj projektują do tego.
Użycie POST
metody jest zwykle używane do dodawania elementu, gdy jest używane w zasobie listy, ale można również obsługiwać kilka akcji dla tej metody. Zobacz tę odpowiedź: Jak zaktualizować zbiór zasobów REST . Możesz także obsługiwać różne formaty reprezentacji danych wejściowych (jeśli odpowiadają one tablicy lub pojedynczym elementom).
W takim przypadku nie jest konieczne definiowanie formatu, aby opisać aktualizację.
Użycie PATCH
metody jest również odpowiednie, ponieważ odpowiednie żądania odpowiadają częściowej aktualizacji. Według RFC5789 ( http://tools.ietf.org/html/rfc5789 ):
Kilka aplikacji rozszerzających protokół Hypertext Transfer Protocol (HTTP) wymaga funkcji częściowej modyfikacji zasobów. Istniejąca metoda HTTP PUT umożliwia tylko całkowitą wymianę dokumentu. Ta propozycja dodaje nową metodę HTTP, PATCH, w celu zmodyfikowania istniejącego zasobu HTTP.
W takim przypadku musisz zdefiniować swój format, aby opisać częściową aktualizację.
Myślę, że w tym przypadku POST
i PATCH
są dość podobne, ponieważ tak naprawdę nie musisz opisywać operacji do wykonania dla każdego elementu. Powiedziałbym, że zależy to od formatu przesłanego oświadczenia.
Sprawa PUT
jest nieco mniej jasna. W rzeczywistości, używając metody PUT
, powinieneś podać całą listę. W rzeczywistości reprezentacja przedstawiona w żądaniu będzie zastępować reprezentację zasobu listy.
Możesz mieć dwie opcje dotyczące ścieżek zasobów.
- Korzystanie ze ścieżki zasobów dla listy dokumentów
W takim przypadku musisz wyraźnie podać link do dokumentów z segregatorem w reprezentacji podanej w żądaniu.
Oto przykładowa trasa do tego /docs
.
Treść takiego podejścia może dotyczyć metody POST
:
[
{ "doc_number": 1, "binder": 4, (other fields in the case of creation) },
{ "doc_number": 2, "binder": 4, (other fields in the case of creation) },
{ "doc_number": 3, "binder": 5, (other fields in the case of creation) },
(...)
]
- Używanie ścieżki zasobu podrzędnego elementu binder
Ponadto można również rozważyć wykorzystanie tras podrzędnych do opisu powiązania między dokumentami a segregatorami. Wskazówki dotyczące powiązania między dokumentem a segregatorem nie muszą być teraz określane w treści żądania.
Oto przykładowa trasa do tego /binder/{binderId}/docs
. W takim przypadku wysyłanie listy dokumentów metodą POST
lub PATCH
dołączanie dokumentów do segregatora z identyfikatorem binderId
po utworzeniu dokumentu, jeśli nie istnieje.
Treść takiego podejścia może dotyczyć metody POST
:
[
{ "doc_number": 1, (other fields in the case of creation) },
{ "doc_number": 2, (other fields in the case of creation) },
{ "doc_number": 3, (other fields in the case of creation) },
(...)
]
Jeśli chodzi o odpowiedź, to do Ciebie należy określenie poziomu odpowiedzi i błędów do zwrócenia. Widzę dwa poziomy: poziom statusu (poziom globalny) i poziom ładunku (poziom cieńszy). Do Ciebie należy również określenie, czy wszystkie wstawki / aktualizacje odpowiadające Twojemu żądaniu muszą być atomowe, czy nie.
W takim przypadku możesz wykorzystać stan HTTP. Jeśli wszystko pójdzie dobrze, otrzymasz status 200
. Jeśli nie, inny status, na przykład 400
jeśli podane dane nie są poprawne (na przykład identyfikator segregatora jest nieprawidłowy) lub coś innego.
W takim przypadku 200
zostanie zwrócony status i do reprezentacji odpowiedzi należy opisanie, co zostało zrobione i gdzie ostatecznie wystąpiły błędy. ElasticSearch ma punkt końcowy w swoim interfejsie API REST do zbiorczej aktualizacji. To może dać ci kilka pomysłów na tym poziomie: http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/bulk.html .
Możesz również zaimplementować przetwarzanie asynchroniczne w celu obsługi dostarczonych danych. W takim przypadku zwracany stan HTTP będzie 202
. Klient musi pobrać dodatkowe zasoby, aby zobaczyć, co się stanie.
Zanim skończę, chciałbym również zauważyć, że specyfikacja OData rozwiązuje problem dotyczący relacji między jednostkami z funkcją o nazwie linki nawigacyjne . Może mógłbyś rzucić okiem na to ;-)
Poniższy link może Ci również pomóc: https://templth.wordpress.com/2014/12/15/designing-a-web-api/ .
Mam nadzieję, że ci to pomoże, Thierry
GET /docs
i pobrać wszystkie dokumenty w szczególności spoiwaGET /docs?binder_id=x
. Aby usunąć podzbiór zasobów,DELETE /docs?binder_id=x
czy powinienem wywołać, czy powinienem wywołaćDELETE /docs
z{"binder_id": x}
w treści żądania? Czy kiedykolwiekPATCH /docs?binder_id=x
używałbyś aktualizacji zbiorczej, czy po prostuPATCH /docs
i przepuszczał pary?Prawdopodobnie będziesz musiał użyć POST lub PATCH, ponieważ jest mało prawdopodobne, aby pojedyncze żądanie, które aktualizuje i tworzy wiele zasobów, będzie idempotentne.
Robienie
PATCH /docs
to zdecydowanie ważna opcja. Używanie standardowych formatów poprawek może okazać się trudne w twoim konkretnym scenariuszu. Nie jestem tego pewien.Możesz użyć 200. Możesz również użyć 207 - Multi Status
Można to zrobić w RESTful sposób. Moim zdaniem kluczem jest posiadanie zasobu przeznaczonego do akceptowania zestawu dokumentów do aktualizacji / utworzenia.
Jeśli używasz metody PATCH, myślę, że twoja operacja powinna być atomowa. tj. nie użyłbym kodu stanu 207, a następnie nie zgłosiłbym sukcesów i niepowodzeń w treści odpowiedzi. Jeśli używasz operacji POST, podejście 207 jest wykonalne. Będziesz musiał zaprojektować własne ciało odpowiedzi, aby komunikować, które operacje zakończyły się sukcesem, a które nie. Nie znam standardowego.
źródło
This can be done in a RESTful way
to znaczy Update i tworzyć muszą być wykonane oddzielnie?PUT ing
PUT /binders/{id}/docs
Utwórz lub zaktualizuj i powiąż pojedynczy dokument z segregatoremna przykład:
PATCH ing
PATCH /docs
Utwórz dokumenty, jeśli ich nie ma, i powiąż je z segregatoramina przykład:
Dodatkowe spostrzeżenia dołączę później, ale w międzyczasie, jeśli chcesz, spójrz na RFC 5789 , RFC 6902 i William Durand's Please. Wpis na blogu Don't Patch Like a Idiot .
źródło
docs
i skojarzyć z nimibinders
. Klient chce utworzyć segregatory, jeśli nie istnieją, i utworzyć skojarzenie, jeśli tak. W JEDNYM POJEDYNCZYM ZAMÓWIENIU.W projekcie, nad którym pracowałem, rozwiązaliśmy ten problem, wprowadzając coś, co nazywamy żądaniami „wsadowymi”. Zdefiniowaliśmy ścieżkę, w
/batch
której przyjęliśmy json w następującym formacie:Odpowiedź ma kod stanu 207 (Multi-Status) i wygląda następująco:
Możesz również dodać obsługę nagłówków w tej strukturze. Zaimplementowaliśmy coś, co okazało się przydatne, czyli zmienne do wykorzystania między żądaniami w partii, co oznacza, że możemy użyć odpowiedzi z jednego żądania jako danych wejściowych do innego.
Facebook i Google mają podobne implementacje:
https://developers.google.com/gmail/api/guides/batch
https://developers.facebook.com/docs/graph-api/making-multiple-requests
Jeśli chcesz utworzyć lub zaktualizować zasób za pomocą tego samego wywołania, użyłbym POST lub PUT w zależności od przypadku. Jeśli dokument już istnieje, czy chcesz, aby cały dokument był:
Jeśli chcesz zachowanie z alternatywy 1, powinieneś użyć POST, a jeśli chcesz zachowanie z alternatywy 2, powinieneś użyć PUT.
http://restcookbook.com/HTTP%20Methods/put-vs-post/
Jak już sugerowali ludzie, możesz również wybrać PATCH, ale wolę zachować proste API i nie używać dodatkowych czasowników, jeśli nie są potrzebne.
źródło
--batch_xxxx
. Czy są jakieś istotne różnice między rozwiązaniami Google i Facebooka? Dodatkowo, jeśli chodzi o „wykorzystanie odpowiedzi z jednego żądania jako danych wejściowych do innego”, brzmi to bardzo interesująco, czy mógłbyś podzielić się więcej szczegółami? lub jakiego rodzaju scenariusza należy użyć?