<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>jax-ws &#8211; Oscar Blancarte &#8211; Software Architecture</title>
	<atom:link href="https://www.oscarblancarteblog.com/tag/jax-ws/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.oscarblancarteblog.com</link>
	<description>Software Architect &#38; FullStack developer</description>
	<lastBuildDate>Tue, 11 Dec 2018 16:00:51 +0000</lastBuildDate>
	<language>es-MX</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.11</generator>

<image>
	<url>https://www.oscarblancarteblog.com/wp-content/uploads/2019/03/cropped-ob-32x32.png</url>
	<title>jax-ws &#8211; Oscar Blancarte &#8211; Software Architecture</title>
	<link>https://www.oscarblancarteblog.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">89905023</site>	<item>
		<title>Introducción a las URL (@Path)</title>
		<link>https://www.oscarblancarteblog.com/2018/12/11/introduccion-a-las-url-path/</link>
					<comments>https://www.oscarblancarteblog.com/2018/12/11/introduccion-a-las-url-path/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Tue, 11 Dec 2018 16:00:51 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[jax-ws]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2460</guid>

					<description><![CDATA[<p>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. &#160; NOTA: Este artículo es parte de [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/11/introduccion-a-las-url-path/">Introducción a las URL (@Path)</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>				<img loading="lazy" class="aligncenter size-large wp-image-2462" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/jax-rs-path-1024x575.jpg" alt="" width="648" height="364">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.<span id="more-2460"></span></p>
<p>&nbsp;</p>
<blockquote><p>NOTA: Este artículo es parte de un tutorial completo para crear API REST con JAX-RS, <a href="https://www.oscarblancarteblog.com/api-rest-java-jax-rs/">si quieres ver el índice completo entra aquí</a>.</p></blockquote>
<p>&nbsp;</p>
<p>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, &nbsp;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.</p>
<p>&nbsp;</p>
<p>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 <span class="lang:default decode:true crayon-inline ">@Path</span>&nbsp; del paquete <span class="lang:default decode:true crayon-inline ">javax.ws.rs</span>&nbsp; que nos permite definir la URL en que un determinado método responde. Veamos el siguiente ejemplo:</p>
<pre class="lang:java decode:true">@GET
@Path("users")
public Response findAllUsers() {
    return Response.ok(userDao.getAllUsers()).build();
}</pre>
<p>&nbsp;</p>
<p>En este ejemplo, vemos el método <span class="lang:default decode:true crayon-inline ">findAllUsers</span>&nbsp; utilizado para obtener todos los usuarios del sistema, lo interesante en este método el valor de la anotación <span class="lang:default decode:true crayon-inline ">@Path</span>&nbsp;, la cual indica que este servicio estará disponible en la URL <em>/users</em>. Por lo tanto, podríamos ejecutar nuestro servicio en una URL como la siguiente <em>http:&lt;host&gt;:&lt;port&gt;/&lt;app_context&gt;/users</em>.</p>
<p>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 <em>&lt;app_context&gt;</em> 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 <em>/users</em> está dado por la anotación <span class="lang:default decode:true crayon-inline ">@Path</span>&nbsp;.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Path Expressions</h2>
<p>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 <span class="lang:default decode:true crayon-inline ">@Path</span>&nbsp; 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.</p>
<p>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:</p>
<ul>
<li>@Path(“users/1”)</li>
<li>@Path(“users/2”)</li>
</ul>
<p>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:</p>
<pre class="lang:java decode:true">@GET
@Path("users/{userId}")
public Response deleteUser( @PathParam("userId") String userId) {
    long parseUserId = Long.parseLong(userId);
&nbsp;&nbsp;&nbsp;&nbsp;User user = userDAO.findUserById(userId);
&nbsp;&nbsp;&nbsp;&nbsp;return Response.ok(user.build();
}</pre>
<p>&nbsp;</p>
<p>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 <span class="lang:default decode:true crayon-inline">{userId}</span>&nbsp;, la cual le indica a JAX-RS, que todo lo que venga después de <em>/users/</em> deberá ser recuperado y luego inyectado en la variable <span class="lang:default decode:true crayon-inline ">userId</span>&nbsp; del método Java. La anotación <span class="lang:default decode:true crayon-inline ">@PathParam</span>&nbsp; se utiliza para indicarle a Java en que parámetro debe de inyectar el valor.</p>
<p>&nbsp;</p>
<p>A pesar de que este nuevo <span class="lang:default decode:true crayon-inline ">@Path</span>&nbsp; funciona, tenemos un detalle, pues le estaríamos diciendo que aceptaría cualquier valor en el parámetro <span class="lang:default decode:true crayon-inline ">{userId}</span>&nbsp;, 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 <span class="lang:default decode:true crayon-inline ">long</span>&nbsp; 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:</p>
<pre class="lang:java decode:true">@GET
@Path("users/{userId : \\d+}")
public Response findUserById(@PathParam("userId") long userId) {
    System.out.println("userId ==&gt; " + userId);
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;User&gt; found = this.users.stream().filter(x -&gt; userId == x.getId().longValue()).collect(Collectors.toList());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//Throws error in case of the user not found
&nbsp;&nbsp;&nbsp;&nbsp;if(found.isEmpty()) return Response.status(Status.BAD_REQUEST).entity("User not found").build();
&nbsp;&nbsp;&nbsp;&nbsp;User userFound = found.get(0);
&nbsp;&nbsp;&nbsp;&nbsp;return Response.ok(userFound).build();
}</pre>
<p>&nbsp;</p>
<p>En este nuevo ejemplo, hemos actualizado el parámetro <span class="lang:default decode:true crayon-inline ">{userId}</span>&nbsp; del path para que se vea de la siguiente manera <span class="lang:default decode:true crayon-inline ">{userId : \\d+}</span>&nbsp;, de esta forma, le indicamos que el parámetro debe de ser uno o más dígitos.</p>
<p>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.</p>
<p>&nbsp;</p>
<p>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é:</p>
<p>&nbsp;</p>
<ul>
<li>CP país: /mexico</li>
<li>CP ciudad: /mexico/cancun</li>
<li>Colonias por CP: /mexico/cancun/80000</li>
</ul>
<p>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:</p>
<pre class="lang:java decode:true">@GET
@Path("{country}")
public Response findColonyByCP(
&nbsp;&nbsp;&nbsp; @PathParam("country") String country) {
}

@GET
@Path("{country}/{city}")
public Response findColonyByCP(
&nbsp;&nbsp;&nbsp; @PathParam("country") String country,
&nbsp;&nbsp;&nbsp; @PathParam("city") String city) {
}

@GET
@Path("{country}/{city}/{cp}")
public Response findColonyByCP(
&nbsp;&nbsp;&nbsp; @PathParam("country") String country,
&nbsp;&nbsp;&nbsp;&nbsp;@PathParam("city") String city,
&nbsp;&nbsp;&nbsp;&nbsp;@PathParam("cp") String cp) {
}</pre>
<p>&nbsp;</p>
<p>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.</p>
<p>También es posible hacer cosas como la siguiente <span class="lang:default decode:true crayon-inline ">@Path(“users/{company}-{id}”)</span>&nbsp;, 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.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Contexto de los Paths</h2>
<p>Hasta este punto hemos visto cómo utilizar la anotación <span class="lang:default decode:true crayon-inline ">@Path</span>&nbsp; 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 <span class="lang:default decode:true crayon-inline ">@Path(“users”)</span>&nbsp; a nivel de clase, para que, de este modo, todos los servicios de esta clase inicien con el path <em>/users</em>, veamos un ejemplo:</p>
<pre class="lang:java decode:true">@Path("/users")
@Consumes(value= MediaType.APPLICATION_JSON)
@Produces(value = MediaType.APPLICATION_JSON)
public class UserService {

    @GET
    public Response findAllUsers() {}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    @POST
    public Response createUser(User userRequest) {}

&nbsp;&nbsp;&nbsp;&nbsp;@PUT
&nbsp;&nbsp;&nbsp;&nbsp;public Response updateUser(User userRequest) {}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;@DELETE
&nbsp;&nbsp;&nbsp;&nbsp;@Path("{userId}")
&nbsp;&nbsp;&nbsp;&nbsp;public Response deleteUser( @PathParam("userId") long userId) {}

&nbsp;&nbsp;&nbsp;&nbsp;@GET
&nbsp;&nbsp;&nbsp;&nbsp;@Path("{userId : \\d+}")
&nbsp;&nbsp;&nbsp;&nbsp;public Response findUserById(@PathParam("userId") long userId) {}
}</pre>
<p>&nbsp;</p>
<p>Lo primero que podemos observar es que varios métodos ya no requieren la anotación <span class="lang:default decode:true crayon-inline ">@Path</span>&nbsp;, sino solo el método (verb) por el cual responden, por ejemplo, el método <span class="lang:default decode:true crayon-inline ">findAllUsers</span>&nbsp; lo podemos ejecutar directamente en la URL <em>GET:/users</em>, por que asume la URL del <span class="lang:default decode:true crayon-inline ">@Path</span>&nbsp; de la clase.Por otra parte, el método <span class="lang:default decode:true crayon-inline ">deleteUsers</span>&nbsp; estará disponible en la URL <em>/users/{userId}</em>, esto debido a que se concatena el <span class="lang:default decode:true crayon-inline ">@Path</span>&nbsp; de la clase con el del método.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Path de la aplicación</h2>
<p>Adicional a la anotación <span class="lang:default decode:true crayon-inline ">@Path</span>&nbsp; existe otra llamada <span class="lang:default decode:true crayon-inline ">@ApplicationPath</span>&nbsp;, 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:</p>
<pre class="lang:java decode:true">package api;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/")
public class RestApplication extends Application {

}</pre>
<p>&nbsp;</p>
<p>Esta anotación la analizamos en la sección “<a href="https://www.oscarblancarteblog.com/2018/06/25/creando-un-api-rest-en-java-parte-1/">Creando un API REST en Java</a>” al inicio de este tutorial.</p>
<p>&nbsp;</p>
<h2>Conclusiones</h2>
<p>Como hemos podido constatar, JAX-RS es sumamente flexible a la hora de definir los paths, sin embargo, no hemos abordado aún los <em>QueryParams</em>, <em>PathParams</em> y <em>HeaderParams</em>, los cuales estaremos analizando más a detalle en las siguientes secciones de este tutorial.		</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/11/introduccion-a-las-url-path/">Introducción a las URL (@Path)</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2018/12/11/introduccion-a-las-url-path/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2460</post-id>	</item>
	</channel>
</rss>
