„Najlepsza” praktyka zapewniająca spokojną odpowiedź POST


217

Więc nic nowego tutaj Po prostu próbuję uzyskać wyjaśnienie i nie mogę znaleźć żadnych innych postów.

Ponownie tworzę nowy zasób, powiedz:

/books (POST)

z ciałem:

{
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

Wiem, że powinienem zwrócić 201 (utworzony) z nagłówkiem lokalizacji nowego zasobu:

Location: /books/12345

Pytanie, na które nie potrafię odpowiedzieć, brzmi: co serwer powinien powrócić w ciele?

Często robiłem tego typu odpowiedzi:

{
  id: 12345,
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

Zrobiłem to z kilku powodów:

  1. Napisałem API dla frameworków takich jak angularjs. W moim szczególnym przypadku używam zasobów kątowych i często potrzebuję tylko identyfikatora zasobu, aby go zlokalizować. Gdybym nie zwrócił identyfikatora w treści odpowiedzi, musiałbym parsować go poza nagłówkiem Location.
  2. W GET ze wszystkich książek zwykle zwracam cały obiekt, a nie tylko identyfikator. W tym sensie mój kod klienta nie musi rozróżniać, skąd uzyskać identyfikator (nagłówek lub treść).

Teraz wiem, że tak naprawdę jestem tutaj w szarej strefie, ale większość ludzi twierdzi, że zwrócenie całego zasobu jest „złą” praktyką. Ale co, jeśli serwer zmieni / doda informacje do zasobu. Z pewnością dodaje identyfikator, ale może również dodawać inne rzeczy, takie jak znacznik czasu. W przypadku, gdy nie zwracam całego zasobu, czy naprawdę lepiej jest wykonać test POST, zwróć identyfikator, a następnie poproś klienta o wykonanie operacji GET, aby uzyskać nowy zasób.


Osobiście wolę puste ciało dla odpowiedzi POST. Czy wartość nagłówka RESTful Location nie powinna być identyfikatorem URI (unikalny identyfikator zasobu)? Może więc powinieneś użyć go jako identyfikatora, a nie parsować go w celu wykrycia wewnętrznego identyfikatora serwera. IMO, klienci RESTful API powinni nawigować za pomocą dostarczonych hiperłączy, a nie budować ścieżki, zgadując, gdzie konkretny serwer lokalizuje zasoby ... A w końcu, czy klient nie zna stanu utworzonego właśnie zasobu? powtarzanie go powoduje marnotrawstwo zasobów sieciowych.
ch4mp

1
Dla Utwórz / Wstaw, Status 201 - UTWORZONY, Lokalizacja nagłówka → localhost: 8080 / pracowników / 1 (Patrz: tutaj )
Hassan Tareq

Odpowiedzi:


129

Zwracanie całego obiektu w ramach aktualizacji nie wydaje się zbyt istotne, ale trudno mi zrozumieć, dlaczego zwracanie całego obiektu podczas jego tworzenia byłoby złym postępowaniem w normalnym przypadku użycia. Przydałoby się to przynajmniej w celu łatwego uzyskania identyfikatora i uzyskania znaczników czasu, gdy jest to istotne. Jest to w rzeczywistości domyślne zachowanie stosowane podczas rusztowania za pomocą Rails.

Naprawdę nie widzę żadnej korzyści ze zwracania tylko identyfikatora i wykonywania żądania GET później, aby uzyskać dane, które można uzyskać za pomocą pierwszego testu POST.

W każdym razie, dopóki interfejs API jest spójny, uważam, że powinieneś wybrać wzór, który najlepiej odpowiada Twoim potrzebom. Nie ma właściwego sposobu na zbudowanie interfejsu API REST, imo.


26
Wiem, że to jest stare, ale mogę podać przekonujący argument za użyciem GET po twoim POST. W specyfikacji http / 1.1 każde narzędzie historyczne może zignorować ustawienia pamięci podręcznej przekazane z odpowiedzi GET ... więc jeśli użytkownik użyje przycisku Wstecz w przeglądarce, aby powrócić do tej strony po zaktualizowaniu go za pomocą testu POST, może użyć nieaktualnego buforowane dane z oryginalnego GET. Jeśli więc ponownie użyjesz GET, możesz zaktualizować pamięć podręczną i uzyskać lepszą migawkę tego, jak wyglądała strona, gdy ją opuścili ...
Cieniowane

8
@Shaded Jeśli interfejs API jest przeznaczony również do użytku przez aplikacje, to twój argument za wysłaniem dwóch żądań nie ma zastosowania. Tam zwykle buforujesz dane, przechowując obiekty typu modelu w pamięci - co zwykle odbywa się w odpowiedzi na żądania POST. Jeśli chodzi o przeglądarki, odpowiedź na żądanie POST tak naprawdę nie boli, dopóki istnieje punkt końcowy GET API.
Jeehut,

Zgadzam się z tym, co mówi Daniel. Nawet jeśli sprawdzisz dojrzałe frameworki, takie jak Spring Data, zawsze zwracają cały obiekt po utrwaleniu go. Myślę, że to dobra praktyka, ponieważ w twoim kliencie zaoszczędzisz
podróż

205

Zwrócenie nowego obiektu jest zgodne z zasadą REST „Jednolity interfejs - manipulowanie zasobami poprzez reprezentacje”. Kompletny obiekt jest reprezentacją nowego stanu utworzonego obiektu.

Jest naprawdę doskonała referencja do projektowania API, tutaj: Najlepsze praktyki projektowania Pragmatic RESTful API

Zawiera odpowiedź na twoje pytanie tutaj: Aktualizacje i tworzenie powinny zwrócić reprezentację zasobów

To mówi:

Aby zapobiec sytuacji, w której konsument interfejsu API musiałby ponownie uderzyć w interfejs API w celu zaktualizowania reprezentacji, API powinien zwrócić zaktualizowaną (lub utworzoną) reprezentację jako część odpowiedzi.

Wydaje mi się to bardzo pragmatyczne i pasuje do wspomnianej powyżej zasady REST.


6
co powiesz na zwrócenie całego zestawu odpowiednich obiektów? w ten sposób możliwe sortowanie może odbywać się po stronie serwera, co ułatwia implementację
interfejsu użytkownika

2
Ale te najlepsze praktyki nie są najlepsze. Autor statet, że HATEOAS, co jest ważne tak samo jak inne zasady, nie może być stosowany, ponieważ „nie jest gotowy”. HATEOAS nigdy nie będzie „gotowy”, ponieważ wszystkie zasady RESTful są tylko zasadami projektowania architektonicznego, a nie konkretnym wdrożeniem. Cytowane odniesienie dotyczy wizji autora dotyczącej RESTful API, która wcale nie jest RESTful z powodu porzucenia HATEOAS. Dlatego nie jest to najlepsza referencja :)
Marcin

1
@marcinn - zauważysz, że pierwotne pytanie zawierało cytaty dotyczące „Najlepszego”, jak sądzę, ponieważ w tej dziedzinie jest wiele opinii. Odwołanie, na które wskazałem, jest praktyczne. Jeśli masz lepsze referencje, udostępnij je. Zawsze jestem otwarty na naukę.
grahamesd

@grahamesd Wdrożenie to inna rzecz, niż projekt / wzór architektoniczny. Nikt nie może oczekiwać, że HATEOAS będzie kiedyś gotowy, ale istnieje szansa, że ​​ktoś stworzy implementację akceptowalną przez wielu. Vinay również napisał o mapowaniu metod http na adresy URL i określone operacje (CRUD), stwierdził, że wersjonowanie przez prefiksowanie adresów URL jest bardziej pragmatyczne, napisał, że filtrowanie według parametrów zapytań jest dobrym rozwiązaniem ... jest w porządku, ale to wszystko ma niewiele do zrobić z architekturą RESTful. Pisał o jakimś kontrakcie. To jest w porządku dla API HTTP, ale nie nazywaj go RESTful.
marcinn

@grahamesd Oto kilka postów wyjaśniających to: - medium.com/@andrea.chiarelli/… - restfulapi.net
marcinn
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.