Introducción a las URL (@Path)

Las URL o Paths de aquí en adelante son una de las partes fundamentes de todos los servicios REST, pues en esta arquitectura, solo puede existir un único recurso por URL, por lo que definir una estructura adecuada y simple es clave para el éxito de nuestra API.

 

NOTA: Este artículo es parte de un tutorial completo para crear API REST con JAX-RS, si quieres ver el índice completo entra aquí.

 

El path es conocido como la dirección URL que aparece en la que se encuentra un determinado recurso, por ejemplo, la página de google se encuentra en https://google.com mediante el Método GET, por lo que ninguna otra página podría existir en esa misma URL, porque estaría violando una de las principales reglas de REST. Así como no puede haber otra página en una misma URL, tampoco podría existir, por ejemplo, tener los datos de dos usuarios en la misma URL. Por ejemplo: https://miapi.com/users/1,  está URL nos dice que estamos buscando el usuario con ID = 1, por lo que sin importar que pase, los datos del usuario 1 siempre deberían estar en esa URL.

 

En JAX-RS, el Path se define como una expresión que se utilizará para identificar hacia qué servicios se debe de direccionar una llamada entrante al API. Para esto, tenemos la anotación @Path  del paquete javax.ws.rs  que nos permite definir la URL en que un determinado método responde. Veamos el siguiente ejemplo:

 

En este ejemplo, vemos el método findAllUsers  utilizado para obtener todos los usuarios del sistema, lo interesante en este método el valor de la anotación @Path , la cual indica que este servicio estará disponible en la URL /users. Por lo tanto, podríamos ejecutar nuestro servicio en una URL como la siguiente http:<host>:<port>/<app_context>/users.

En este punto el host y el puerto es más que obvio que es, por lo que no entraremos en detalle sobre estos. El <app_context> es la URL base que nos asigna el servidor de aplicación, el cual por lo general corresponde con el nombre del proyecto, y finalmente, el /users está dado por la anotación @Path .

 

 

Path Expressions

Con la finalidad de crear servicios para procesar determinadas solicitudes, es necesario crear expresiones que ayuden a JAX-RS a distinguir que método debe de procesar una solicitud determinada, es por ello que @Path  permite definir expresiones complejas, así convertir ciertas secciones de la URL en parámetros que podrán ser utilizados por los métodos para saber cómo procesar la solicitud.

Veamos un ejemplo, imaginemos que tenemos dos usuarios en la base de datos y requerimos poder consultarlos por medio del ID, una solución sería crear dos métodos con diferente URL, por ejemplo:

  • @Path(“users/1”)
  • @Path(“users/2”)

Los paths anteriores nos permitirían diferencia si queremos consultar el usuario 1 o el 2, sin embargo, esto no es una solución práctica, ya que, si tenemos 100 usuarios, deberíamos de tener 100 métodos con Path diferente, por ello, en lugar de eso, podemos utilizar las expresiones para indicar que ciertas partes de la URL son en realidad un parámetro, veamos el siguiente ejemplo:

 

Este ejemplo es mucho más sensato, pues ya no hay necesidad de tener un método para cada usuario y en su lugar, hemos definido en el Path la variable {userId} , la cual le indica a JAX-RS, que todo lo que venga después de /users/ deberá ser recuperado y luego inyectado en la variable userId  del método Java. La anotación @PathParam  se utiliza para indicarle a Java en que parámetro debe de inyectar el valor.

 

A pesar de que este nuevo @Path  funciona, tenemos un detalle, pues le estaríamos diciendo que aceptaría cualquier valor en el parámetro {userId} , pero el ID de los usuarios es numérico, entonces estaríamos a expensas de que nos manden un valor no numérico, y que la instrucción donde parseamos el valor a long  falla, por eso, es necesario protegernos un poco más y complementar la expresión para indicar que el parámetro solo recibe valores numéricos:

 

En este nuevo ejemplo, hemos actualizado el parámetro {userId}  del path para que se vea de la siguiente manera {userId : \\d+} , de esta forma, le indicamos que el parámetro debe de ser uno o más dígitos.

Mediante JAX-RS es posible crear complejas reglas basadas en expresiones regulares para que nuestros parámetros sean los más exactos posibles, sin embargo, no vamos a entrar a detalle sobre este tema, pues podríamos alargarnos muchísimo y mi objetivo es simplemente que sepas que tienes esta posibilidad.

 

A si como podemos tener una variable, podríamos tener todas las que sean necesarias, por ejemplo, que pasaría si requiere recuperar todos los códigos postales de un país, una ciudad y todas las colonias que hay dentro de un código postal determinado, aquí estaríamos hablando de 3 servicios que podrían estar en conflicto, veamos por qué:

 

  • CP país: /mexico
  • CP ciudad: /mexico/cancun
  • Colonias por CP: /mexico/cancun/80000

El primero me regresaría todos los códigos postales que están en México, el segundo, me regresaría todos los CP de la ciudad de Cancún, la cual pertenece a México, y finalmente, la tercera me debería indicar todas las colonias que están el CP 80000. El problema con estos Path es que todos comienzan con el País, lo que puede provocar que las URL colapsen, pero por suerte, en JAX-RS es muy simple saltarse este problema, veamos como quedarían los métodos para estos 3 servicios:

 

Como vemos en este ejemplo, podemos separar cada sección de la URL por medio de variables, y así reconocer cada sección de la URL por separado.

También es posible hacer cosas como la siguiente @Path(users/{company}-{id}) , en esta nueva modalidad, tenemos dos parámetros en la misma subsección de la URL, en la cual podemos buscar un usuario de una determinada empresa.

 

 

Contexto de los Paths

Hasta este punto hemos visto cómo utilizar la anotación @Path  sobre los métodos, sin embargo, también es posible implementarla a nivel de clase. Cuando un path es definido a nivel de clase, afecta a todos los métodos de la clase, anteponiendo el este path al que definamos en los métodos, por ejemplo, si tenemos una clase que tiene todos los servicios relacionados a usuarios, entonces podríamos definir el @Path(users)  a nivel de clase, para que, de este modo, todos los servicios de esta clase inicien con el path /users, veamos un ejemplo:

 

Lo primero que podemos observar es que varios métodos ya no requieren la anotación @Path , sino solo el método (verb) por el cual responden, por ejemplo, el método findAllUsers  lo podemos ejecutar directamente en la URL GET:/users, por que asume la URL del @Path  de la clase.Por otra parte, el método deleteUsers  estará disponible en la URL /users/{userId}, esto debido a que se concatena el @Path  de la clase con el del método.

 

 

Path de la aplicación

Adicional a la anotación @Path  existe otra llamada @ApplicationPath , la cual está un poco fuera de tema, pero vale la pena recordarla. Esta anotación se utiliza definir el Path base que TODA la aplicación tendrá, esta se implementa una clase independiente, por lo general en el paquete base de la app:

 

Esta anotación la analizamos en la sección “Creando un API REST en Java” al inicio de este tutorial.

 

Conclusiones

Como hemos podido constatar, JAX-RS es sumamente flexible a la hora de definir los paths, sin embargo, no hemos abordado aún los QueryParams, PathParams y HeaderParams, los cuales estaremos analizando más a detalle en las siguientes secciones de este tutorial.

4 thoughts to “Introducción a las URL (@Path)”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *