Powiedzmy, że chcę mieć zasób RESTful dla ludzi, w którym klient może przypisać identyfikator.
Osoba wygląda tak: {"id": <UUID>, "name": "Jimmy"}
W jaki sposób klient powinien go zapisać (lub „PUT”)?
PUT /person/UUID {"id": <UUID>, "name": "Jimmy"}
- teraz mamy tę paskudną duplikację, którą musimy cały czas weryfikować: Czy identyfikator w treści jest zgodny z tym na ścieżce?- Asymetryczna reprezentacja:
PUT /person/UUID {"name": "Jimmy"}
GET /person/UUID
zwroty{"id": <UUID>, "name": "Jimmy"}
- Brak identyfikatorów w treści - identyfikator tylko w lokalizacji:
PUT /person/UUID {"name": "Jimmy"}
GET /person/UUID
zwroty{"name": "Jimmy"}
- Nie
POST
wydaje się to dobrym pomysłem, ponieważ identyfikator jest generowany przez klienta.
Jakie są typowe wzorce i sposoby rozwiązania tego problemu? Identyfikatory tylko w lokalizacji wydają się najbardziej dogmatycznie poprawnym sposobem, ale utrudniają też praktyczną implementację.
id
razem z TO z identyfikatorem i jednostką oraz dodatkowymi konwerterami i zbyt dużym narzutem dla programistów.Jeśli jest to publiczny interfejs API, odpowiadaj ostrożnie, ale zgadzaj się swobodnie.
Rozumiem przez to, że powinieneś wspierać zarówno 1, jak i 2. Zgadzam się, że 3 nie ma sensu.
Sposobem na obsługę zarówno 1, jak i 2 jest pobranie identyfikatora z adresu URL, jeśli żaden nie jest podany w treści żądania, a jeśli znajduje się w treści żądania, sprawdź, czy pasuje do identyfikatora w adresie URL. Jeśli te dwa elementy nie są zgodne, zwróć odpowiedź 400 złych żądań.
Zwracając zasób osoby, zachowaj ostrożność i zawsze dołączaj identyfikator w pliku json, nawet jeśli jest on opcjonalny.
źródło
Jednym z rozwiązań tego problemu jest nieco myląca koncepcja „hipertekstu jako silnika stanu aplikacji” lub „HATEOAS”. Oznacza to, że odpowiedź REST zawiera dostępne zasoby lub akcje do wykonania jako hiperłącza. Korzystając z tej metody, która była częścią pierwotnej koncepcji REST, unikalne identyfikatory / identyfikatory zasobów same są hiperłączami. Na przykład możesz mieć coś takiego:
Następnie, jeśli chcesz zaktualizować ten zasób, możesz zrobić (pseudokod):
Zaletą tego jest to, że klient nie musi mieć pojęcia o wewnętrznej reprezentacji identyfikatorów użytkowników na serwerze. Identyfikatory mogą się zmieniać, a nawet same adresy URL mogą się zmieniać, o ile klient ma sposób je odkryć. Na przykład podczas pobierania kolekcji osób możesz zwrócić odpowiedź w następujący sposób:
(Oczywiście możesz również zwrócić pełny przedmiot osobisty dla każdej osoby, w zależności od potrzeb aplikacji).
Dzięki tej metodzie myślisz o swoich obiektach bardziej w kategoriach zasobów i lokalizacji, a mniej w kategoriach ID. W ten sposób wewnętrzna reprezentacja unikalnego identyfikatora jest oddzielona od logiki klienta. To był pierwotny bodziec dla REST: stworzenie architektur klient-serwer, które są luźniej powiązane niż systemy RPC, które istniały wcześniej, przy użyciu funkcji HTTP. Więcej informacji na temat HATEOAS można znaleźć w artykule w Wikipedii oraz w tym krótkim artykule .
źródło
We wstawce nie musisz dodawać identyfikatora w adresie URL. W ten sposób, jeśli wyślesz ID w PUT, możesz zinterpretować jako UPDATE do zmiany klucza podstawowego.
WSTAWIĆ:
AKTUALIZACJA
Interfejs JSON API korzysta z tego standardu i rozwiązuje niektóre problemy ze zwracaniem wstawionego lub zaktualizowanego obiektu z łączem do nowego obiektu. Niektóre aktualizacje lub wstawki mogą zawierać logikę biznesową, która zmieni dodatkowe pola
Zobaczysz również, że możesz uniknąć pobierania po wstawce i aktualizacji.
źródło
Zadawano to już wcześniej - dyskusję warto zajrzeć:
Czy odpowiedź GET typu RESTful powinna zwracać identyfikator zasobu?
To jedno z tych pytań, w których łatwo ugrzęznąć w debacie na temat tego, co jest, a co nie jest „RESTful” .
Na ile to jest warte, staram się myśleć w kategoriach spójnych zasobów i nie zmieniać ich projektu między metodami. Jednak dla IMHO najważniejszą rzeczą z punktu widzenia użyteczności jest spójność w całym API!
źródło
Chociaż dobrze jest mieć różne reprezentacje dla różnych operacji, ogólną rekomendacją dla PUT jest przechowywanie CAŁEGO ładunku . To znaczy, że
id
powinno tam być. W przeciwnym razie powinieneś użyć PATCH.Powiedziawszy to, myślę, że PUT powinien być używany głównie do aktualizacji i
id
zawsze powinien być również przekazywany w adresie URL. W rezultacie używanie PUT do aktualizacji identyfikatora zasobu jest złym pomysłem. Pozostawia nas w niepożądanej sytuacji, gdyid
adres URL może różnić się odid
w treści.Jak więc rozwiązać taki konflikt? Zasadniczo mamy 2 opcje:
Warning
(X-API-Warn
etc).To tak blisko, jak tylko mogę odpowiedzieć na to pytanie, ponieważ ogólnie temat jest kwestią opinii.
źródło
FYI, odpowiedzi tutaj są błędne.
Widzieć:
https://restfulapi.net/rest-api-design-tutorial-with-example/
https://restfulapi.net/rest-put-vs-post/
https://restfulapi.net/http-methods/#patch
POŁOŻYĆ
ŁATA
Więc powinieneś go używać w ten sposób:
Praktyki RESTful wskazują, że nie powinno mieć znaczenia, co umieścisz w / {id} - zawartość rekordu powinna zostać zaktualizowana do tej dostarczonej przez ładunek - ale GET / {id} powinien nadal prowadzić do tego samego zasobu.
Innymi słowy, PUT / 3 może aktualizować się do identyfikatora ładunku 4, ale GET / 3 powinien nadal łączyć się z tym samym ładunkiem (i zwracać ten z identyfikatorem ustawionym na 4).
Jeśli zdecydujesz, że twoje API wymaga tego samego identyfikatora w URI i ładunku, Twoim zadaniem jest upewnić się, że pasuje, ale zdecydowanie użyj PATCH zamiast PUT, jeśli wykluczasz identyfikator w ładunku, który powinien tam być w całości . W tym miejscu zaakceptowana odpowiedź jest błędna. PUT musi zastąpić cały zasób, gdzie poprawka-as może być częściowa.
źródło
Nie ma nic złego w stosowaniu różnych podejść. ale myślę, że najlepszym sposobem jest rozwiązanie z 2nd .
jest najczęściej używany w ten sposób, nawet struktura jednostek korzysta z tej techniki, gdy jednostka jest dodawana w dbContext klasa bez wygenerowanego identyfikatora jest identyfikatorem wygenerowanym przez odwołanie w Entity Framework.
źródło
Patrzę na to z punktu widzenia JSON-LD / Semantic Web, ponieważ jest to dobry sposób na osiągnięcie prawdziwej zgodności REST, jak to opisałem na tych slajdach . Patrząc na to z tej perspektywy, nie ma wątpliwości, aby przejść do opcji (1.), ponieważ identyfikator (IRI) zasobu sieciowego powinien zawsze być równy adresowi URL, którego mogę użyć do wyszukania / wyłuskiwania zasobu. Myślę, że weryfikacja nie jest naprawdę trudna do wdrożenia ani nie jest intensywna obliczeniowo; więc nie uważam tego za ważny powód, aby wybrać opcję (2.). Myślę, że opcja (3.) tak naprawdę nie jest opcją, ponieważ POST (utwórz nowy) ma inną semantykę niż PUT (aktualizacja / zastąpienie).
źródło
Może zajść potrzeba przyjrzenia się typom żądań PATCH / PUT.
Żądania PATCH są używane do częściowej aktualizacji zasobu, podczas gdy w żądaniach PUT musisz wysłać cały zasób, który zostanie nadpisany na serwerze.
Jeśli chodzi o posiadanie identyfikatora w adresie URL, myślę, że zawsze powinieneś go mieć, ponieważ identyfikacja zasobu jest standardową praktyką. Nawet API Stripe działa w ten sposób.
Możesz użyć żądania PATCH, aby zaktualizować zasób na serwerze o identyfikatorze, aby go zidentyfikować, ale nie aktualizuj rzeczywistego identyfikatora.
źródło