Na przykład mam podmioty: klient, raport. Klient może mieć wiele raportów i myślę, że punkt końcowy dla jednego zarządzania raportami powinien być zagnieżdżony w następujący sposób:
/clients/{client_id}/reports/{report_id}
Jeśli chodzi o wszystkie raporty jednego klienta, oczekuje się enpoint:
/clients/{client_id}/reports
Ale jak powinien wyglądać punkt końcowy dla uzyskania wszystkich raportów wszystkich klientów, aby interfejs API był spójny i dobrze zaprojektowany.
Moje podejście:
- (Widziałem to w niektórych aplikacjach Google) użyj „-” zamiast tego i parsuj jako „wszystkie”:
/clients/-/reports
Utrzymuje to ten sam format punktu końcowego, ale wygląda nieco nietypowo, nie można znaleźć żadnego kodu RFC, który sugerowałby w ten sposób.
- Utwórz osobny punkt końcowy tylko dla wszystkich raportów:
/reports
Ale aby uzyskać raporty klienta, nadal:
/clients/{client_id}/reports
- Refaktoryzuj punkty końcowe, aby „klient” nie był rodzicem, ale tylko parametrem filtru:
/reports?client={client_id}
- raporty jednego klienta
/reports
- raporty wszystkich klientów
W przypadku dodania nowego punktu końcowego do publikowania raportu dla konkretnego klienta, może to wyglądać brzydko, ponieważ będzie to żądanie POST z parametrem w adresie URL.
Czy są jakieś inne sugestie pomysłów?
źródło
Odpowiedzi:
Przede wszystkim pamiętaj, że nie ma złotych reguł modelowania interfejsów API RESTful. Wszystko, co mamy, to najlepsze praktyki i konwencje. Biorąc to pod uwagę, prawdopodobną odpowiedzią jest - jak zwykle - wybierz ten, który najlepiej spełnia twoje wymagania, aw tym przypadku ten, który najlepiej wyraża Twój model.
Więc sprawdź trzy opcje z wyrazistości.
# 1 Notacja „-”
To świetny pomysł. Pozwala nam wyrazić warunek, do
reports
którego należą wszyscyclients
. Zawęża „zapytanie” do określonego zestawu raportów (tych znajdujących się wclients
granicach).Utrzymuje pojęcie hierarchii (przynależności) przez cały czas, więc jeśli
reports
można je znaleźć w różnych lokalizacjach, notacja ta ma duże znaczenie. Na przykład:/clients/-/reports
/departments/-/reports
/employees/-/reports
Jednak w przypadku pobierania wszystkich dostępnych raportów w systemie zachowanie hierarchii nie zapewnia żadnej cennej przewagi nad następną opcją.
# 2 Różne identyfikatory URI
Jeśli nie musimy wyrażać granic / kontekstów / hierarchii w momencie wyszukiwania wszystkich dostępnych raportów , takie podejście wydaje mi się bardziej rozsądne.
Nowy identyfikator URI (
/reports
) pozostawia również otwartą możliwość zarządzania raportami . Nie musimy jednak zapewniać pełnego wsparcia RESTful, jeśli nie uznamy tego za konieczne. Na przykład, oświadczyłeśMake a separate endpoint just for all the reports
. W porządku, musisz tylko zaimplementowaćGET
i być może niektóre filtry do wysyłania zapytań i to wszystko.Pamiętaj, że nadal możesz to zrobić
/reports?client={client_id}
. Posiadanie innego identyfikatora URI dla tego samego zasobu jest w porządku. Niektóre artykuły, które przeczytałem, nazwaliby tę solidnością .# 3 Cofnięcie hierarchii
Mam wrażenie, że to podejście nie spełnia twoich oczekiwań. Plus, myślę, że doprowadzi cię to ostatecznie do punktu początkowego.
Wnioski
Pamiętaj, że nr 1 i nr 2 nie wykluczają się wzajemnie. Możemy wdrożyć oba. Biorąc pod uwagę faktyczną sytuację i zgodnie z przesłankami PO, wdrożyłbym tylko nr 2.
1: jest to równoważne
/clients/-/reports
Chybaźródło
Wzorce projektowe API Google sugerują użycie „-” w tym scenariuszu.
Źródło:
https://cloud.google.com/apis/design/design_patterns#list_sub-collections
źródło
/client/{client_id}/report/{report_id}
i/clients/report/{report_id}
/reports
?/clients...
i/reports
.