Interfejs API REST może mieć parametry na co najmniej dwa sposoby:
- Jako część ścieżki URL (tj.
/api/resource/parametervalue
) - Jako argument zapytania (tj.
/api/resource?parameter=value
)
Jaka jest tutaj najlepsza praktyka? Czy istnieją jakieś ogólne wytyczne, kiedy stosować 1, a kiedy 2?
Przykład ze świata rzeczywistego: Twitter używa parametrów zapytania do określania przedziałów. (http://api.twitter.com/1/statuses/home_timeline.json?since_id=12345&max_id=54321
)
Czy uznanie za lepsze zaprojektowanie umieszczenia tych parametrów w ścieżce adresu URL byłoby lepsze?
Późna odpowiedź, ale dodam trochę więcej wglądu do tego, co zostało udostępnione, a mianowicie, że istnieje kilka rodzajów „parametrów” w żądaniu i należy to wziąć pod uwagę.
Teraz spójrzmy na różne miejsca, w których mogą iść te parametry.
Zasadniczo chcesz, aby stan był ustawiony w nagłówkach lub plikach cookie, w zależności od rodzaju informacji o stanie. Myślę, że wszyscy możemy się z tym zgodzić. W razie potrzeby użyj niestandardowych nagłówków http (X-My-Header).
Podobnie, Treść ma tylko jedno miejsce, do którego należy przynależność, która znajduje się w treści żądania, jako ciągi zapytania lub jako wieloczęściowy http i / lub treść JSON. Jest to zgodne z tym, co otrzymujesz z serwera, gdy wysyła ci treść. Więc nie powinieneś być niegrzeczny i rób to inaczej.
Lokalizatory takie jak „id = 5” lub „action = refresh” lub „page = 2” powinny mieć postać ścieżki URL, na przykład, gdy
mysite.com/article/5/page=2
częściowo wiesz, co każda część powinna oznaczać (podstawy, takie jak artykuł i 5 oczywiście oznacza, że podasz mi dane typu artykuł o id 5), a dodatkowe parametry są określone jako część identyfikatora URI. Mogą mieć postaćpage=2
lubpage/2
jeśli wiesz, że po pewnym punkcie identyfikatora URI „foldery” są sparowanymi klucz-wartościami.Filtry zawsze trafiają do ciągu zapytania, ponieważ chociaż są one częścią wyszukiwania właściwych danych, służą tylko do zwrócenia podzbioru lub modyfikacji tego, co zwracają Lokalizatory samodzielnie. Wyszukiwanie w
mysite.com/article/?query=Obama
(podzestawie) jest filtrem i tak samo jest/article/5?order=backwards
(modyfikacja). Pomyśl o tym, co robi, a nie tylko jak się nazywa!Jeśli „widok” określa format wyjściowy, to jest to filter (
mysite.com/article/5?view=pdf
), ponieważ zwraca modyfikację znalezionego zasobu, a nie bazuje na tym, którego zasobu chcemy. Jeśli zamiast tego zdecyduje, którą konkretną część artykułu zobaczymy (mysite.com/article/5/view=summary
), to jest to lokalizator.Pamiętaj, zawężenie zestawu zasobów jest filtrowaniem. Lokalizowanie czegoś konkretnego w zasobie to lokalizowanie ... duh. Filtrowanie podzbiorów może zwracać dowolną liczbę wyników (nawet 0). Lokalizowanie zawsze znajdzie określone wystąpienie czegoś (jeśli istnieje). Filtrowanie modyfikacji zwróci te same dane co lokalizator, z wyjątkiem zmodyfikowanych (jeśli taka modyfikacja jest dozwolona).
Mam nadzieję, że to pomogło dać ludziom chwile eureki, jeśli zgubili się, gdzie umieścić rzeczy!
źródło
id
ma filtra? Zwraca podzbiór zasobu(page-1)*perpage
i pokażperpage
elementy”. Używanie go jako filtra jest poprawne, ale z różnych powodów. Nazywanie go „stroną” jest technicznie nieprawidłowe. Bardziej poprawne semantycznie byłoby nazwać to „od” lub „startAt”perpage
na 50 zamiast na 20.To zależy od projektu. Nie ma reguł dla identyfikatorów URI w REST przez HTTP (najważniejsze jest to, że są unikalne). Często chodzi o gust i intuicję ...
Przyjmuję następujące podejście:
źródło
IMO parametry powinny być lepsze jako argumenty zapytania. Adres URL służy do identyfikowania zasobu, a dodane parametry zapytania określają, którą część zasobu chcesz, dowolny stan, który powinien mieć zasób itp.
źródło
http://labs.apache.org/webarch/uri/rfc/rfc3986.html#query
Zgodnie z implementacją REST
1) Zmienne ścieżki służą do bezpośredniego działania na zasoby, takie jak kontakt lub utwór, np.
GET etc / api / resource / {songid} lub
GET etc / api / resource / { zwróci odpowiednie dane.
2) Zapytania perms / argument są używane dla zasobów bezpośrednich, takich jak metadane utworu, np. GET / api / resource / {songid}? Metadata = gatunki, zwróci dane gatunku dla tego konkretnego utworu.
źródło
„Spakuj” i POST swoje dane w kontekście „kontekstu”, który zapewnia lokalizator zasobów wszechświata, co oznacza numer 1 dla samego lokalizatora.
Zwróć uwagę na ograniczenia z # 2. Wolę testy POST niż nr 1.
Uwaga: ograniczenia są omówione dla
POST w Czy istnieje maksymalny rozmiar zawartości parametru POST?
GET w Czy istnieje limit długości żądania GET? i Maksymalny rozmiar parametrów URL w _GET
ps limity te są oparte na możliwościach klienta (przeglądarka) i serwera (konfiguracja).
źródło
Zgodnie ze standardem URI ścieżka dotyczy parametrów hierarchicznych, a zapytanie dotyczy parametrów niehierarchicznych. Ofc. może być bardzo subiektywne, co jest dla ciebie hierarchiczne.
W sytuacjach, w których do tego samego zasobu przypisanych jest wiele identyfikatorów URI, lubię umieszczać parametry - niezbędne do identyfikacji - na ścieżce, a parametry - niezbędne do zbudowania reprezentacji - w zapytaniu. (Dla mnie w ten sposób łatwiej jest wyznaczyć trasę.)
Na przykład:
/users/123
i/users/123?fields="name, age"
/users
i/users?name="John"&age=30
Do zmniejszania mapy lubię stosować następujące podejścia:
/users?name="John"&age=30
/users/name:John/age:30
Tak naprawdę to od Ciebie (i routera po stronie serwera) zależy, jak zbudujesz URI.
Uwaga: aby wspomnieć, te parametry są parametrami zapytania. Tak więc to, co naprawdę robisz, to zdefiniowanie prostego języka zapytań. Poprzez złożone zapytania (które zawierają operatory takie jak i, lub większe niż itp.) Sugeruję, abyś używał już istniejącego języka zapytań. Możliwości szablonów URI są bardzo ograniczone ...
źródło
Jako programista często po stronie klienta wolę argument zapytania. Również dla mnie oddziela ścieżkę URL od parametrów, dodaje przejrzystości i oferuje większą rozszerzalność. Pozwala mi to również na oddzielną logikę między budowaniem adresu URL / URI a konstruktorem parametrów.
Podoba mi się to, co powiedział Manuel Aldana na temat drugiej opcji, jeśli w grę wchodzi jakieś drzewo. Widzę, że części specyficzne dla użytkownika są usuwane w ten sposób.
źródło
Nie ma twardych i szybkich reguł, ale ogólną zasadę z czysto koncepcyjnego punktu widzenia, którą lubię stosować, można krótko podsumować w następujący sposób: ścieżka URI (z definicji) reprezentuje zasób, a parametry zapytania są zasadniczo modyfikatorami tego zasobu . Tak daleko, że prawdopodobnie nie pomoże ... Z REST API masz główne metody działając na podstawie pojedynczego zasobu użyciu
GET
,PUT
orazDELETE
. Dlatego to, czy coś powinno być reprezentowane na ścieżce, czy jako parametr, można sprowadzić do tego, czy metody te mają sens dla danej reprezentacji. Czy byłbyś rozsądniePUT
na tej ścieżce i czy byłoby to semantycznie rozsądne? Mógłbyś oczywiściePUT
coś dosłownie wszędzie i wygiąć zaplecze, aby sobie z tym poradzić, ale tak powinno byćPUT
co stanowi reprezentację rzeczywistego zasobu, a nie jakiejś niepotrzebnie kontekstowej wersji tego zasobu. W przypadku kolekcji to samo można zrobićPOST
. Jeśli chcesz dodać do konkretnej kolekcji, jaki adres URL ma sensPOST
.Nadal pozostawia to niektóre szare obszary, ponieważ niektóre ścieżki mogą wskazywać, ile dzieci zasobów rodzicielskich jest nieco uznaniowe i zależy od ich wykorzystania. Jedyną twardą linią, którą to rysuje, jest to, że każdy rodzaj przechodnich reprezentacji powinien być wykonywany przy użyciu parametru zapytania, ponieważ nie miałby zasobu podstawowego.
W odpowiedzi na przykład ze świata rzeczywistego podany w pierwotnym pytaniu (API Twittera) parametry reprezentują zapytanie przechodnie, które filtruje stan zasobów (a nie hierarchię). W tym konkretnym przykładzie byłoby całkowicie nierozsądne dodawanie do kolekcji reprezentowanej przez te ograniczenia, a ponadto to zapytanie nie byłoby reprezentowane jako ścieżka, która miałaby jakikolwiek sens w kategoriach grafu obiektowego.
Przyjęcie tego rodzaju perspektywy zorientowanej na zasoby może łatwo odwzorować bezpośrednio na wykresie obiektowym modelu domeny i doprowadzić logikę interfejsu API do punktu, w którym wszystko działa bardzo czysto i w sposób dość dokumentujący, gdy tylko osiągnie przejrzystość. Koncepcję tę można również wyjaśnić, odchodząc od systemów, które używają tradycyjnego routingu adresów URL odwzorowanego na normalnie źle dopasowany model danych (tj. RDBMS). Proca Apache z pewnością byłaby dobrym miejscem do rozpoczęcia. Koncepcja wysyłania obiektów w systemie takim jak Zope zapewnia również wyraźniejszy analog.
źródło
Oto moja opinia.
Parametry zapytania są używane jako metadane żądania. Działają one jako filtr lub modyfikator istniejącego wywołania zasobu.
Przykład:
/calendar/2014-08-08/events
powinien podać wydarzenia kalendarzowe na ten dzień.
Jeśli chcesz wydarzenia dla określonej kategorii
/calendar/2014-08-08/events?category=appointments
lub jeśli potrzebujesz wydarzeń trwających dłużej niż 30 minut
/calendar/2014-08-08/events?duration=30
Test lakmusa polegałby na sprawdzeniu, czy żądanie może być nadal obsługiwane bez parametrów zapytania.
źródło
Zazwyczaj dążę do # 2, jako argument zapytania (tj. / Api / resource? Parametr = wartość).
Trzecią opcją jest opublikowanie parametru = wartość w treści.
Wynika to z faktu, że działa lepiej w przypadku zasobów o wielu parametrach i jest bardziej rozszerzalny do wykorzystania w przyszłości.
Bez względu na to, który wybierzesz, upewnij się, że wybierasz tylko jeden, nie mieszaj i nie dopasowuj. To prowadzi do mylącego API.
źródło
Jeden „wymiar” tego tematu został pominięty, ale jest on bardzo ważny: są chwile, w których „najlepsze praktyki” muszą być zgodne z planem, który wdrażamy lub rozszerzamy o możliwości REST.
Praktyczny przykład:
Wiele aplikacji internetowych obecnie implementuje architekturę MVC (Model, Widok, Kontroler). Zakładają, że zapewniona jest pewna standardowa ścieżka, tym bardziej, gdy te aplikacje internetowe mają opcję „Włącz adresy URL SEO”.
Wystarczy wspomnieć o dość znanej aplikacji internetowej: sklepie e-commerce OpenCart. Gdy administrator włączy „Adresy URL SEO”, oczekuje, że wspomniane adresy URL pojawią się w dość standardowym formacie MVC, takim jak:
Gdzie
special-offers
to kontroler MVC, który przetwarza adres URL (pokazuje stronę z ofertami specjalnymi)list-all
to nazwa akcji lub funkcji kontrolera, którą należy wywołać. (*)limit = 25 jest opcją, stwierdzającą, że na stronie będzie wyświetlanych 25 pozycji.
(*)
list-all
to fikcyjna nazwa funkcji, której użyłem dla jasności. W rzeczywistości OpenCart i większość platform MVC ma domyślną, domyślną (i zwykle pomijaną w adresie URL)index
funkcję, która jest wywoływana, gdy użytkownik chce wykonać domyślną akcję. Tak więc rzeczywisty adres URL to:Dzięki teraz dość standardowej aplikacji lub strukturze ramowej podobnej do powyższej często otrzymujesz zoptymalizowany do tego serwer sieciowy, który przepisuje dla niego adresy URL (prawdziwy „URL nie SEOedowany” to:)
http://www.domain.tld/index.php?route=special-offers/list-all&limit=25
.Dlatego jako programista masz do czynienia z istniejącą infrastrukturą i dostosowujesz swoje „najlepsze praktyki”, chyba że jesteś administratorem systemu, wiesz dokładnie, jak dostosować konfigurację przepisywania Apache / NGinx (ta ostatnia może być nieprzyjemna!) I tak dalej na.
Tak więc interfejs API REST często byłby znacznie lepszy zgodnie ze standardami aplikacji internetowej, zarówno pod względem zgodności z nim, jak i łatwości / szybkości (a tym samym oszczędności budżetu).
Aby powrócić do powyższego praktycznego przykładu, spójny interfejs API REST byłby czymś o adresach URL takich jak:
lub (adresy URL inne niż SEO)
z mieszanką argumentów „utworzonych ścieżek” i argumentów „utworzonych zapytań”.
źródło
Widzę wiele interfejsów API REST, które nie radzą sobie dobrze z parametrami. Jednym z często pojawiających się przykładów jest sytuacja, w której identyfikator URI zawiera dane osobowe.
http://software.danielwatrous.com/design-principles-for-rest-apis/
Myślę, że następczym pytaniem jest, kiedy parametr w ogóle nie powinien być parametrem, ale powinien zostać przeniesiony do NAGŁÓWKA lub CIAŁA żądania.
źródło
To bardzo interesujące pytanie.
Możesz użyć obu z nich, nie ma ścisłej reguły na ten temat, ale korzystanie ze zmiennych ścieżki URI ma pewne zalety:
Ale jeśli użyjesz zmiennych ścieżki, wszystkie te usługi mogą buforować twoje żądania GET.
Daje użytkownikowi więcej informacji na temat struktury danych.
Ale jeśli twoje dane nie mają żadnej relacji hierarchicznej, nadal możesz używać zmiennych ścieżki, używając przecinka lub średnika:
/ Miasto / długość geograficzna, szerokość geograficzna
Z reguły używaj przecinka, gdy kolejność parametrów ma znaczenie, użyj średnika, gdy kolejność nie ma znaczenia:
/ IconGenerator / czerwony; niebieski; zielony
Oprócz tych powodów istnieją przypadki, w których bardzo często używa się zmiennych ciągu zapytania:
http: // www.google.com/search?q=rest
Podsumowując, nie ma żadnego silnego powodu, aby używać jednej z tych metod, ale w miarę możliwości należy używać zmiennych URI.
źródło