Kiedy używać @QueryParam vs. @PathParam


276

Nie zadaję już zadanego pytania: Jaka jest różnica między @PathParam a @QueryParam

To jest „najlepsza praktyka” lub pytanie z konwencji.

Kiedy należy użyć @PathParamvs @QueryParam.

Co mogę o tym pomyśleć, w decyzji można wykorzystać te dwa elementy do rozróżnienia wzorca informacji. Pozwól mi zilustrować poniżej mojego LTPO - mniej niż idealna obserwacja.

Użycie PathParam może być zarezerwowane dla kategorii informacji, która ładnie wpada w gałąź drzewa informacji. PathParam można wykorzystać do przejścia do hierarchii klas jednostek.

Natomiast QueryParam można zarezerwować do określania atrybutów w celu zlokalizowania wystąpienia klasy.

Na przykład,

  • /Vehicle/Car?registration=123
  • /House/Colonial?region=newengland

/category?instance

@GET
@Path("/employee/{dept}")
Patient getEmployee(@PathParam("dept")Long dept, @QueryParam("id")Long id) ;

vs /category/instance

@GET
@Path("/employee/{dept}/{id}")
Patient getEmployee(@PathParam("dept")Long dept, @PathParam("id")Long id) ;

vs ?category+instance

@GET
@Path("/employee")
Patient getEmployee(@QueryParam("dept")Long dept, @QueryParam("id")Long id) ;

Nie sądzę, że istnieje standardowa konwencja robienia tego. Jest tu? Chciałbym jednak usłyszeć o tym, jak ludzie używają PathParam vs QueryParam do różnicowania swoich informacji, tak jak na przykładzie powyżej. Bardzo chciałbym usłyszeć przyczynę tej praktyki.


Odpowiedzi:


245

REST może nie być standardem jako takim, ale czytanie ogólnej dokumentacji REST i postów na blogu powinno dać ci wskazówki, jak dobrze ustrukturyzować adresy URL API. Większość pozostałych interfejsów API zwykle ma na ścieżce tylko nazwy i identyfikatory zasobów. Jak na przykład:

/departments/{dept}/employees/{id}

Niektóre interfejsy API REST używają ciągów zapytań do filtrowania, stronicowania i sortowania, ale ponieważ REST nie jest ścisłym standardem, polecam sprawdzenie niektórych interfejsów API REST, takich jak github i stackoverflow, i zobaczenie, co może działać dobrze w twoim przypadku użycia.

Polecam umieszczenie wymaganych parametrów na ścieżce, a wszelkie parametry opcjonalne powinny z pewnością być parametrami ciągu zapytania. Umieszczenie opcjonalnych parametrów na ścieżce spowoduje, że będzie się naprawdę bałaganić podczas próby napisania programów obsługi adresów URL, które pasują do różnych kombinacji.


73
Chciałbym zalecamy umieszczenie wszystkich wymaganych parametrów na ścieżce, a wszelkie ewentualne parametry powinny być z pewnością zapytań parametry string. ” - kciuk +1 tak def
smeeb

1
jeśli ta konwencja ma być również zastosowana do żądania Put, powiedzmy, że chcemy zaktualizować określoną wersję encji db, czy identyfikator URI powinien być PUT /depatments/{dept}/employees/{id}/{version}i wersja jest opcjonalna, czy powinna, PUT /depatments/{dept}/employees/{id}?version=12a wersja jest opcjonalna
najlepsze życzenia

W takim przypadku zaleciłbym: - PUT /depatments/{dept}/employees/{id}/versions/{version}utworzenie pracownika z wybraną wersją - POST /depatments/{dept}/employees/{id}/versionsutworzenie pracownika z wersją określoną przez backend
Guillaume Vauvert

90

Tym się właśnie zajmuję.

Jeśli istnieje scenariusz pobrania rekordu na podstawie identyfikatora, na przykład musisz uzyskać szczegółowe informacje o pracowniku o identyfikatorze 15, możesz mieć zasób z @PathParam.

GET /employee/{id}

Jeśli istnieje scenariusz, w którym musisz uzyskać szczegółowe informacje o wszystkich pracownikach, ale tylko 10 naraz, możesz użyć parametru zapytania

GET /employee?start=1&size=10

Oznacza to, że początkowy identyfikator pracownika 1 otrzymuje dziesięć rekordów.

Podsumowując, użyj @PathParam do pobierania na podstawie identyfikatora. Użytkownik @QueryParam dla filtra lub jeśli masz ustaloną listę opcji, które użytkownik może przekazać.


czy zarówno „@PathParam”, jak i „@QueryParam” zapewniają tę samą funkcjonalność? Czy „@QueryParam” to tylko inny sposób pisania tego samego?
Rishabh Agarwal

1
@RishabhAgarwal, mimo że oba zapewniają tę samą funkcjonalność, praktyka czyszczenia kodu polega na tym, że zalecane jest ustawienie wymaganego parametru jako zmiennej ścieżki i dowolnego parametru opcjonalnego jako parametru zapytania.
Akhil Ghatiki,

@RishabhAgarwal Aby uzyskać więcej informacji, możesz zapoznać się z moim artykułem Najważniejsze wskazówki dotyczące interfejsu API Rest
Arun B Chandrasekaran,

43

Myślę, że jeśli parametr identyfikuje konkretny byt, powinieneś użyć zmiennej ścieżki. Na przykład, aby uzyskać wszystkie posty na moim blogu, proszę

GET: myserver.com/myblog/posts

aby otrzymać post o id = 123, poprosiłbym

GET: myserver.com/myblog/posts/123

ale poprosiłem o filtrowanie mojej listy postów i uzyskanie wszystkich postów od 1 stycznia 2013 r

GET: myserver.com/myblog/posts?since=2013-01-01

W pierwszym przykładzie „posty” identyfikują konkretny byt (cały zbiór postów na blogu). W drugim przykładzie „123” oznacza także konkretny byt (pojedynczy post na blogu). Ale w ostatnim przykładzie parametr „od = 01.01.2013” ​​jest żądaniem filtrowania kolekcji wpisów, a nie konkretnym podmiotem. Kolejnym dobrym przykładem jest paginacja i porządkowanie

GET: myserver.com/myblog/posts?page=2&order=backward

Mam nadzieję, że to pomaga. :-)


8

Ja osobiście zastosowałem podejście „jeśli użytkownik ma sens, aby dodać zakładkę do adresu URL, który zawiera te parametry, użyj PathParam”.

Na przykład, jeśli adres URL profilu użytkownika zawiera parametr identyfikatora profilu, ponieważ użytkownik może go dodać do zakładek i / lub wysłać pocztą e-mail, podałbym ten identyfikator profilu jako parametr ścieżki. Inną konsekwencją tego jest to, że strona oznaczona adresem URL zawierającym parametr ścieżki nie zmienia się - użytkownik skonfiguruje swój profil, zapisze go, a następnie prawdopodobnie nie zmieni tak wiele; oznacza to, że webcrawlers / wyszukiwarki / przeglądarki / etc mogą ładnie buforować tę stronę w oparciu o ścieżkę.

Jeśli parametr przekazany w adresie URL prawdopodobnie zmieni układ / treść strony, użyłbym tego jako parametru query. Na przykład, jeśli adres URL profilu obsługuje parametr określający, czy ma być wyświetlany adres e-mail użytkownika, czy nie, uważam to za parametr zapytania. (Wiem, zapewne można powiedzieć, że&noemail=1 parametr lub cokolwiek to jest parametr może być użyty jako parametr ścieżki i generuje 2 osobne strony - jedną z e-mailem, drugą bez niego - ale logicznie tak nie jest: to wciąż ta sama strona z pokazanymi atrybutami lub bez nich.

Mam nadzieję, że to pomoże - doceniam wyjaśnienie, które może być nieco rozmyte :)


Myślę, że te odpowiedzi mylą zasoby z trasami. Pytanie dotyczy zasobów interfejsu API REST, zwykle zwracających JSON lub XML, a nie tras aplikacji internetowej, które pomagają nawigować w obrębie aplikacji.
Hampus


5

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:

  • Pamięć podręczna : większość internetowych usług pamięci podręcznej w Internecie nie buforuje żądania GET, gdy zawierają parametry zapytania. Robią to, ponieważ istnieje wiele systemów RPC korzystających z żądań GET do zmiany danych na serwerze (błąd !! Get musi być bezpieczną metodą)

Ale jeśli użyjesz zmiennych ścieżki, wszystkie te usługi mogą buforować twoje żądania GET.

  • Hierarchia : Zmienne ścieżki mogą reprezentować hierarchię: / Miasto / Ulica / Miejsce

Daje to użytkownikowi więcej informacji o strukturze 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 stosuje się zmienne ciągu zapytania:

  • Gdy potrzebujesz, aby przeglądarka automatycznie wstawiała zmienne formularza HTML do identyfikatora URI
  • Kiedy masz do czynienia z algorytmem. Na przykład silnik Google używa ciągów zapytań:

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.


2

Jak wspomniano, REST nie jest standardem. Jeśli jednak chcesz wdrożyć standardową konwencję URI, możesz rozważyć konwencję oData URI . Wersja 4 została zatwierdzona jako standard OASIS i istnieją biblioteki dla oData dla różnych języków, w tym Java przez Apache Olingo . Nie zniechęcaj się faktem, że jest to spawn od Microsoftu, ponieważ uzyskał on wsparcie również od innych graczy z branży tym Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook i SAP

Więcej osób adoptujących jest wymienionych tutaj


2

Z Wikipedii: Uniform Resource Locator

Ścieżka , która zawiera dane, zwykle zorganizowane w formie hierarchicznej , która pojawia się jako sekwencja segmentów oddzielonych ukośnikami.

Opcjonalne zapytanie , oddzielone od poprzedniej części znakiem zapytania (?), Zawierające ciąg zapytania danych niehierarchicznych .

- Zgodnie z koncepcyjnym projektem adresu URL możemy zaimplementować PathParam dla danych hierarchicznych / dyrektyw / komponentów lokalizatora lub zaimplementować QueryParam, gdy dane nie są hierarchiczne. Ma to sens, ponieważ ścieżki są naturalnie uporządkowane, podczas gdy zapytania zawierają zmienne, które można uporządkować dowolnie (nieuporządkowane pary zmienne / wartości).

Poprzedni komentator napisał:

Myślę, że jeśli parametr identyfikuje konkretny byt, powinieneś użyć zmiennej ścieżki.

Inny napisał:

Użyj @PathParam do pobierania na podstawie identyfikatora. Użytkownik @QueryParam dla filtra lub jeśli masz ustaloną listę opcji, które użytkownik może przekazać.

Inne,

Polecam umieszczenie wymaganych parametrów na ścieżce, a wszelkie parametry opcjonalne powinny z pewnością być parametrami ciągu zapytania.

- Można jednak wdrożyć elastyczny, niehierarchiczny system identyfikacji określonych podmiotów! Można mieć wiele unikalnych indeksów w tabeli SQL i pozwolić na identyfikację jednostek za pomocą dowolnej kombinacji pól, która zawiera unikalny indeks! Różne kombinacje (być może również zamawiane inaczej) mogą być użyte w przypadku linków z różnych powiązanych podmiotów (stron odsyłających). W takim przypadku możemy mieć do czynienia z danymi niehierarchicznymi, służącymi do identyfikacji poszczególnych podmiotów - lub w innych przypadkach mogą określać tylko niektóre zmienne / pola - niektóre składniki unikalnych indeksów - i odzyskiwać listę / zestaw rekordów. W takich przypadkach implementacja adresów URL jako QueryParams może być łatwiejsza, bardziej logiczna i rozsądna!

Czy długi łańcuch szesnastkowy może osłabić / zmniejszyć wartość słów kluczowych w pozostałej części ścieżki? To może być warte zastanowić się nad potencjalnymi konsekwencjami SEO umieszczania zmiennych / wartości na ścieżce lub w zapytaniuoraz implikacje dla ludzkiego interfejsu, czy chcemy, aby użytkownicy mogli przeglądać / badać hierarchię adresów URL, edytując zawartość paska adresu. Moja strona 404 nie znaleziona używa zmiennych SSI, aby automatycznie przekierowywać uszkodzone adresy URL do ich rodziców! Roboty wyszukujące mogą również przechodzić przez hierarchię ścieżek. Z drugiej strony osobiście, kiedy udostępniam adresy URL w mediach społecznościowych, ręcznie usuwam wszelkie prywatne unikalne identyfikatory - zwykle przez obcięcie zapytania z adresu URL, pozostawiając tylko ścieżkę: w tym przypadku istnieje pewna użyteczność w umieszczaniu unikalnych identyfikatorów w ścieżce zamiast w zapytaniu. To, czy chcemy ułatwić korzystanie z komponentów ścieżki jako prostego interfejsu użytkownika, może zależy od tego, czy dane / komponenty są czytelne dla człowieka, czy nie. Pytanie o czytelność dla człowieka wiąże się nieco z kwestią hierarchii: często dane, które można wyrazić jako słowa kluczowe czytelne dla człowieka, są również hierarchiczne; podczas gdy dane hierarchiczne często mogą być wyrażone jako słowa kluczowe czytelne dla człowieka. (Same wyszukiwarki mogą być zdefiniowane jako zwiększenie wykorzystania adresów URL jako interfejsu użytkownika.) Hierarchie słów kluczowych lub dyrektyw mogą nie być ściśle uporządkowane, ale zwykle są wystarczająco blisko, abyśmy mogli uwzględnić alternatywne przypadki na ścieżce, ioznacz jedną opcję jako przypadek „kanoniczny” .

Istnieje zasadniczo kilka rodzajów pytań, na które możemy odpowiedzieć za pomocą adresu URL dla każdego żądania:

  1. Jakiego rodzaju rekordu / rzeczy żądamy / serwujemy?
  2. Których jesteśmy zainteresowani?
  3. Jak chcemy prezentować informacje / zapisy?

Pytanie 1 prawie na pewno najlepiej pokrywa ścieżka lub PathParams. Q3 (który jest prawdopodobnie kontrolowany przez zestaw arbitralnie uporządkowanych parametrów opcjonalnych i wartości domyślnych); jest prawie na pewno najlepiej objęty przez QueryParams. Q2: To zależy…


2

Możesz obsługiwać zarówno parametry zapytania, jak i parametry ścieżki, np. W przypadku agregacji zasobów - gdy samo gromadzenie poddziałów ma sens.

/departments/{id}/employees
/employees?dept=id

Parametry zapytania mogą obsługiwać podzbiory hierarchiczne i niehierarchiczne; parametry ścieżki są tylko hierarchiczne.

Zasoby mogą wykazywać wiele hierarchii. Obsługuj krótkie ścieżki, jeśli będziesz sprawdzać szerokie podkolekcje przekraczające granice hierarchii.

/inventory?make=toyota&model=corolla
/inventory?year=2014

Użyj parametrów zapytania, aby połączyć hierarchie ortogonalne.

/inventory/makes/toyota/models/corolla?year=2014
/inventory/years/2014?make=toyota&model=corolla
/inventory?make=toyota&model=corolla&year=2014

Używaj tylko parametrów ścieżki w przypadku kompozycji - gdy zasób nie ma sensu oddzielać się od jego elementu nadrzędnego, a globalna kolekcja wszystkich elementów podrzędnych nie jest sama w sobie przydatnym zasobem.

/words/{id}/definitions
/definitions?word=id   // not useful

1

Powód jest w rzeczywistości bardzo prosty. Korzystając z parametru zapytania, można przyjmować znaki takie jak „/”, a klient nie musi ich kodować w formacie HTML. Istnieją inne powody, ale jest to prosty przykład. Co do tego, kiedy użyć zmiennej ścieżki. Powiedziałbym, że kiedy masz do czynienia z identyfikatorami lub jeśli zmienna ścieżki jest kierunkiem zapytania.


1

Daję jeden przykład do dołu i kiedy używamy @Queryparami@pathparam

Na przykład biorę jeden zasób to carResourceklasa

Jeśli chcesz, aby dane wejściowe twojej metody resouce były manadatory, użyj typu param as @pathaparam, jeśli dane wejściowe twojej metody zasobów powinny być opcjonalne, zachowaj ten typ @QueryParamparam jako parametr

@Path("/car")
class CarResource
{
    @Get
    @produces("text/plain")
    @Path("/search/{carmodel}")
    public String getCarSearch(@PathParam("carmodel")String model,@QueryParam("carcolor")String color) {
        //logic for getting cars based on carmodel and color
            -----
        return cars
    }
}

Do tego zasobu przekaż żądanie

req uri ://address:2020/carWeb/car/search/swift?carcolor=red

Jeśli podasz takie wymaganie, zasoby podadzą model samochodu i kolor

 req uri://address:2020/carWeb/car/search/swift

Jeśli podasz taki wymóg, metoda resoce wyświetli tylko szybki model samochodu

req://address:2020/carWeb/car/search?carcolor=red

Jeśli podasz w ten sposób, otrzymamy wyjątek ResourceNotFound, ponieważ w klasie zasobów samochodowych zadeklarowałem karmodel, ponieważ @pathPrammusisz to zrobić i powinieneś podać go jako reQ uri, w przeciwnym razie nie przejdzie on wymaganego zasobu, ale jeśli nie podasz koloru również przekaże wymaganie do zasobu dlaczego, ponieważ kolor @quetyParamjest opcjonalny w wymaganiu.


0
  1. @QueryParam można wygodnie używać z adnotacją Wartość domyślna, dzięki czemu można uniknąć wyjątku wskaźnika zerowego, jeśli nie zostanie przekazany żaden parametr zapytania.

Jeśli chcesz przeanalizować parametry zapytania z żądania GET, możesz po prostu zdefiniować odpowiedni parametr dla metody, która będzie obsługiwać żądanie GET i opatrzyć je @QueryParamadnotacjami

  1. @PathParamwyodrębnia wartości URI i dopasowuje do @Path. I stąd pobiera parametr wejściowy. 2.1 @PathParammoże być więcej niż jednym i jest ustawiony na argumenty metod

    @Path("/rest")
    public class Abc {
    
        @GET
        @Path("/msg/{p0}/{p1}")
        @Produces("text/plain")
        public String add(@PathParam("p0") Integer param1, @PathParam("p1")  Integer param2 )
        {
            return String.valueOf(param1+param2);
        }
    } 

W powyższym przykładzie
http://localhost:8080/Restr/rest/msg/{p0}/{p1},
p0mecze param1i p1mecze param2. Tak na URI
http://localhost:8080/Restr/rest/msg/4/6,
możemy uzyskać wynik 10.

W usłudze REST JAX-RS zapewnia @QueryParami @FormParamoba do akceptowania danych z żądania HTTP. Formularz HTTP można przesłać różnymi metodami, takimi jak GET i POST.

@QueryParam : Akceptuje żądanie GET i odczytuje dane z ciągu zapytania.

@FormParam: Akceptuje żądanie POST i pobiera dane z formularza HTML lub dowolnego żądania mediów


0

W pigułce,

@Pathparam działa dla wartości przekazywanej zarówno przez Zasoby, jak i Ciąg Zapytania

  • /user/1
  • /user?id=1

@Queryparam działa dla wartości przekazującej tylko ciąg zapytania

  • /user?id=1
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.