Wprowadzamy nowy interfejs API REST i chciałem, aby społeczność przekazała informacje o najlepszych praktykach dotyczących sposobu formatowania parametrów wejściowych:
Obecnie nasze API jest bardzo skoncentrowane na JSON (zwraca tylko JSON). Debata na temat tego, czy chcemy / musimy zwrócić XML, to osobna kwestia.
Ponieważ nasze dane wyjściowe API są skoncentrowane na JSON, poszliśmy ścieżką, w której nasze dane wejściowe są nieco skoncentrowane na JSON i pomyślałem, że może to być wygodne dla niektórych, ale ogólnie dziwne.
Na przykład, aby uzyskać kilka szczegółów produktu, w których można pobrać wiele produktów naraz, obecnie mamy:
http://our.api.com/Product?id=["101404","7267261"]
Czy powinniśmy to uprościć:
http://our.api.com/Product?id=101404,7267261
A może przydaje się wejście JSON? Więcej bólu?
Możemy zaakceptować oba style, ale czy ta elastyczność faktycznie powoduje więcej zamieszania i ból głowy (łatwość konserwacji, dokumentacja itp.)?
Bardziej złożony przypadek ma miejsce, gdy chcemy zaoferować bardziej złożone dane wejściowe. Na przykład, jeśli chcemy zezwolić na wiele filtrów podczas wyszukiwania:
http://our.api.com/Search?term=pumas&filters={"productType":["Clothing","Bags"],"color":["Black","Red"]}
Niekoniecznie chcemy umieszczać typy filtrów (np. ProductType i kolor) jako nazwy żądań takie jak to:
http://our.api.com/Search?term=pumas&productType=["Clothing","Bags"]&color=["Black","Red"]
Ponieważ chcieliśmy zgrupować wszystkie filtry wejściowe razem.
Czy to naprawdę ma znaczenie? Może być prawdopodobne, że istnieje tak wiele narzędzi JSON, że typ danych wejściowych po prostu nie ma większego znaczenia.
Wiem, że nasi klienci JavaScript wykonujący wywołania AJAX do API mogą docenić dane wejściowe JSON, aby ułatwić im życie.
[]
składnia nie zawsze jest obsługiwana (i mimo że jest powszechna, może nawet naruszać specyfikację URI). Niektóre serwery HTTP i języki programowania wolą po prostu powtarzać nazwę (npproductType=value1&productType=value2
.)./user/
w organizmie, wyślę{ q:{}, d: {} }
zq
jak zapytaniu z użytkownikiem będzie odpytywany w DB id
jak zmodyfikowanych danych.Standardowym sposobem przekazania listy wartości jako parametrów adresu URL jest ich powtórzenie:
http://our.api.com/Product?id=101404&id=7267261
Większość kodu serwera zinterpretuje to jako listę wartości, chociaż wiele z nich ma uproszczenia dla pojedynczej wartości, więc być może będziesz musiał szukać.
Wartości graniczne również są w porządku.
Jeśli potrzebujesz wysłać JSON na serwer, nie lubię go widzieć w adresie URL (który ma inny format). W szczególności adresy URL mają ograniczenia rozmiaru (w praktyce, jeśli nie teoretycznie).
Sposób, w jaki widziałem, jak RESTfully wykonuje skomplikowane zapytanie, składa się z dwóch etapów:
POST
wymagania dotyczące zapytania, odbieranie identyfikatora (zasadniczo tworzenie zasobu kryteriów wyszukiwania)GET
wyszukiwanie, odwołując się do powyższego identyfikatoraźródło
Pierwszy:
Myślę, że możesz to zrobić na 2 sposoby
http://our.api.com/Product/<id>
: jeśli chcesz tylko jeden rekordhttp://our.api.com/Product
: jeśli chcesz wszystkie rekordyhttp://our.api.com/Product/<id1>,<id2>
: jak zasugerował James, może być opcją, ponieważ to, co następuje po tagu produktu, jest parametremLub najbardziej lubię:
Możesz użyć Hypermedia jako właściwości silnika stanu aplikacji (HATEOAS) RestFul WS i wykonać wywołanie,
http://our.api.com/Product
które powinno zwrócić równoważne adresy URLhttp://our.api.com/Product/<id>
i wywołać je po tym.druga
Gdy musisz wykonać zapytania dotyczące połączeń URL. Sugerowałbym ponowne użycie HATEOAS.
1) Zadzwoń pod numer
http://our.api.com/term/pumas/productType/clothing/color/black
2) Zadzwoń pod numer
http://our.api.com/term/pumas/productType/clothing,bags/color/black,red
3) (Korzystanie z HATEOAS) Zadzwoń do ` http://our.api.com/term/pumas/productType/ -> otrzymaj adresy URL wszystkich możliwych adresów URL odzieży -> zadzwoń do tych, których chcesz (ubrania i torby) - > otrzymaj możliwe kolorowe adresy URL -> zadzwoń do tych, których chcesz
źródło
Może chcesz sprawdzić RFC 6570 . Ta specyfikacja szablonu URI pokazuje wiele przykładów tego, jak adresy URL mogą zawierać parametry.
źródło
Pierwszy przypadek:
Normalne wyszukiwanie produktu wyglądałoby tak
http://our.api.com/product/1
Myślę więc, że najlepszą praktyką byłoby to zrobić
http://our.api.com/Product/101404,7267261
Druga sprawa
Szukaj z parametrami querystring - tak dobrze. Kusiłoby mnie, aby połączyć warunki z AND i OR zamiast używać
[]
.PS Może to być subiektywne, więc rób to, z czym czujesz się komfortowo.
Powodem umieszczenia danych w adresie URL jest to, że link można wkleić na stronie / udostępnić użytkownikom. Jeśli to nie jest problem, należy zamiast tego użyć JSON / POST.
EDYCJA: Po zastanowieniu myślę, że to podejście pasuje do bytu z kluczem złożonym, ale nie do zapytania dla wielu bytów.
źródło
/
nie powinno być końca, ponieważ identyfikator URI dotyczy zasobu, a nie kolekcji.Popieram odpowiedź nategood, ponieważ jest kompletna i wydaje się, że zaspokaja twoje potrzeby. Chciałbym jednak dodać komentarz na temat identyfikacji wielu (1 lub więcej) zasobów w ten sposób:
http://our.api.com/Product/101404,7267261
W ten sposób:
Skomplikuj klientów , zmuszając ich do interpretowania twojej odpowiedzi jako tablicy, co jest dla mnie sprzeczne z intuicją, jeśli złożę następujące żądanie:
http://our.api.com/Product/101404
Twórz nadmiarowe interfejsy API za pomocą jednego interfejsu API, aby uzyskać wszystkie produkty, i jednego powyżej, aby uzyskać 1 lub wiele. Ponieważ nie powinieneś pokazywać użytkownikowi więcej niż 1 strony szczegółów ze względu na UX, uważam, że posiadanie więcej niż 1 identyfikatora byłoby bezużyteczne i służyło wyłącznie do filtrowania produktów.
Może to nie być tak problematyczne, ale albo będziesz musiał poradzić sobie z tym po stronie serwera, zwracając pojedynczy byt (sprawdzając, czy twoja odpowiedź zawiera jedną lub więcej), albo pozwalając klientom nim zarządzać.
Przykład
Chcę zamówić książkę w Amazing . Wiem dokładnie, która to książka i widzę ją na liście podczas nawigacji po horrorach:
Po wybraniu drugiej książki następuje przekierowanie na stronę z opisem części książkowej listy:
A może na stronie z pełnymi szczegółami tej książki?
Moja opinia
Sugerowałbym użycie identyfikatora w zmiennej path, gdy gwarantowana jest unikalność przy pobieraniu szczegółów tego zasobu. Na przykład poniższe interfejsy API sugerują wiele sposobów uzyskania szczegółowych informacji o konkretnym zasobie (zakładając, że produkt ma unikalny identyfikator, a specyfikacja tego produktu ma unikalną nazwę i można nawigować z góry na dół):
Gdy potrzebujesz więcej niż jednego zasobu, sugeruję odfiltrowanie z większej kolekcji. Dla tego samego przykładu:
Oczywiście to jest moja opinia, ponieważ nie jest narzucona.
źródło