Quando utilizzare @QueryParam vs @PathParam


277

Non sto ponendo la domanda che è già stata posta qui: qual è la differenza tra @PathParam e @QueryParam

Questa è una "best practice" o una domanda sulla convenzione.

Quando si usa @PathParamvs @QueryParam.

Quello che posso pensare è che la decisione potrebbe usare i due per differenziare il modello di informazione. Permettetemi di illustrare di seguito il mio LTPO - meno di un'osservazione perfetta.

L'uso di PathParam potrebbe essere riservato alla categoria di informazioni, che rientrerebbe perfettamente in un ramo di un albero di informazioni. PathParam può essere utilizzato per eseguire il drill-down della gerarchia di classi di entità.

Considerando che, QueryParam potrebbe essere riservato per specificare gli attributi per individuare l'istanza di una classe.

Per esempio,

  • /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) ;

Non penso che ci sia una convenzione standard per farlo. È lì? Tuttavia, vorrei sapere come le persone usano PathParam vs QueryParam per differenziare le loro informazioni come ho illustrato sopra. Mi piacerebbe anche sentire il motivo della pratica.


Risposte:


245

REST potrebbe non essere uno standard in quanto tale, ma la lettura della documentazione REST generale e dei post sul blog dovrebbe fornire alcune linee guida per un buon modo di strutturare gli URL API. La maggior parte delle API di riposo tendono ad avere solo nomi e ID risorse nel percorso. Ad esempio:

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

Alcune API REST usano stringhe di query per filtrare, impaginare e ordinare, ma poiché REST non è uno standard rigoroso, ti consiglio di controllare alcune API REST come github e stackoverflow e vedere cosa potrebbe funzionare bene per il tuo caso d'uso.

Consiglierei di inserire tutti i parametri richiesti nel percorso e tutti i parametri opzionali dovrebbero sicuramente essere parametri della stringa di query. Inserire parametri opzionali nel percorso finirà per diventare davvero disordinato quando si tenta di scrivere gestori di URL che corrispondono a combinazioni diverse.


73
" Mi piacerebbe raccomando di mettere tutti i parametri richiesti nel percorso, e gli eventuali parametri opzionali dovrebbe certamente essere di query parametri di stringa. " - pollici in su uno sì def
smeeb

1
se questa convenzione dovesse essere utilizzata anche per la richiesta Put, supponiamo di voler aggiornare una versione specifica dell'entità db, se l'URI fosse PUT /depatments/{dept}/employees/{id}/{version}e la versione fosse facoltativa o dovesse essere PUT /depatments/{dept}/employees/{id}?version=12e la versione fosse facoltativa
auguri

In questo caso, consiglierei: - PUT /depatments/{dept}/employees/{id}/versions/{version}di creare un dipendente con una versione scelta - POST /depatments/{dept}/employees/{id}/versionsdi creare un dipendente con una versione determinata dal backend
Guillaume Vauvert

90

Questo è ciò che faccio.

Se esiste uno scenario per recuperare un record basato su ID, ad esempio è necessario ottenere i dettagli dell'impiegato il cui ID è 15, quindi è possibile disporre di risorse con @PathParam.

GET /employee/{id}

Se esiste uno scenario in cui è necessario ottenere i dettagli di tutti i dipendenti, ma solo 10 alla volta, è possibile utilizzare la query param

GET /employee?start=1&size=10

Ciò significa che l'avvio dell'ID dipendente 1 ottiene dieci record.

Per riassumere, utilizzare @PathParam per il recupero in base all'ID. Utente @QueryParam per filtro o se si dispone di un elenco fisso di opzioni che l'utente può passare.


"@PathParam" e "@QueryParam" offrono la stessa funzionalità? '@QueryParam' è solo un altro modo di scrivere la stessa cosa?
Rishabh Agarwal,

1
@RishabhAgarwal anche se entrambi forniscono la stessa funzionalità, la pratica clean code è che, si consiglia di inserire un parametro richiesto come variabile di percorso e qualsiasi parametro opzionale come parametro di query.
Akhil Ghatiki il

@RishabhAgarwal Per ulteriori informazioni, è possibile fare riferimento al mio articolo Best Practices API Rest
Arun B Chandrasekaran

43

Penso che se il parametro identifica un'entità specifica, è necessario utilizzare una variabile di percorso. Ad esempio, per ottenere tutti i post sul mio blog che chiedo

GET: myserver.com/myblog/posts

per ottenere il post con id = 123, richiederei

GET: myserver.com/myblog/posts/123

ma per filtrare il mio elenco di post e ottenere tutti i post dal 1 ° gennaio 2013, lo richiederei

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

Nel primo esempio "post" identifica un'entità specifica (l'intera raccolta di post di blog). Nel secondo esempio, "123" rappresenta anche un'entità specifica (un singolo post di blog). Ma nell'ultimo esempio, il parametro "since = 2013-01-01" è una richiesta per filtrare la raccolta di messaggi non un'entità specifica. L'impaginazione e l'ordinamento sarebbero un altro buon esempio, ad es

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

Spero che aiuti. :-)


8

Personalmente ho usato l'approccio di "se ha senso per l'utente aggiungere un segnalibro a un URL che include questi parametri, quindi usa PathParam".

Ad esempio, se l'URL di un profilo utente include alcuni parametri dell'ID profilo, poiché questo può essere aggiunto ai segnalibri dall'utente e / o inviato tramite e-mail in giro, includerei tale ID profilo come parametro di percorso. Inoltre, un altro aspetto da tenere presente è che la pagina indicata dall'URL che include il percorso param non cambia: l'utente imposterà il suo profilo, lo salverà e quindi difficilmente cambierà molto da lì in poi; questo significa che i webcrawlers / i motori di ricerca / i browser / ecc. possono memorizzare in cache questa pagina in base al percorso.

Se è probabile che un parametro passato nell'URL cambi il layout / contenuto della pagina, lo userò come queryparam. Ad esempio, se l'URL del profilo supporta un parametro che specifica se mostrare l'email dell'utente o meno, lo considero un parametro di query. (So, probabilmente, si potrebbe dire che il &noemail=1parametro o qualunque esso sia può essere usato come un parametro di percorso e genera 2 pagine separate - una con l'e-mail su di essa, una senza di essa - ma logicamente non è il caso: esso è sempre la stessa pagina con o senza alcuni attributi mostrati.

Spero che questo aiuti - apprezzo che la spiegazione potrebbe essere un po 'sfocata :)


Penso che questa risposta confonda le risorse con le rotte. La domanda riguarda le risorse di un'API REST, che in genere restituisce JSON o XML, non le rotte di un'applicazione Web, che ti aiutano a navigare all'interno dell'applicazione.
Hampus


5

È una domanda molto interessante.

Puoi usarli entrambi, non esiste una regola rigida su questo argomento, ma l'uso delle variabili del percorso URI presenta alcuni vantaggi:

  • Cache : la maggior parte dei servizi di cache Web su Internet non memorizza nella cache la richiesta GET quando contiene parametri di query. Lo fanno perché ci sono molti sistemi RPC che utilizzano richieste GET per modificare i dati nel server (fallire !! Get deve essere un metodo sicuro)

Ma se usi variabili di percorso, tutti questi servizi possono memorizzare nella cache le tue richieste GET.

  • Gerarchia : le variabili del percorso possono rappresentare la gerarchia: / Città / Via / Luogo

Fornisce all'utente maggiori informazioni sulla struttura dei dati.

Ma se i tuoi dati non hanno alcuna relazione gerarchica, puoi comunque utilizzare le variabili Path, usando virgola o punto e virgola:

/ Città / longitudine, latitudine

Di norma, utilizzare la virgola quando l'ordinamento dei parametri è importante, utilizzare i punti e virgola quando l'ordinamento non ha importanza:

/ IconGenerator / rosso; blu; verde

A parte questi motivi, ci sono alcuni casi in cui è molto comune utilizzare le variabili della stringa di query:

  • Quando è necessario che il browser inserisca automaticamente le variabili del modulo HTML nell'URI
  • Quando hai a che fare con l'algoritmo. Ad esempio, il motore di Google utilizza stringhe di query:

http: // www.google.com/search?q=rest

Per riassumere, non c'è alcun motivo valido per usare uno di questi metodi, ma ogni volta che puoi, usa le variabili URI.


2

Come notato da te, REST non è uno standard. Tuttavia, se stai cercando di implementare una convenzione URI basata su standard, potresti prendere in considerazione la convenzione URI oData . La versione 4 è stata approvata come standard OASIS ed esistono librerie per oData per varie lingue, incluso Java tramite Apache Olingo . Non lasciarti scoraggiare dal fatto che sia un prodotto di Microsoft poiché ha ottenuto il supporto anche da altri giocatori del settore , tra cui Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook e SAP

Altri utenti vengono elencati qui


2

Da Wikipedia: Uniform Resource Locator

Un percorso , che contiene dati, generalmente organizzati in forma gerarchica , che appare come una sequenza di segmenti separati da barre.

Una query facoltativa , separata dalla parte precedente da un punto interrogativo (?), Contenente una stringa di query di dati non gerarchici .

- In base alla progettazione concettuale dell'URL, potremmo implementare un PathParam per i dati gerarchici / direttive / componenti di localizzazione o implementare un QueryParam quando i dati non sono gerarchici. Questo ha senso perché i percorsi sono naturalmente ordinati, mentre le query contengono variabili che possono essere ordinate in modo arbitrario (coppie variabili / valori non ordinate).

Un precedente commentatore ha scritto,

Penso che se il parametro identifica un'entità specifica, è necessario utilizzare una variabile di percorso.

Un altro ha scritto,

Utilizzare @PathParam per il recupero in base all'ID. Utente @QueryParam per filtro o se si dispone di un elenco fisso di opzioni che l'utente può passare.

Un altro,

Consiglierei di inserire tutti i parametri richiesti nel percorso e tutti i parametri opzionali dovrebbero sicuramente essere parametri della stringa di query.

- Tuttavia, si potrebbe implementare un sistema flessibile, non gerarchico per identificare entità specifiche! Uno potrebbe avere più indici univoci su una tabella SQL e consentire l'identificazione delle entità usando qualsiasi combinazione di campi che compongono un indice univoco! Combinazioni diverse (forse anche ordinate in modo diverso), potrebbero essere utilizzate per collegamenti da varie entità correlate (referrer). In questo caso, potremmo avere a che fare con dati non gerarchici, usati per identificare singole entità - o in altri casi, potremmo specificare solo determinate variabili / campi - alcuni componenti di indici univoci - e recuperare un elenco / set di record. In tali casi, potrebbe essere più semplice, logico e ragionevole implementare gli URL come QueryParams!

Una lunga stringa esadecimale potrebbe diluire / diminuire il valore delle parole chiave nel resto del percorso? Potrebbe valere la pena considerare le potenziali implicazioni SEO del posizionamento di variabili / valori nel percorso o nella querye le implicazioni dell'interfaccia umana sul fatto che desideriamo che gli utenti siano in grado di attraversare / esplorare la gerarchia degli URL modificando il contenuto della barra degli indirizzi. La mia pagina 404 non trovata utilizza le variabili SSI per reindirizzare automaticamente gli URL non funzionanti ai loro genitori! I robot di ricerca potrebbero anche attraversare la gerarchia dei percorsi. D'altra parte, personalmente, quando condivido gli URL sui social media, rimuovo manualmente tutti gli identificatori univoci privati, in genere troncando la query dall'URL, lasciando solo il percorso: in questo caso, c'è qualche utilità nel posizionare identificatori univoci nel percorso piuttosto che nella query. Se vogliamo facilitare l'uso dei componenti del percorso come interfaccia utente grezza, forse dipende dal fatto che i dati / componenti siano leggibili o meno. La questione della leggibilità umana riguarda in qualche modo la questione della gerarchia: spesso, anche i dati che possono essere espressi come parole chiave leggibili dall'uomo sono gerarchici; mentre i dati gerarchici possono spesso essere espressi come parole chiave leggibili dall'uomo. (I motori di ricerca stessi potrebbero essere definiti in modo da aumentare l'uso degli URL come interfaccia utente.) Le gerarchie di parole chiave o direttive potrebbero non essere ordinate rigorosamente, ma di solito sono abbastanza vicine da poter coprire casi alternativi nel percorso, eetichetta un'opzione come il caso "canonico" .

Esistono fondamentalmente diversi tipi di domande a cui potremmo rispondere con l'URL per ogni richiesta:

  1. Che tipo di record / cosa stiamo richiedendo / servendo?
  2. A quale (i) siamo interessati?
  3. Come vogliamo presentare le informazioni / i record?

Q1 è quasi certamente meglio coperto dal percorso o da PathParams. Q3 (che è probabilmente controllato tramite una serie di parametri opzionali arbitrariamente ordinati e valori predefiniti); è quasi sicuramente meglio coperto da QueryParams. Q2: dipende ...


2

È possibile supportare sia i parametri della query sia i parametri del percorso, ad esempio, nel caso di aggregazione di risorse, quando la raccolta di risorse secondarie ha senso da sola.

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

I parametri di query possono supportare il sottoinsieme gerarchico e non gerarchico; i parametri del percorso sono solo gerarchici.

Le risorse possono presentare più gerarchie. Supporta percorsi brevi se esegui query su raccolte secondarie estese che attraversano i confini gerarchici.

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

Utilizzare i parametri di query per combinare le gerarchie ortogonali.

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

Usa solo i parametri del percorso nel caso della composizione - quando una risorsa non ha senso divorziata dal suo genitore e la raccolta globale di tutti i bambini non è una risorsa utile in sé.

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

1

Il motivo è in realtà molto semplice. Quando si utilizza un parametro di query, è possibile inserire caratteri come "/" e il client non deve codificarli in HTML. Ci sono altri motivi, ma questo è un semplice esempio. Per quanto riguarda quando utilizzare una variabile di percorso. Vorrei dire ogni volta che hai a che fare con id o se la variabile path è una direzione per una query.


1

Sto dando un esempio alla undersand quando usiamo @Queryparame@pathparam

Ad esempio, sto prendendo una risorsa è di carResourceclasse

Se vuoi rendere gestibili gli input del tuo metodo di risorsa, usa il tipo param come @pathaparam, se gli input del tuo metodo di risorsa dovrebbero essere opzionali, allora mantieni quel tipo di @QueryParamparametro come param

@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
    }
}

Per questa risposta passare la richiesta

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

Se fornisci req in questo modo, la risorsa fornirà il modello e il colore di base dell'auto

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

Se dai a req in questo modo il metodo Resice mostrerà solo un'auto basata su un modello rapido

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

Se lo fai in questo modo otterremo un'eccezione ResourceNotFound perché nella classe di risorgimento auto ho dichiarato il modello del carmello @pathPramche è necessario e dovresti fornire il modello come reQ uri altrimenti non passerà il req per risorgere ma se non passi il colore inoltre passerà il req alla risorsa perché, poiché il colore @quetyParamè facoltativo in req.


0
  1. @QueryParam può essere comodamente utilizzato con l'annotazione Valore predefinito in modo da evitare un'eccezione puntatore null se non viene passato alcun parametro di query.

Quando si desidera analizzare i parametri della query da una richiesta GET, è possibile semplicemente definire i rispettivi parametri per il metodo che gestirà la richiesta GET e annotarli con @QueryParamannotazioni

  1. @PathParamestrae i valori URI e corrisponde a @Path. E quindi ottiene il parametro di input. 2.1 @PathParampuò essere più di uno ed è impostato su argomenti di metodi

    @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);
        }
    } 

Nell'esempio sopra
http://localhost:8080/Restr/rest/msg/{p0}/{p1},
p0partite param1e p1partite param2. Quindi, per l'URI
http://localhost:8080/Restr/rest/msg/4/6,
otteniamo il risultato 10.

Nel servizio REST, JAX-RS fornisce @QueryParamed @FormParamentrambi per accettare i dati dalla richiesta HTTP. Un modulo HTTP può essere inviato con diversi metodi come GET e POST.

@QueryParam : Accetta la richiesta GET e legge i dati dalla stringa di query.

@FormParam: Accetta la richiesta POST e recupera i dati dal modulo HTML o da qualsiasi richiesta del supporto


0

In poche parole,

@Pathparam funziona per il valore che passa sia attraverso le risorse che la stringa di query

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

@Queryparam funziona per il valore passando solo Query String

  • /user?id=1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.