Cuándo usar @QueryParam vs @PathParam

277

No estoy haciendo la pregunta que ya se hace aquí: ¿Cuál es la diferencia entre @PathParam y @QueryParam?

Esta es una pregunta de "mejores prácticas" o convención.

¿Cuándo utilizar @PathParamvs @QueryParam.

Lo que puedo pensar es que la decisión podría estar usando los dos para diferenciar el patrón de información. Permítanme ilustrar debajo de mi LTPO: observación menos que perfecta.

El uso de PathParam podría reservarse para la categoría de información, que caería muy bien en una rama de un árbol de información. PathParam podría usarse para profundizar en la jerarquía de clase de entidad.

Mientras que QueryParam podría reservarse para especificar atributos para localizar la instancia de una clase.

Por ejemplo,

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

No creo que haya una convención estándar para hacerlo. ¿Esta ahí? Sin embargo, me gustaría saber cómo las personas usan PathParam vs QueryParam para diferenciar su información como lo ejemplifiqué anteriormente. También me encantaría escuchar la razón detrás de la práctica.

Beato Geek
fuente
44
posible duplicado de Cuándo usar pathParams o QueryParams
Joachim Sauer

Respuestas:

245

Puede que REST no sea un estándar como tal, pero leer la documentación general de REST y las publicaciones de blog debería darle algunas pautas para una buena forma de estructurar las URL de API. La mayoría de las API de descanso tienden a tener solo nombres de recursos e ID de recursos en la ruta. Como:

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

Algunas API REST usan cadenas de consulta para el filtrado, la paginación y la clasificación, pero como REST no es un estándar estricto, recomendaría verificar algunas API REST como github y stackoverflow y ver qué podría funcionar bien para su caso de uso.

Recomiendo poner cualquier parámetro requerido en la ruta, y cualquier parámetro opcional ciertamente debería ser un parámetro de cadena de consulta. Poner parámetros opcionales en la ruta terminará siendo muy complicado cuando intente escribir controladores de URL que coincidan con diferentes combinaciones.

theon
fuente
73
" Recomiendo poner cualquier parámetro requerido en la ruta, y cualquier parámetro opcional debería ser un parámetro de cadena de consulta " . - aprobado +1 sí def
smeeb
1
si esta convención se usa también para la solicitud Put, digamos que queremos actualizar una versión específica de la entidad db, si el URI PUT /depatments/{dept}/employees/{id}/{version}y la versión son opcionales o si lo es PUT /depatments/{dept}/employees/{id}?version=12y la versión es opcional
mis mejores deseos
En este caso, recomendaría: - PUT /depatments/{dept}/employees/{id}/versions/{version}crear un empleado con una versión elegida - POST /depatments/{dept}/employees/{id}/versionscrear un empleado con una versión determinada por el backend
Guillaume Vauvert
90

Esto es lo que hago.

Si hay un escenario para recuperar un registro basado en la identificación, por ejemplo, necesita obtener los detalles del empleado cuya identificación es 15, entonces puede tener recursos con @PathParam.

GET /employee/{id}

Si hay un escenario en el que necesita obtener los detalles de todos los empleados pero solo 10 a la vez, puede usar el parámetro de consulta

GET /employee?start=1&size=10

Esto dice que la identificación de empleado inicial 1 obtiene diez registros.

Para resumir, use @PathParam para la recuperación basada en la identificación. Usuario @QueryParam para el filtro o si tiene alguna lista fija de opciones que el usuario pueda pasar.

Arun B Chandrasekaran
fuente
¿Tanto '@PathParam' como '@QueryParam' proporcionan la misma funcionalidad? ¿Es '@QueryParam' simplemente otra forma de escribir lo mismo?
Rishabh Agarwal
1
@RishabhAgarwal, aunque ambos proporcionan la misma funcionalidad, la práctica del código limpio es que, se recomienda colocar un parámetro requerido como variable de ruta y cualquier parámetro opcional como parámetro de consulta.
Akhil Ghatiki
@RishabhAgarwal Para obtener más información, puede consultar mi artículo Recomendaciones de Rest API
Arun B Chandrasekaran
43

Creo que si el parámetro identifica una entidad específica, debe usar una variable de ruta. Por ejemplo, para obtener todas las publicaciones en mi blog solicito

GET: myserver.com/myblog/posts

para obtener la publicación con id = 123, solicitaría

GET: myserver.com/myblog/posts/123

pero para filtrar mi lista de publicaciones y obtener todas las publicaciones desde el 1 de enero de 2013, solicitaría

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

En el primer ejemplo, "publicaciones" identifica una entidad específica (la colección completa de publicaciones de blog). En el segundo ejemplo, "123" también representa una entidad específica (una sola publicación de blog). Pero en el último ejemplo, el parámetro "since = 2013-01-01" es una solicitud para filtrar la colección de publicaciones, no una entidad específica. La paginación y el orden serían otro buen ejemplo, es decir

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

Espero que ayude. :-)

10 grano de arena
fuente
8

Personalmente utilicé el enfoque de "si tiene sentido que el usuario marque una URL que incluya estos parámetros, use PathParam".

Por ejemplo, si la URL para un perfil de usuario incluye algún parámetro de ID de perfil, ya que el usuario puede marcarlo y enviarlo por correo electrónico, incluiría esa ID de perfil como parámetro de ruta. Además, otra consideración para esto es que la página indicada por la URL que incluye la ruta param no cambia: el usuario configurará su perfil, lo guardará y luego es poco probable que cambie tanto a partir de ahí; Esto significa que los webcrawlers / motores de búsqueda / navegadores / etc pueden almacenar en caché esta página en función de la ruta.

Si es probable que un parámetro pasado en la URL cambie el diseño / contenido de la página, lo usaría como un marco de consulta. Por ejemplo, si la URL del perfil admite un parámetro que especifica si se muestra o no el correo electrónico del usuario, consideraría que es un parámetro de consulta. (Sé que podría decirse que el&noemail=1 parámetro o cualquier parámetro que sea se puede usar como parámetro de ruta y genera 2 páginas separadas, una con el correo electrónico, una sin él, pero lógicamente ese no es el caso: es sigue siendo la misma página con o sin ciertos atributos mostrados.

Espero que esto ayude, agradezco que la explicación sea un poco confusa :)

Liv
fuente
Creo que esta respuesta confunde los recursos con las rutas. La pregunta es sobre los recursos de una API REST, que generalmente devuelve JSON o XML, no sobre las rutas de una aplicación web, que lo ayudan a navegar dentro de la aplicación.
Hampus
5

Es una pregunta muy interesante.

Puede usar ambos, no hay ninguna regla estricta sobre este tema, pero el uso de variables de ruta URI tiene algunas ventajas:

  • Caché : la mayoría de los servicios de caché web en Internet no almacenan en caché la solicitud GET cuando contienen parámetros de consulta. Lo hacen porque hay muchos sistemas RPC que usan solicitudes GET para cambiar los datos en el servidor (¡¡¡¡falla !! Get debe ser un método seguro)

Pero si usa variables de ruta, todos estos servicios pueden almacenar en caché sus solicitudes GET.

  • Jerarquía : las variables de ruta pueden representar la jerarquía: / Ciudad / Calle / Lugar

Le da al usuario más información sobre la estructura de los datos.

Pero si sus datos no tienen ninguna relación de jerarquía, aún puede usar las variables de ruta, usando una coma o punto y coma:

/ Ciudad / longitud, latitud

Como regla general, use una coma cuando el orden de los parámetros sea importante, use punto y coma cuando el orden no sea importante:

/ IconGenerator / rojo; azul; verde

Además de esos motivos, hay algunos casos en los que es muy común usar variables de cadena de consulta:

  • Cuando necesita que el navegador coloque automáticamente variables de formulario HTML en el URI
  • Cuando se trata de algoritmo. Por ejemplo, el motor de Google utiliza cadenas de consulta:

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

En resumen, no hay ninguna razón sólida para usar uno de estos métodos, pero siempre que pueda, use variables URI.

jfcorugedo
fuente
2

Como señaló Theon, REST no es un estándar. Sin embargo, si está buscando implementar una convención de URI basada en estándares, puede considerar la convención de URI de oData . Ver 4 ha sido aprobado como un estándar OASIS y existen bibliotecas para oData para varios idiomas, incluido Java, a través de Apache Olingo . No permita que el hecho de que sea un engendro de Microsoft lo desanime, ya que también obtuvo el apoyo de otros jugadores de la industria. , que incluyen Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook y SAP

Más adoptadores se enumeran aquí

MikeM
fuente
2

De Wikipedia: Localizador uniforme de recursos

Una ruta , que contiene datos, generalmente organizada en forma jerárquica. , que aparece como una secuencia de segmentos separados por barras.

Una consulta opcional , separada de la parte anterior por un signo de interrogación (?), Que contiene una cadena de consulta de datos no jerárquicos .

- De acuerdo con el diseño conceptual de la URL, podríamos implementar un PathParam para datos jerárquicos / directivas / componentes de localización, o implementar un QueryParam cuando los datos no son jerárquicos. Esto tiene sentido porque las rutas están naturalmente ordenadas, mientras que las consultas contienen variables que pueden ordenarse arbitrariamente (pares de variables / valores desordenados).

Un comentarista anterior escribió:

Creo que si el parámetro identifica una entidad específica, debe usar una variable de ruta.

Otro escribió:

Use @PathParam para la recuperación basada en la identificación. Usuario @QueryParam para el filtro o si tiene alguna lista fija de opciones que el usuario pueda pasar.

Otro,

Recomiendo poner cualquier parámetro requerido en la ruta, y cualquier parámetro opcional ciertamente debería ser un parámetro de cadena de consulta.

- Sin embargo, ¡uno podría implementar un sistema flexible y no jerárquico para identificar entidades específicas! ¡Uno podría tener múltiples índices únicos en una tabla SQL y permitir que se identifiquen entidades usando cualquier combinación de campos que comprenda un índice único! Se pueden usar diferentes combinaciones (quizás también ordenadas de manera diferente) para enlaces de varias entidades relacionadas (referentes). En este caso, podríamos estar tratando con datos no jerárquicos, utilizados para identificar entidades individuales, o en otros casos, solo podríamos especificar ciertas variables / campos, ciertos componentes de índices únicos, y recuperar una lista / conjunto de registros. En tales casos, podría ser más fácil, más lógico y razonable implementar las URL como QueryParams.

¿Podría una cadena hexadecimal larga diluir / disminuir el valor de las palabras clave en el resto de la ruta? Puede valer la pena la considerar las posibles implicaciones de SEO de colocar variables / valores en la ruta o en la consulta, y las implicaciones de la interfaz humana de si queremos que los usuarios puedan atravesar / explorar la jerarquía de las URL editando el contenido de la barra de direcciones. ¡Mi página 404 No encontrado utiliza variables SSI para redirigir automáticamente las URL rotas a sus padres! Los robots de búsqueda también pueden atravesar la jerarquía de rutas. Por otro lado, personalmente, cuando comparto URL en las redes sociales, elimino manualmente todos los identificadores únicos privados, generalmente truncando la consulta de la URL, dejando solo la ruta: en este caso, hay alguna utilidad para colocar identificadores únicos en la ruta en lugar de en la consulta. Si queremos facilitar el uso de componentes de ruta como una interfaz de usuario en bruto, tal vez depende de si los datos / componentes son legibles por humanos o no. La cuestión de la legibilidad humana se relaciona un poco con la cuestión de la jerarquía: a menudo, los datos que pueden expresarse como palabras clave legibles por humanos también son jerárquicos; mientras que los datos jerárquicos a menudo se pueden expresar como palabras clave legibles por humanos. (Los propios motores de búsqueda pueden definirse como un aumento del uso de URL como interfaz de usuario). Las jerarquías de palabras clave o directivas pueden no estar estrictamente ordenadas, pero generalmente son lo suficientemente cercanas como para que podamos cubrir casos alternativos en el camino, yetiquete una opción como el caso "canónico" .

Hay fundamentalmente varios tipos de preguntas que podemos responder con la URL para cada solicitud:

  1. ¿Qué tipo de registro / cosa estamos solicitando / sirviendo?
  2. ¿En cuál (es) estamos interesados?
  3. ¿Cómo queremos presentar la información / registros?

Es casi seguro que la Q1 está mejor cubierta por la ruta o por PathParams. Q3 (que probablemente se controla mediante un conjunto de parámetros opcionales ordenados arbitrariamente y valores predeterminados); es casi seguro que mejor cubierto por QueryParams. P2: Depende ...

Matthew Slyman
fuente
2

Puede admitir parámetros de consulta y parámetros de ruta, por ejemplo, en el caso de la agregación de recursos, cuando la recopilación de subrecursos tiene sentido por sí sola.

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

Los parámetros de consulta pueden admitir subconjuntos jerárquicos y no jerárquicos; Los parámetros de ruta son jerárquicos solamente.

Los recursos pueden exhibir múltiples jerarquías. Admita rutas cortas si va a consultar subcolecciones amplias que cruzan límites jerárquicos.

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

Utilice parámetros de consulta para combinar jerarquías ortogonales.

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

Utilice solo parámetros de ruta en el caso de la composición: cuando un recurso no tiene sentido divorciarse de su padre y la colección global de todos los hijos no es un recurso útil en sí mismo.

/words/{id}/definitions
/definitions?word=id   // not useful
Steve Mitchell
fuente
1

La razón es realmente muy simple. Al utilizar un parámetro de consulta, puede incluir caracteres como "/" y su cliente no necesita codificarlos en html. Hay otras razones, pero ese es un ejemplo simple. En cuanto a cuándo usar una variable de ruta. Yo diría que siempre que se trate de identificadores o si la variable de ruta es una dirección para una consulta.

Tony
fuente
1

Estoy dando un ejemplo a underand y cuando usamos @Queryparamy@pathparam

Por ejemplo, estoy tomando un recurso es carResourceclase

Si desea que las entradas de su método de recursos sean manejables, use el tipo de parámetro como @pathaparam, si las entradas de su método de recursos deben ser opcionales, mantenga ese tipo de @QueryParamparámetro como parámetro

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

Para este recurso pase la solicitud

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

Si da una solicitud como esta, el recurso le dará el modelo y el color del automóvil basado

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

Si da una solicitud como esta, el método de recurso mostrará solo un automóvil basado en un modelo rápido

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

Si da así, obtendremos la excepción ResourceNotFound porque en la clase de recursos del automóvil, declare carmodel, ya @pathPramque debe y debe dar el carmodel como reQ uri, de lo contrario no pasará la solicitud de recursos, pero si no pasa el color también pasará la solicitud al recurso por qué porque el color @quetyParames opcional en la solicitud.

DB5
fuente
0
  1. @QueryParam se puede usar convenientemente con la anotación de Valor predeterminado para que pueda evitar una excepción de puntero nulo si no se pasa ningún parámetro de consulta.

Cuando desee analizar los parámetros de consulta de una solicitud GET, simplemente puede definir el parámetro respectivo para el método que manejará la solicitud GET y anotarlos con @QueryParamanotaciones

  1. @PathParamextrae los valores de URI y coincide con @Path. Y por lo tanto obtiene el parámetro de entrada. 2.1 @PathParampuede ser más de uno y se establece en argumentos de métodos

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

En el ejemplo anterior
http://localhost:8080/Restr/rest/msg/{p0}/{p1},
p0coincide param1y p1coincide param2. Entonces, para el URI
http://localhost:8080/Restr/rest/msg/4/6,
obtenemos el resultado 10.

En el Servicio REST, JAX-RS proporciona @QueryParamy @FormParamambos para aceptar datos de una solicitud HTTP. Un formulario HTTP se puede enviar por diferentes métodos como GET y POST.

@QueryParam : Acepta la solicitud GET y lee los datos de la cadena de consulta.

@FormParam: Acepta la solicitud POST y obtiene datos del formulario HTML o cualquier solicitud de los medios

Amlesh Kumar
fuente
0

En pocas palabras,

@Pathparam funciona para el valor que pasa por Recursos y Cadena de consulta

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

@Queryparam funciona para el valor que pasa solo Cadena de consulta

  • /user?id=1
ArulRajP
fuente