<?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/"
	>

<channel>
	<title>REST &#8211; Oscar Blancarte &#8211; Software Architecture</title>
	<atom:link href="https://www.oscarblancarteblog.com/category/rest/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.oscarblancarteblog.com</link>
	<description>Software Architect &#38; FullStack developer</description>
	<lastBuildDate>Wed, 04 Sep 2019 19:11:27 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://www.oscarblancarteblog.com/wp-content/uploads/2019/03/cropped-ob-32x32.png</url>
	<title>REST &#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>Valores por defecto con @DefaultValue</title>
		<link>https://www.oscarblancarteblog.com/2019/01/21/valores-por-defecto-con-defaultvalue/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/21/valores-por-defecto-con-defaultvalue/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Mon, 21 Jan 2019 14:00:34 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2748</guid>

					<description><![CDATA[Es habitual que algunos de los parámetros de nuestros servicios sean opcionales para el cliente, lo que provocaría la llega de estos valores en null para nuestra API, lo que puede resultar un problema para algunos parámetros que son requeridos para el correcto funcionamiento del API y que al menos debemos de tener un valor [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/defaultvalues-1024x575.jpg" alt="Default Values con @DefaultValues" class="wp-image-2749"/></figure>



<p class="wp-block-paragraph">Es habitual que algunos de los parámetros de nuestros servicios sean opcionales para el cliente, lo que provocaría la llega de estos valores en null para nuestra API, lo que puede resultar un problema para algunos parámetros que son requeridos para el correcto funcionamiento del API y que al menos debemos de tener un valor por defecto en caso de no enviarse.<br></p>



<span id="more-2748"></span>



				
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><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 class="wp-block-paragraph"><br>Mediante la anotación <code>@DefaultValue</code> podemos establecer un valor por default a algunos de nuestros parámetros que son opcionales para el cliente, lo que evita que tengan un valor nulo al llegar al API. Esta característica es especialmente buena en casos en los que el API necesita que estos parámetros tengan algún valor a pesar que el cliente no lo envíe, pues dejarlos en null puede provocar el fallo del servicio.</p>



<p class="wp-block-paragraph">Imaginemos el siguiente ejemplo, tenemos que construir un servicios de consulta de clientes que permita paginar los resultados, por lo que el servicio deberá proporcionar la página actual y el número de registros esperados por página. En este ejemplo, podríamos imagina que si los valores no se definen, entonces el API debería de retornar todo, pero esto puede provocar un problema de performance, por que hay muchísimos clientes y cada cliente tiene una serie de objetos asociados que deberán ser retornados también, provocando una gran carga sobre la base de datos, es por ello, que debemos asegurarnos de que si el API no recibe estos parámetros entonces deberemos establecer un valor por default. Veamos el siguiente ejemplo:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">package api.services;

import java.util.*;
import javax.ws.rs.core.*;

@Path("customers")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class CustomersService {
	
	@GET
	public Response getCustomers(
			@DefaultValue("1") @QueryParam("currentPage") int currentPage, 
			@DefaultValue("10") @QueryParam("pageSize") int pageSize) {
		
		//Validate input
		if(currentPage &lt; 1 || pageSize &lt; 1) {
			return Response.ok("Invalid params").build();
		}
		
		//ccreate Dataset 
		List&lt;String> customers = new ArrayList&lt;>();
		for(int c = 1 ; c&lt;=100 ; c++) {
			customers.add("Customer " + c);
		}
		
		//Calculate sublist range
		int startIndex = (currentPage-1) * pageSize;
		int endIndex = startIndex + pageSize;
		
		//No more results
		if(startIndex >=customers.size()) {
			return Response.ok(new Object[0]).build();
		}
		
		//Prevent ArrayIndexOutOfBoundsException
		if(endIndex > customers.size()) {
			endIndex = customers.size();
		}
		
		//Getting sublist of elements
		List&lt;String> filters = customers.subList(startIndex, endIndex);
		
		return Response.ok(filters)
				.header("x-size", customers.size())
				.header("x-startIndex", startIndex)
				.header("x-endIndex", endIndex)
				.build();
	}	
}</code></pre>



<p class="wp-block-paragraph"><br>Para este ejemplo hemos definido que si el cliente no envía la página actual (<code>currentPage</code>) le daremos el valor de 1 por default, y para el tamaño de la página (<code>pageSize</code>) hemos definido el valor de 10. Esto quiere decir que en caso de que el cliente no envíe estos parámetros, regresaremos los 10 primeros registros.</p>



<p class="wp-block-paragraph">También hemos retornado los headers <code>x-size</code>, <code>x-startIndex</code>, <code>x-endIndex</code> como metadato para el cliente, para que sepa el total de los elementos, el index del primer registro y el último respectivamente.</p>



<p class="wp-block-paragraph">Veamos algunos ejemplos. En primer lugar probaremos ejecutar el servicio sin ninguno de los parámetros, para comprobar los valores por default:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test-sin-parametros.jpg" alt="probando los Default Values " class="wp-image-2751"/></figure>



<p class="wp-block-paragraph">Podemos comprobar que se han retornado los primeros 10 resultados. </p>



<p class="wp-block-paragraph">Hora probaremos únicamente con el parámetro pageSize=3, lo que establecerá la página por default en 1, regresando los primeros 3 resultados:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test-pagesize.jpg" alt="probando los Default Values 2" class="wp-image-2752"/></figure>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Conclusiones</h2>



<p class="wp-block-paragraph">Los valores por default son una excelente opción para lidiar con valores requeridos por el API, pero que nos obligatorios para el cliente, sin embargo, el echo de que tengamos valores por default, no significa que no debemos validar los parámetros, pues el cliente siempre podrá enviar valores no esperados por el API que provoquen una falla o en el peor de los casos, hacer una <a href="https://www.oscarblancarteblog.com/2016/11/15/sql-injection/">inyección SQL</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/01/21/valores-por-defecto-con-defaultvalue/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2748</post-id>	</item>
		<item>
		<title>Bean Params con @BeanParam</title>
		<link>https://www.oscarblancarteblog.com/2019/01/17/bean-params/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/17/bean-params/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Fri, 18 Jan 2019 00:17:13 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2735</guid>

					<description><![CDATA[Los bean params hacen referencia a la capacidad de JAX-RS para recibir como parámetro objetos complejos definidos por una clase, esta clase puede ser vista como un Data Transfer Object (DTO), la cual contiene una serie de propiedades recuperadas de varias partes del request, como el header, query, path y formulario. Los Beans params no [&#8230;]]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/beanparam-1024x575.jpg" alt="Bean Params con @BeanParam" class="wp-image-2736"/></figure>



<p class="wp-block-paragraph">Los bean params hacen referencia a la capacidad de JAX-RS para recibir como parámetro objetos complejos definidos por una clase, esta clase puede ser vista como un <a href="https://www.oscarblancarteblog.com/2018/11/30/data-transfer-object-dto-patron-diseno/">Data Transfer Object</a> (DTO), la cual contiene una serie de propiedades recuperadas de varias partes del request, como el header, query, path y formulario.<br><br></p>



<span id="more-2735"></span>



				
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><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 class="wp-block-paragraph"><br>Los Beans params no es una característica nativa del protocolo HTTP o la arquitectura REST, si no que JAX-RS la agrega para poder mapear todos los tipos de parámetros en una sola clase, la cual podríamos ver como un DTO que concentra en un solo punto todos los parámetros esperados. </p>



<p class="wp-block-paragraph">Para comprender mejor como funcionan los Beans params, imaginemos que tenemos un formulario para registrar nuevos clientes, este formulario enviara al servicio todos los campos al API por medio de <code>@FormParams</code>, también enviaremos como un header un token de autenticación, para identificar al usuario que está realizando la invocación, imaginemos que el cliente llego por medio de una campaña promocional, por lo que necesitamos saber si llego por facebook, google, etc. por lo que enviaremos un <code>@QueryParam</code> para saber de donde llego el cliente. </p>



<p class="wp-block-paragraph">Este caso, podríamos crear un parámetro en Java para uno de los parámetros esperados o podríamos crear una clase como la siguiente:</p>



<pre class="wp-block-code"><code>package api.services;

import javax.ws.rs.*;

public class CustomerDTO {
	@CookieParam("token") 
	private String token;

	@FormParam("firstname") 
	private String firstname; 
	
	@FormParam("lastname") 
	private String lastname;
	
	@FormParam("status") 
	private String status;
	
	@QueryParam("source")
	private String source;

	/* GET and SET */
}</code></pre>



<p class="wp-block-paragraph"><br>La clase <code>CustomerDTO</code> es en realidad una composición de variables que son recuperadas de varias partes de la petición. Solo en este caso hemos recuperado parámetros de las cookies (<code>@CookieParam</code>), form (<code>@FormParam</code>), query (<code>@QueryParam</code>), sin embargo, la idea de los <code>@BeanParam</code> es que se pueden utilizar cualquiera de las @xxxParam, lo que quiere decir que podemos utilizar:</p>



<ul class="wp-block-list"><li><a href="https://www.oscarblancarteblog.com/2018/12/17/path-params-con-pathparam/">@PathParam</a></li><li>@QueryParam</li><li>@MatrixParam</li><li>@CookieParam</li><li>@HeaderParam</li></ul>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">El siguiente paso es crear un método REST que reciba el <code>@BeanParam</code>:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("customers")
public class CustomersService {
	
	@POST
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response saveCustomer(@BeanParam CustomerDTO customer) {
		
		String result = String.format("firstname = %s, lastname = %s, status = %s, token = %s, source = %s", 
				new Object[]{customer.getFirstname(), 
						customer.getLastname(),
						customer.getStatus(), 
						customer.getToken(),
						customer.getSource()});
		
		return Response.ok(result).build();
	}	
}
</code></pre>



<p class="wp-block-paragraph"><br>El formulario con el que invocaremos el servicio REST es el siguiente:</p>



<pre class="wp-block-code lang:xhtml decode:true"><code>&lt;!DOCTYPE html>
&lt;html>
	&lt;body>
		&lt;p>Customer form&lt;/p>
	
		&lt;form action="http://localhost:8080/api-0.0.1-SNAPSHOT/customers?source=google" method="post">
			&lt;div>
				&lt;label for="firstname" style="display:inline-block; width: 100px;">Nombre&lt;/label>
				&lt;input id="firstname" type="text" name="firstname" />
			&lt;/div>
			&lt;div>
				&lt;label for="lastname" style="display:inline-block; width: 100px;">Apellido&lt;/label>
				&lt;input id="lastname" type="text" name="lastname" />
			&lt;/div>
			&lt;div>
				&lt;label for="status" style="display:inline-block; width: 100px;">Estatus&lt;/label>
				&lt;select id="status" name="status" >
					&lt;option value="active">Activo&lt;/option>
  					&lt;option value="inactive">Inactivo&lt;/option>
				&lt;/select>
			&lt;/div>
			&lt;br/>
			&lt;input type="submit" value="Guardar" />
		&lt;/form>
	&lt;/body>
&lt;/html></code></pre>



<p class="wp-block-paragraph">Observemos que hemos agregado el query param en el <code>action</code> del <code>&lt;form&gt;</code>, por lo que será enviado al servidor al momento del submit.</p>



<p class="wp-block-paragraph">Adicional, agregaremos la cookie token directamente desde el inspector de chrome:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test-3-1024x502.jpg" alt="@BeanParam cookie" class="wp-image-2739"/></figure>



<p class="wp-block-paragraph"><br>Y obtendremos el siguiente resultado:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/result-1.jpg" alt="@BeanParam test result" class="wp-image-2741"/></figure>



<h2 class="wp-block-heading">Conclusiones</h2>



<p class="wp-block-paragraph">Como hemos podido validar, los <code>@BeanParam</code> son una excelente estrategia para realizar una composición de una serie de parámetros en una sola fuente de datos, los cuales podríamos fácilmente reutilizar para más de un servicio. Además, nos evita tener que definir una serie de parámetros para poder recuperar cada uno de los valores esperados.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator"/>
		]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/01/17/bean-params/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2735</post-id>	</item>
		<item>
		<title>Cookie params con @CookieParam</title>
		<link>https://www.oscarblancarteblog.com/2019/01/15/cookie-params-con-cookieparam/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/15/cookie-params-con-cookieparam/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Tue, 15 Jan 2019 19:14:39 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2727</guid>

					<description><![CDATA[Las cookies son hasta la fecha una de las formas más utilizadas que tenemos para persistir valores del lado del cliente, las cuales pueden ser recuperadas por el servidor para identificar a un usuario, darle seguimiento o simplemente para guardar algún valor que utilizaremos después. Todas las cookies que guardemos en el cliente serán transmitidas [&#8230;]]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/cookieparam-1024x575.jpg" alt="Cookie params con @CookieParam" class="wp-image-2728"/></figure>



<p class="wp-block-paragraph">Las cookies son hasta la fecha una de las formas más utilizadas que tenemos para persistir valores del lado del cliente, las cuales pueden ser recuperadas por el servidor para identificar a un usuario, darle seguimiento o simplemente para guardar algún valor que utilizaremos después.<br><br></p>



<span id="more-2727"></span>



				
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><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 class="wp-block-paragraph"><br>Todas las cookies que guardemos en el cliente serán transmitidas al servidor de forma automática al servidor en los request posteriores, lo que puede ser de grán ayuda para identificar la sesión del usuario, el estado o incluso, guardar tokens de autenticación para identificar al usuario en cada llamada.</p>



<p class="wp-block-paragraph">Las cookies no es algo que podamos ver a simple vista, pues solo se pueden ver con ayuda de herramientas que monitoren el tráfico HTTP, como es el caso del inspector de elementos de Chrome u otras herramientas especializadas como es el caso de Restlet, SOAPUI, postman, etc.</p>



<p class="wp-block-paragraph">Desde chrome podemos ver todas las cookies que una página ha dejado en nuestro equipo, e incuso, podríamos agregar algunas manualmente para realizar algunas pruebas. Para verlas, solo basta abrir el inspector de elementos, dirigirse a la pestaña de Application y seleccionar la opción de cookies, tal como podemos ver en la siguiente imagen:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/cookies-chrome.jpg" alt="cookies Inspector de elementos con Chorme" class="wp-image-2729"/></figure>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Recuperar las Cookies con JAX-RS</h2>



<p class="wp-block-paragraph">Mediante el API de JAX-RS es muy fácil de recuperar las cookies del lado del servidor, ya que solo es necesario anotar con <code>@CookieParam</code> alguno de los parámetros del método Java en la cual queremos inyectar el valor de una cookie. Veamos el siguiente ejemplo que espera una cookie de autenticación llamado token:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("customers")
public class CustomersService {

	@POST
	@Produces(MediaType.TEXT_PLAIN)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response saveCustomer(
			@CookieParam("token") String token) {
		
		if("1234".equals(token)) {
			return Response.ok("OK").build();
		}else {
			return Response.ok("UNAUTHORIZED").status(Response.Status.UNAUTHORIZED).build();
		}
	}
}</code></pre>



<p class="wp-block-paragraph">En este ejemplo estamos el header <code>token</code>, el cual deberá tener el valor <code>1234</code>, de lo contrario, mandaremos un error de autenticación.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Establecer una nueva Cookie</h2>



<p class="wp-block-paragraph">Otra cosa que podemos hacer es establecer una nueva cookie en el cliente, por ejemplo, podríamos agregar el token en caso de que este no tenga uno, veamos cómo quedaría:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;
import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("customers")
public class CustomersService {

	@POST
	@Produces(MediaType.TEXT_PLAIN)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response saveCustomer(
			@CookieParam("token") String token) {
		
		if(token == null) {
			NewCookie newToken = new NewCookie("token", "1234");
			return Response.ok("OK").cookie(newToken).build();
		}
		
		return Response.ok("OK").build();
	}	
}</code></pre>



<p class="wp-block-paragraph">Utilizamos la clase <code>NewCookie</code> para definir una nueva cookie que deberá ser creada en el cliente, demás, utilizamos el método <code>cookie</code> de la clase Response para enviarla al cliente.</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/newtoken.jpg" alt="nuevo cookie" class="wp-image-2730"/></figure>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Conclusiones</h2>



<p class="wp-block-paragraph">A pesar de que las cookies han sido la forma tradicional de guardar los datos en el cliente, la llegada de HTML5 nuevas alternativas, como lo es el Local Storage y el Session Storage, de los cuales no hablaremos en esta ocasión, pero las menciono por si quieres investigar un poco más al respecto.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator"/>
		]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/01/15/cookie-params-con-cookieparam/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2727</post-id>	</item>
		<item>
		<title>Header params con @HeaderParam</title>
		<link>https://www.oscarblancarteblog.com/2019/01/10/header-params-con-headerparam/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/10/header-params-con-headerparam/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Fri, 11 Jan 2019 05:30:38 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2709</guid>

					<description><![CDATA[Los header son utilizados en REST para enviar metadatos asociados a la petición o la respuesta, los cuales van desde el formato y tamaño del payload, nombre del servidor del servidor de aplicaciones, fecha de invocación, caducidad de un recurso, versión y nombre del sistema operativo, tipo de navegador, dispositivo, lenguaje y hasta headers para [&#8230;]]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/headerpram-1024x575.jpg" alt="Header params con @HeaderParam" class="wp-image-2720"/></figure>



<p class="wp-block-paragraph">Los header son utilizados en REST para enviar metadatos asociados a la petición o la respuesta, los cuales van desde el formato y tamaño del payload, nombre del servidor del servidor de aplicaciones, fecha de invocación, caducidad de un recurso, versión y nombre del sistema operativo,  tipo de navegador, dispositivo, lenguaje y hasta headers para la seguridad.<br><br></p>



<span id="more-2709"></span>



				
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><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 class="wp-block-paragraph"><br>Los headers es una sección adicional al payload de una solicitud, la cual no puede ser vista a simple vista, si no que requiere de un analizador HTTP para poderlos ver, sin embargo, todas las solicitudes llevan por default una serie de headers, incluso si nosotros no  las establecemos. Los headers enviados por default varían de cliente a cliente y de servidor a servidor, por lo que en este artículo aprenderemos a analizar los headers.</p>



<p class="wp-block-paragraph">Uno de los principales usos de los header es para enviar los tokens de  <br>autenticación, como es el caso de<a href="https://www.oscarblancarteblog.com/2017/06/08/autenticacion-con-json-web-tokens/"> JSON Web Token</a> (JWT), el cual lo establecemos en el header <code>Authorization</code>, dicho lo anterior, veremos como recuperar este header mediante el API JAX-RS de Java.</p>



<pre class="wp-block-code"><code>package api.services;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("security")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class Security {
	
	@GET
	public Response authenticate(@HeaderParam("authorization") String token) {
		return Response.ok("token="+token).build();
	}
}</code></pre>



<p class="wp-block-paragraph">Los header pueden ser recuperados anotando los parámetros con <code>@HaderParam</code>, por lo que vamos a requerir un parámetro en Java por cada header que esperamos recibir en el API.</p>



<p class="wp-block-paragraph">Si ejecutamos el ejemplo anterior, podemos ver el siguiente resultado:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test-1-1024x625.jpg" alt="JAX-RS @HeaderParam recuperar un query param" class="wp-image-2721"/></figure>



<p class="wp-block-paragraph">En la parte superior podemos ver los header que definimos en el request y en la parte de abajo los header que nos retorno el servidor; en la respuesta podemos ver el token que le hemos enviado.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Otra de las formas de recuperar los header es por medio de la clase <code>HttpHeaders</code>, la cual podemos inyectar a nuestro método mediante la anotación <code>@Context</code>. La ventaja evidente de esté método es que podemos recuperar cualquier header, sin importar si lo esperábamos o no y nos evita tener que definir una grán cantidad de parámetros si esperamos muchos headers. Veamos un nuevo ejemplo con este método:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("security")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public class Security {
	
	@GET
	public Response authenticate (@Context HttpHeaders headers) {
		String result = "";
		for(Map.Entry entry: headers.getRequestHeaders().entrySet() ) {
			result += entry.getKey() + "=" + entry.getValue() + ", ";
		}
		
		return Response.ok(result).build();
	}
}</code></pre>



<p class="wp-block-paragraph"><br>Ahora veamos una ejecución de prueba:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test-2-1024x679.jpg" alt="JAX-RS @HeaderParam recuperar todos los query params" class="wp-image-2722"/></figure>



<p class="wp-block-paragraph">En este caso, podemos observar que hemos recibido muchos más parámetros de los que enviamos, y esto se debe a lo que mencionamos al inicio, y es que cada cliente agrega una serie de headers para identificarlo.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Agregar headres en la respuesta</h2>



<p class="wp-block-paragraph">Ademas de recibir headers, también podemos enviar headers a los clientes del API; los headers los podemos agregar directamente al objeto Response, mediante una serie de claves-valor, veamos un ejemplo:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;
import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("security")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public class Security {
		
	@GET
	public Response authenticate (@Context HttpHeaders headers) {
		String result = "";
		for(Map.Entry entry: headers.getRequestHeaders().entrySet() ) {
			result += entry.getKey() + "=" + entry.getValue() + ", ";
		}
		
		Response.ResponseBuilder response = Response.ok(result);
		response.header("my-header1", "value 1");
		response.header("my-header2", "value 2");
		
		return response.build();
	}
}</code></pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Conclusiones</h2>



<p class="wp-block-paragraph">No debemos de confundirnos al momento de utilizar los headers, pues no se deben de utilizar como una forma de enviar parámetros a nuestro API, si no como metadatos que complementen el request y que ayuden al servidor/cliente como tratar la solocitud/respuesta.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator"/>
		]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/01/10/header-params-con-headerparam/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2709</post-id>	</item>
		<item>
		<title>Path params con @FormParam</title>
		<link>https://www.oscarblancarteblog.com/2019/01/07/path-params-con-formparam/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/07/path-params-con-formparam/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Mon, 07 Jan 2019 20:22:07 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2699</guid>

					<description><![CDATA[Una de las cosas que pocos saben, es que REST nos permite crear servicios que se integren a la perfección con los formularios HTML, de tal forma que podemos lugar una etiqueta &#60;form&#62; directamente con un servicio REST. para ello, JAX-RS nos proporciona la anotación @FormParam. La diferencia fundamental que tienen los form params con [&#8230;]]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/formparam-1024x575.jpg" alt="" class="wp-image-2701"/></figure>



<p class="wp-block-paragraph">Una de las cosas que pocos saben, es que REST nos permite crear servicios que se integren a la perfección con los formularios HTML, de tal forma que podemos lugar una etiqueta <code>&lt;form&gt;</code> directamente con un servicio REST. para ello, JAX-RS nos proporciona la anotación <code>@FormParam</code>.</p>



<span id="more-2699"></span>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



				
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><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>
		


<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">La diferencia fundamental que tienen los form params con respecto a los demás, es que se obtiene directamente los campo asociados al formulario desde el cual se ejecuta, pero para entender mejor, veamos el siguiente ejemplo:</p>



<pre class="wp-block-code lang:xhtml decode:true"><code>&lt;html>
	&lt;body>
		&lt;p>Customer form&lt;/p>
		&lt;form action="http://localhost:8080/api-0.0.1-SNAPSHOT/customers" method="post">
			&lt;div>
				&lt;label for="firstname" style="display:inline-block; width: 100px;">Nombre&lt;/label>
				&lt;input id="firstname" type="text" name="firstname" />
			&lt;/div>
			&lt;div>
				&lt;label for="lastname" style="display:inline-block; width: 100px;">Apellido&lt;/label>
				&lt;input id="lastname" type="text" name="lastname" />
			&lt;/div>
			&lt;div>
				&lt;label for="status" style="display:inline-block; width: 100px;">Estatus&lt;/label>
				&lt;select id="status" name="status" >
					&lt;option value="active">Activo&lt;/option>
  					&lt;option value="inactive">Inactivo&lt;/option>
				&lt;/select>
			&lt;/div>
			&lt;br/>
			&lt;input type="submit" value="Guardar" />
		&lt;/form>
	&lt;/body>
&lt;/html></code></pre>



<p class="wp-block-paragraph">En este ejemplo debemos poner atención en la etiqueta <code>&lt;form&gt;</code>, la cual está apuntando a un servicios REST mediante la etiqueta <code>action</code>, con lo cual le estamos diciendo al navegador que envíe el formulario a nuestro servicio REST.</p>



<p class="wp-block-paragraph">Otra de las cosas a tomar en cuenta son los campos dentro del form, como lo son el nombre, apellido y estatus, los cuales serán los que sean enviados al servicio REST.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Una vez explicado lo anterior, pasemos a la implementación en JAX-RS para recuperar estos parámetros:</p>



<pre class="wp-block-code"><code>package api.services;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("customers")
public class CustomersService {

	@POST
	@Produces(MediaType.TEXT_PLAIN)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response saveCustomer(
			@FormParam("firstname") String firstname, 
			@FormParam("lastname") String lastname, 
			@FormParam("status") String status) {
		
		String result = String.format("firstname = %s, lastname = %s, status = %s", new String[]{firstname, lastname, status});
		return Response.ok(result).build();
	}
}</code></pre>



<p class="wp-block-paragraph">Veamos como hemos definido una anotación <code>@FormParam</code> para cada uno de los parámetros esperados del formulario, los cuales serán mapeados a cada uno de los parámetros del método en Java.</p>



<p class="wp-block-paragraph">Las anotaciones @Consumes la utilizamos definir que esperamos el payload como un formulario.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Probando el servicio</h2>



<p class="wp-block-paragraph">Lo primero será abrir el la página HTML para verlo de la siguiente manera:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/index.jpg" alt="" class="wp-image-2704"/></figure>



<p class="wp-block-paragraph">Una vez capturado el formulario, la damos grabar, lo que detonará el submit del formulario y la ejecución del servicio REST, lo que dará como resultado lo siguiente:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/response.jpg" alt="" class="wp-image-2705"/></figure>



<p class="wp-block-paragraph">Podemos ver como el servicio REST ha recibido todos los parámetros y los ha regresado como una cadena de texto.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Mediante la anotación <code>@FormParam</code> es fácil recuperar los valores de un formulario, pues los mapeamos a una parámetro especifico del método Java, sin embargo, esta forma tiene la limitación de que requerimos N parámetros en Java para mapear los N form params, lo que puede llegar a ser complicado en formularios grandes o donde los nombres de los parámetros pudieran variar, en tales casos, podemos implementarlos de la siguiente manera para recuperar todos los form params como un colección:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("customers")
public class CustomersService {
	
	@POST
	@Produces(MediaType.TEXT_PLAIN)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response getFormDataUsingMultivaluedMap(MultivaluedMap&lt;String, String> formParams) {
		String result = "";
		for(Map.Entry entry: formParams.entrySet() ) {
			result += entry.getKey() + "=" + entry.getValue() + ", ";
		}
		
		return Response.ok(result).build();
	}
}</code></pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Conclusiones</h2>



<p class="wp-block-paragraph">Los <code>@FormParam</code> pueden ser una buena alternativa cuando queremos ligar directamente un formulario con servicios REST, evitando tener que construir un request especifico. </p>



<p class="wp-block-paragraph">Como inconveniente, tenemos que el servicio REST deberá retornar la estructura HTML de la siguiente página que verá el usuario, o en su defecto, podemos redireccionar al usuario a la siguiente página.</p>
		]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/01/07/path-params-con-formparam/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2699</post-id>	</item>
		<item>
		<title>Query params con @QueryParam</title>
		<link>https://www.oscarblancarteblog.com/2019/01/03/java-query-param/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/03/java-query-param/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 03 Jan 2019 16:00:44 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2683</guid>

					<description><![CDATA[Otra de las formas que tenemos para enviar parámetros al API REST son los Query Params, los cuales son una serie de clave-valor que se agregan al final de la URL, justo después del signo de interrogación (?). Para comprender mejor que es un Query param a analizar la siguiente URL para consultar los clientes [&#8230;]]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/queryparam-1024x575.jpg" alt="" class="wp-image-2684"/></figure>



<p class="wp-block-paragraph">Otra de las formas que tenemos para enviar parámetros al API REST son los Query Params, los cuales son una serie de clave-valor que se agregan al final de la URL, justo después del signo de interrogación (<code>?</code>).</p>



<p class="wp-block-paragraph"><br><br></p>



<span id="more-2683"></span>



				
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><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 class="wp-block-paragraph"><br><br>Para comprender mejor que es un Query param a analizar la siguiente URL para consultar los clientes por medio del nombre:</p>



<p class="wp-block-paragraph"><em>http://myapi.com/customers?<strong>name=oscar</strong></em></p>



<p class="wp-block-paragraph"><br>El query param es la clave valor <code>name=oscar</code> que vemos al final de la URL, y como regla, siempre deberán estar después del símbolo de interrogación. Además, una URL puede tener N query params, cómo el siguiente ejemplo:</p>



<p class="wp-block-paragraph">http://myapi.com/customers?<strong>firstname=oscar</strong>&amp;l<strong>astname=blancarte</strong>&amp;<strong>status=active</strong></p>



<p class="wp-block-paragraph"><br>Esta URL la podemos utilizar para buscar a todos los clientes donde su nombre es oscar, su apellido es blancarte y su estatus es activo. Cuando utilizamos más de un Query param, es importante separar cada uno mediante el simbolo <code>&amp;</code>.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Recuperar los Query params con JAX-RS</h2>



<p class="wp-block-paragraph">Una vez explicado lo anterior, vamos a pasar a explicar como podemos recuperar los query params mediante el API JAX-RS de Java.</p>



<p class="wp-block-paragraph">La forma más simple de recuperar un Query param es anotar los parámetros de los métodos con <code>@QueryParam</code>, de tal forma que deberemos tener un parámetro por cada query param esperado. Veamos el siguiente ejemplo:</p>



<pre class="wp-block-code"><code>@GET
@Path("customers")
public Response getCustomers(
		@QueryParam("firstname") String firstname, 
		@QueryParam("lastname") String lastname, 
		@QueryParam("status") String status) {
	String result = String.format("firstname = %s, lastname = %s, status = %s", new String[]{firstname, lastname, status});
	return Response.ok(result).build();
}</code></pre>



<p class="wp-block-paragraph"><br>Podemos observar que hemos definido la anotación <code>@QueryParam</code> en cada parámetro sobre el cual queremos mapear el parámetro. </p>



<p class="wp-block-paragraph">Veamos ahora un ejemplo del ejecución de este método:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoke-1-1024x652.jpg" alt="" class="wp-image-2694"/></figure>



<p class="wp-block-paragraph">Como resultado podemos ver que hemos recibido los parámetros desde Java y devueltos como parte de la respuesta, lo que demuestra que hemos logrado mapear los query params con los parámetros del método Java.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">El ejemplo anterior es la forma más simple de recuperar los query params, sin embargo, tiene el inconveniente de que debemos definir un parámetro en Java para cada query param que esperamos recibir, lo que puede ser complicado si tenemos muchos o los nombre de los query params pueden variar, pues no tendremos forma de predecirlos para mapearlos a un parámetro en Java. </p>



<p class="wp-block-paragraph">Para solucionar estos casos tenemos la clase <code>UriInfo</code>, la cual debemos de inyectar al método en lugar de los <code>@QueryParam</code>, veamos el siguiente ejemplo:</p>



<pre class="wp-block-code"><code>@GET
@Path("customers2")
public Response getCustomers(
		@Context UriInfo uriInfo) {
	String result = "";
	for(Map.Entry entry: uriInfo.getQueryParameters().entrySet() ) {
		result += entry.getKey() + "=" + entry.getValue() + ", ";
	}
	return Response.ok(result).build();
}</code></pre>



<p class="wp-block-paragraph"><br>En este nuevo ejemplo podemos apreciar que hemos inyectado la clase UriInfo mediante la anotación <code>@Context</code> y por medio de esta clase podemos recuperar todos los query params, sin importar la cantidad que nos envíen e incluso si lo esperamos o no. La ventaja de este método es que podemos recuperar todos los query params como un <code>Set</code> e iterar todos los query params enviados.</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoke2-1024x599.jpg" alt="" class="wp-image-2695"/></figure>



<p class="wp-block-paragraph">Observemos en esta última prueba que hemos enviado los query params de siempre y hemos agregado el param date.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Conclusiones</h2>



<p class="wp-block-paragraph">Hemos comprobado lo fácil que es recuperar los query params con <code>@QueryParam</code>, he incluso, recuperarlos mediante la clase <code>UriInfo</code>, pero hay que tener cuidado al momento de utilizarlos, pues en muchos de los casos, podríamos pasar los parámetros mediante <code>@PathParam</code>. </p>



<p class="wp-block-paragraph">Por lo general, los <code>@QueryParam</code> se utilizan para complementar las búsquedas y los <code>@PathParam</code> para establecer el contexto de la búsqueda, es decir, mediante <code>@PathParam</code> decimos lo que estamos buscando y los <code>@QueryParam</code> como los queremos o los filtros de la selección.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator"/>
		]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/01/03/java-query-param/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2683</post-id>	</item>
		<item>
		<title>Path params con @PathParam</title>
		<link>https://www.oscarblancarteblog.com/2018/12/17/path-params-con-pathparam/</link>
					<comments>https://www.oscarblancarteblog.com/2018/12/17/path-params-con-pathparam/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Mon, 17 Dec 2018 16:00:30 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2515</guid>

					<description><![CDATA[Por increíble que parezca, en REST la URL puede proporcionar una de las principales fuentes de información para los servicios, pues es posible definir como parámetros de entrada ciertas parte de la URL, lo que nos permite en primer lugar, crear métodos especiales para atender ciertas URL, pero por otra parte, esos fragmentos de URL [&#8230;]]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/jaxrs-pathparams-1024x575.jpg" alt="JAX-RS Path params con @PathParams" class="wp-image-2522"/></figure>



<p class="wp-block-paragraph">Por increíble que parezca, en REST la URL puede proporcionar una de las principales fuentes de información para los servicios, pues es posible definir como parámetros de entrada ciertas parte de la URL, lo que nos permite en primer lugar, crear métodos especiales para atender ciertas URL, pero por otra parte, esos fragmentos de URL pueden ser inyectados como parámetros a los métodos Java.<br><br></p>



<span id="more-2515"></span>



<blockquote class="wp-block-quote is-style-default is-layout-flow wp-block-quote-is-layout-flow"><p>NOTA: Este artículo pertenece a una guia completa para aprender a crear un API REST con el API de JAX-RS de Java, ve el <a href="https://www.oscarblancarteblog.com/api-rest-java-jax-rs/">índice completo</a> aquí.</p><p></p></blockquote>



<p class="wp-block-paragraph"><br>Hace unos días escribía sobre la forma de escribir los Path y como podemos como podemos podíamos definir parámetros con la anotación <code>@Path</code>, puede regresara a la sección <a href="https://www.oscarblancarteblog.com/2018/12/11/introduccion-a-las-url-path/">Introducción a las URL con @Path</a> si quieres tener un poco más de contexto sobre lo que estaremos hablando esta sección.<br><br></p>



<h2 class="wp-block-heading">Definiendo un Path Param</h2>



<p class="wp-block-paragraph">No vamos a entrar en mucho detalle sobre como definir un parámetro desde <code>@Path</code> pues ya lo explicamos en una sección pasado, pero si repasaremos como se hacia.&nbsp;<br></p>



<pre class="wp-block-code"><code>@GET
@Path("/users/{userId}")
public Response findUserById(long userId) {}</code></pre>



<p class="wp-block-paragraph"><br>Como podemos apreciar en el fragmento de código anterior, es posible definir ciertas secciones de una URL como parámetros, encerrando entre llaves (<code>{userId}</code>) la parte que queremos recuperar como parámetro desde Java.&nbsp;<br><br></p>



<h2 class="wp-block-heading">Recuperar una Path Param con @PathParam</h2>



<p class="wp-block-paragraph">Ya que hemos definido todas secciones de parámetros dentro del <code>@Path</code>, lo que seguirá es recuperarlos desde el método Java para poderlos utilizar, para ello, debemos de establecer la anotación <code>@PathParam</code> en cada uno de los parámetros del método Java sobre el cual queremos inyectar el valor.</p>



<pre class="wp-block-code"><code>@GET
@Path("/users/{userId}")
public Response findUserById(@PathParam("userId") long user) {
    System.out.println("UserID ==> " + user);
}</code></pre>



<p class="wp-block-paragraph"><br>En el fragmento de código anterior, podemos apreciar como hemos establecido la anotación <code>@PathParam</code> para el parámetro <code>user</code>, el cual será inyectado con el valor del parámetro <code>userId</code> del <code>@Path</code>.<br><br></p>



<h2 class="wp-block-heading">Recuperar un Path param mediante UriInfo</h2>



<p class="wp-block-paragraph">La segunda forma de recuperar un Path param es mediante la interface <code>UriInfo</code>, la cual es una interface que contiene todos los metadatos relacionados con la URL. Al ser una interface no puede ser instanciada, por lo que deberá ser inyectada para ser utilizada, vamos como sería:</p>



<pre class="wp-block-code"><code>@GET
@Path("uriInfo/{param1}")
public Response getUriInfo(@Context UriInfo uriInfo) {
    String param1 = uriInfo.getPathParameters().getFirst("param1");
    return Response.ok(param1).build();
}</code></pre>



<p class="wp-block-paragraph"><br>La interface <code>UriInfo</code> proporciona el método <code>getPathParameters</code> que retorna una subclase de la interface <code>java.util.Map</code> con todos los parámetros, por lo que podemos iterar el nombre de los parámetros y sus valores, o podemos buscar directamente el valor de un parámetro mediante el método <code>getFist</code>.&nbsp;<br>Al ejecutar el método anterior deberíamos tener como resultado el valor del parámetro <code>param1</code>, vamos el resultado:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test.jpg" alt="" class="wp-image-2523"/></figure>



<h2 class="wp-block-heading">Conclusiones</h2>



<p class="wp-block-paragraph">Los Path params son indispensables para definir de forma clara los recursos de tu API, pues evita tener que agregar parámetros de tipo Query, los cuales hacen que las URL sean complejas y difíciles de recordar, ademas de que no son agradables para SEO.<br><br><br></p>
		]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2018/12/17/path-params-con-pathparam/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2515</post-id>	</item>
		<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[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;]]]></description>
										<content:encoded><![CDATA[<p>				<img fetchpriority="high" decoding="async" 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>
]]></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>
		<item>
		<title>Entendiendo los métodos HTTP (JAX-RS)</title>
		<link>https://www.oscarblancarteblog.com/2018/12/05/entendiendo-los-metodos-http-jax-rs/</link>
					<comments>https://www.oscarblancarteblog.com/2018/12/05/entendiendo-los-metodos-http-jax-rs/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Wed, 05 Dec 2018 16:00:32 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaEE]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2419</guid>

					<description><![CDATA[En la entrada pasada hablamos acerca de los métodos HTTP disponibles por JAX-RS, sin embargo, hay ocasiones en las que los métodos implementados por default no son suficientes y necesitamos agregar alguno adicional. &#160; NOTA: Este artículo es parte de un tutorial completo para crear API REST con JAX-RS, si quieres ver el índice completo [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>				<img decoding="async" class="aligncenter wp-image-2421 size-large" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/jax-rs-3-1024x575.jpg" alt="Entendiendo los métodos HTTP (JAX-RS)" width="648" height="364" />En la entrada pasada hablamos acerca de los métodos HTTP disponibles por JAX-RS, sin embargo, hay ocasiones en las que los métodos implementados por default no son suficientes y necesitamos agregar alguno adicional.<span id="more-2419"></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>Antes que nada, podrás encontrar todo el código fuente en GitHub: <a href="https://github.com/oscarjb1/blog-tutorial-jaxrs/tree/master/HTTP%20method%20extensions/api" target="_blank" rel="noopener">https://github.com/oscarjb1/blog-tutorial-jaxrs/tree/master/HTTP%20method%20extensions/api</a></p>
<p>&nbsp;</p>
<p>Para estos casos, JAX-RS nos ofrece la anotación <span class="lang:default decode:true crayon-inline ">@HttpMethod</span>  que nos sirve para crear un nuevo método, esta anotación la tendremos que implementar sobre una anotación personalizada. Digamos que requerimos implementar un nuevo método que nos permite bloquear un recurso para que cualquier otro consumidor del API no pueda modificarlo, para esto, podríamos crear un método HTTP llamado LOCK, veamos cómo quedaría:</p>
<pre class="lang:java decode:true" title="LOCK.java">package api.methods;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.ws.rs.HttpMethod;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("LOCK")
public @interface LOCK {

}
</pre>
<p>No quiero entrar en los detalles sobre como crear una anotación, pues no es el tema central de este artículo, pues lo que solo nos centraremos en lo que es realmente necesario para crear un nuevo método HTTP. Como vemos, hemos creado una nueva anotación llamada LOCK, esta a su vez, implementa la anotación <span class="lang:default decode:true crayon-inline ">@HttpMethod</span> , la cual recibe como parámetro el nombre del número método HTTP que vamos a implementar, en este caso &#8220;LOCK&#8221;.</p>
<p>&nbsp;</p>
<p>Finalmente, solo restaría implementar un método que implemente la interface <span class="lang:default decode:true crayon-inline ">@LOCK</span> :</p>
<pre class="lang:default decode:true" title="UserService.java">@LOCK
@Path("{userId}")
@Produces(MediaType.TEXT_PLAIN)
public Response lockUser() {
    return Response.ok("User loked").build();
}</pre>
<p>Como vemos, en el método anterior, solo debemos anotar la función con <span class="lang:default decode:true crayon-inline ">@LOCK</span>  y JAX-RS será lo suficientemente inteligente como para detectar que estamos utilizando el método HTTP LOCK.</p>
<p>&nbsp;</p>
<p>Una vez implementado, solo restaría probar que el servicio realmente funciona, para ello utilizamos Restlet para probar el servicio:</p>
<p><img decoding="async" class="aligncenter wp-image-2420 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/LOCK.jpg" alt="HTTP method extension LOCK" width="921" height="747" /></p>
<p>&nbsp;</p>
<p>Hay que tomar en cuenta que los métodos HTTP predefinidos en JAX-RS nos servirán para prácticamente para el 100% de los casos, por lo que no es recomendable implementar un método HTTP solo por hacerlo. Si bien, no es recomendable crear métodos HTTP solo por crearlo o por tener un método proprio, sí que hay dos casos donde se recomienda crear nuestros propios métodos:</p>
<ol>
<li>Cuando estamos creando alguno protocolo nuevo que requiera de la implementación de nuevos métodos.</li>
<li>Cuando alguna aplicación de terceros sobre la cual no tenemos control, nos solicite la creación de un servicio que responda en algún método determinado.</li>
</ol>
<p>&nbsp;</p>
<h2>Conclusiones</h2>
<p>Hemos visto como JAX-RS es lo bastante extensible para crear fácilmente nuevos métodos HTTP, aun que como ya vimos, debemos ser cuidados al momento de definir un nuevo método, pues crearlo solo por crearlo, puede ser un error que complique nuestra API.		</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2018/12/05/entendiendo-los-metodos-http-jax-rs/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2419</post-id>	</item>
		<item>
		<title>Métodos HTTP (REST)</title>
		<link>https://www.oscarblancarteblog.com/2018/12/03/metodos-http-rest/</link>
					<comments>https://www.oscarblancarteblog.com/2018/12/03/metodos-http-rest/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Mon, 03 Dec 2018 16:00:13 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaEE]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2389</guid>

					<description><![CDATA[Los métodos HTTP definen la acción que se realizará sobre un determinado recurso. Los métodos HTTP, también suelen ser llamados HTTP Verbs. Aunque el nombre correcto es Verbs, la realidad es que, en la práctica, casi siempre son llamados “métodos”, por lo que utilizaremos el nombre “métodos” para referirnos a ellos. &#160; NOTA: Este artículo [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>				<img loading="lazy" decoding="async" class="aligncenter wp-image-2406 size-large" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/jax-rs-2-1024x575.jpg" alt="Métodos HTTP (REST)" width="648" height="364" />Los métodos HTTP definen la acción que se realizará sobre un determinado recurso. Los métodos HTTP, también suelen ser llamados HTTP Verbs. Aunque el nombre correcto es Verbs, la realidad es que, en la práctica, casi siempre son llamados “métodos”, por lo que utilizaremos el nombre “métodos” para referirnos a ellos.<span id="more-2389"></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>Entender los métodos HTTP es fundamental para comprender la forma en que funciona la arquitectura REST, pues mediante los métodos le indicamos al servidor la forma en que debe de tratar una determinada petición, dicho esto, una misma URL puede ser tratada de forma diferente por el servidor.</p>
<p>&nbsp;</p>
<p>HTTP define una gran cantidad de métodos que son utilizados para diferentes circunstancias, por lo que trataremos de listar lo más relevantes y más utilizamos en la construcción de servicios REST, los métodos son los siguientes:</p>
<p>&nbsp;</p>
<ul>
<li><strong>GET:</strong> Es utilizado únicamente para <strong>consultar información</strong> al servidor, muy parecidos a realizar un SELECT a la base de datos. No soporta el envío del payload</li>
<li><strong>POST:</strong> Es utilizado para solicitar la <strong>creación de un nuevo registro</strong>, es decir, algo que no existía previamente, es decir, es equivalente a realizar un INSERT en la base de datos. Soporta el envío del payload.</li>
<li><strong>PUT</strong>: Se utiliza para <strong>actualizar por completo un registro existente</strong>, es decir, es parecido a realizar un UPDATE a la base de datos. Soporta el envío del payload.</li>
<li><strong>PATCH</strong>: Este método es similar al método PUT, pues permite actualizar un registro existente, sin embargo, este se utiliza cuando <strong>actualizar solo un fragmento del registro</strong> y no en su totalidad, es equivalente a realizar un UPDATE a la base de datos. Soporta el envío del payload</li>
<li><strong>DELETE</strong>: Este método se utiliza para <strong>eliminar un registro existente</strong>, es similar a DELETE a la base de datos. No soporta el envío del payload.</li>
<li><strong>HEAD</strong>: Este método se utilizar para <strong>obtener información sobre un determinado recurso</strong> sin retornar el registro. Este método se utiliza a menudo para probar la validez de los enlaces de hipertexto, la accesibilidad y las modificaciones recientes.</li>
</ul>
<p>&nbsp;</p>
<p>Hasta aquí los métodos más utilizados en la construcción de servicios REST con JAX-RS, sin embargo, existen algunos métodos más que son interesantes conocer, pues no los encontraremos al momento de depurar o analizar el tráfico de red.</p>
<ul>
<li><strong>CONNECT</strong>: Se utiliza para establecer una comunicación bidireccional con el servidor. En la práctica no es necesario ejecutarlo, si no el mismo API de HTTP se encarga de ejecutarlo para establecer la comunicación previo a lanzar alguna solicitud al servidor.</li>
<li><strong>OPTIONS</strong>: Este método es utilizado para describir las opciones de comunicación para el recurso de destino. Es muy utilizado con <a href="https://developer.mozilla.org/es/docs/Web/HTTP/Access_control_CORS">CORS</a> (Cross-Origin Resource Sharing) para validar si el servidor acepta peticiones de diferentes origines.</li>
</ul>
<p>&nbsp;</p>
<p>A pesar de que los métodos están diseñados para realizar ciertas acciones, la realidad es que <strong>nada impide que los utilices de forma errónea</strong>, es decir, fácilmente podrías utilizar el método DELETE para consultar o el POST para eliminar un recurso, si bien, el API funcionará, el desarrollador se volverá loco al intentar entender como funciona el API, es por este motivo que debemos entender y tener mucho cuidado en la forma en que implementamos los métodos.</p>
<p>&nbsp;</p>
<p>A pesar de que existe una gran cantidad de método HTTP, la implementación de JAX-RS solo implementa los que son realmente utilizados para crear servicios REST. Para implementar un método HTTP con JAX-RS solo es necesario anotar un método con cualquiera de las siguientes anotaciones del paquete <span class="lang:default decode:true crayon-inline">javax.ws.rs</span> :</p>
<ul>
<li>@GET</li>
<li>@POST</li>
<li>@PUT</li>
<li>@DELETE</li>
<li>@HEAD</li>
<li>@OPTION</li>
</ul>
<p>&nbsp;</p>
<p>Por ejemplo, para crear un servicio que retorne todos los Usuarios, podríamos crear un método como el siguiente:</p>
<pre class="lang:default decode:true">@GET
public Response findAllUsers() {
    List&lt;Users&gt; users = userDAO.getUsers();
    return Response.ok(users ).build();
}</pre>
<p>&nbsp;</p>
<p>Antes de comenzar, te cuento que puedes descargar el código completo en <a href="https://github.com/oscarjb1/blog-tutorial-jaxrs/tree/master/M%C3%A9todos%20HTTP/api" target="_blank" rel="noopener">https://github.com/oscarjb1/blog-tutorial-jaxrs/tree/master/M%C3%A9todos%20HTTP/api</a></p>
<p>&nbsp;</p>
<p>De la misma forma, podríamos crear cualquier otro método y anotarlo con el método que necesitemos. Para comprobar cómo funcionan los métodos, vamos a crear un servicio REST que nos permite tener las operaciones básicas para realizar un CRUD (Altas, Bajas, Cambio, Consulta en inglés).</p>
<pre class="lang:java decode:true " title="UserService.java">package api.services;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import api.domain.User;


@Path("/users")
@Consumes(value= MediaType.APPLICATION_JSON)
@Produces(value = MediaType.APPLICATION_JSON)
public class UserService {
	
	//User database pre-initialization
	private static final List&lt;User&gt; users = new ArrayList&lt;&gt;();
	
	static {
		users.add(new User(1L, "oscar", "1234"));
		users.add(new User(2L, "juan", "1234"));
		users.add(new User(3L, "maria", "1234"));
	}
	
	
	@GET
	public Response findAllUsers() {
		return Response.ok(this.users).build();
	}
	
	@POST
	public Response createUser(User userRequest) {
		userRequest.setId(users.size()+1l);
		this.users.add(userRequest);
		return Response.ok(userRequest).build();
	}
	
	@PUT
	public Response updateUser(User userRequest) {
		List&lt;User&gt; found = this.users.stream().filter(
                    x -&gt; userRequest.getId() == x.getId()).collect(Collectors.toList());
		
		//Throws error in case of the user not found
		if(found.isEmpty()) 
                    return Response.status(Status.BAD_REQUEST).entity("User not found").build();
		
		User updateUser = found.get(0);
		updateUser.setPassword(userRequest.getPassword());
		updateUser.setUsername(userRequest.getUsername());
		return Response.ok(updateUser).build();
	}
	
	@DELETE
	@Path("{userId}")
	public Response deleteUser( @PathParam("userId") long userId) {
		System.out.println("userId ==&gt; " + userId);
		List&lt;User&gt; found = this.users.stream().filter(
                    x -&gt; userId == x.getId().longValue()).collect(Collectors.toList());
		
		//Throws error in case of the user not found
		if(found.isEmpty()) 
                    return Response.status(Status.BAD_REQUEST).entity("User not found").build();
		
		User updateUser = found.get(0);
		this.users.remove(updateUser);
		return Response.noContent().build();
	}
	
	
	@HEAD
	public Response pingUsersService() {
		return Response.noContent().header("running", true).build();
	}
	
}

</pre>
<p>Como podrás apreciar, no estamos utilizando una base de datos real para guardar los cambios, pues no es el propósito en este punto, más bien, queremos enfocarnos en la forma en que los métodos son declarados, dicho esto, pasemos a analizar cómo funciona:</p>
<p>&nbsp;</p>
<h2>Inicialización del servicio</h2>
<p>En primer lugar, podemos apreciar que el servicio responde en el path <span class="lang:default decode:true crayon-inline">/users</span>, lo cual podemos comprobar en la anotación <span class="lang:default decode:true crayon-inline ">@Path</span>  a nivel de clase. Por el momento no profundizaremos en esto, pues más adelante tendremos una sección especial para explicar cómo funcionan los paths. Por otra parte, tenemos una lista llamada users, la cual utilizaremos como un sustituto a la DB para ir guardando los nuevos usuarios, actualizar o borrar los existentes. De entrada, iniciamos la lista con 3 usuarios.</p>
<p>Las anotaciones <span class="lang:default decode:true crayon-inline ">@Consumes</span>  y <span class="lang:default decode:true crayon-inline ">@Produces</span>  las utilizamos para indicar que él payload recibido y enviado como respuesta serán en formato JSON respectivamente. En otra sección de esta guía profundizaremos en el tema, por lo que por ahora no es necesario entender del todo esta parte.</p>
<p>&nbsp;</p>
<h2>Consulta de todos los usuarios (@GET)</h2>
<p>El método <span class="lang:default decode:true crayon-inline">findAllUsers</span> es utilizado fue desarrollado para retornar todos los usuarios que tengamos registrados. Como ya hablamos anteriormente, de inicio tendremos 3 usuarios precargados, por lo que podremos comprobar si realmente funciona. Para la prueba utilizaremos el plugin de Chrome llamado Restlet, pero podrías utilizar otros programas como SOAPUI.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-2390 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/GET.jpg" alt="Métodos HTTP GET" width="1021" height="802" /></p>
<p>En la imagen podemos apreciar claramente que, al ejecutar el servicio, este nos regresa un array con los 3 usuarios que se pre-cargaron.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Crear un nuevo usuario (@POST)</h2>
<p>De la misma forma en la que consultamos los usuarios existentes, podemos crear nuevos mediante el método POST. La única diferencia, es que es necesario enviarle en el payload el <span class="lang:default decode:true crayon-inline ">username</span>  y el <span class="lang:default decode:true crayon-inline ">password</span>  con el que se deberá crear, el ID será auto generado.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-2391 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/POST.jpg" alt="Métodos HTTP POST" width="918" height="747" /></p>
<p>Como resultado de la ejecución, tenemos un nuevo usuario creado, podemos comprobar que es nuevo por el ID que se va generando de forma secuencial.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Actualización de un usuario existente (@PUT)</h2>
<p>De la misma forma en que acabamos de crear un usuario, podemos actualizar sus datos mediante el método PUT. Para comprobar de que el usuario es actualizado, podremos observar que el ID del mismo no cambiara, y en su lugar, solo se actualizara el <span class="lang:default decode:true crayon-inline ">username</span>  y el <span class="lang:default decode:true crayon-inline ">password</span> . Como vamos a actualizar el registro, es necesario enviarle el ID como parámetro.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-2392 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/PUT.jpg" alt="Métodos HTTP PUT" width="919" height="744" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Eliminar un usuario (@DELETE)</h2>
<p>El caso del delete es un poco diferente, pues como este método no soporta enviarle el payload, es necesario enviarle el ID del usuario a eliminar de otra forma. En este caso, vamos a enviarle el ID como parte de la URL, es por ello, que agregaremos “<strong>/1</strong>” al final y agregaremos la anotación <span class="lang:default decode:true crayon-inline ">@PathParam</span>  para indicarle a JAX-RS como debe de recuperar el ID. Más adelante en otra sección de este tutorial analizaremos cómo funcionan estos parámetros, por ahora no nos preocupemos por esto.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-2393 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/DELETE.jpg" alt="Métodos HTTP DELETE" width="938" height="622" /></p>
<p>En este caso no hay necesidad de retornar nada, es por ello que vemos el mensaje de “NO CONTENT”.</p>
<p>&nbsp;</p>
<h2>Comprobar disponibilidad del servicio (@HEAD)</h2>
<p>Finalmente, validaremos si el servicio está activo realizando una petición HEAD, el cual nos regresará el header “running” si está actualmente en funcionamiento.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-2394 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/HEAD.jpg" alt="Métodos HTTP HEAD" width="941" height="687" /></p>
<p>&nbsp;</p>
<h2>Conclusiones</h2>
<p>Como hemos podido comprobar, crear servicios REST que respondan en los diferentes métodos es sumamente simple, y solo falta anotar el método con la anotación adecuada para crear un nuevo servicio. Solo quedo pendiente comprobar el funcionamiento del método OPTION (<span class="lang:default decode:true crayon-inline ">@OPTION</span> ) el cual tu podrías implementar como tarea.</p>
<p>&nbsp;		</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2018/12/03/metodos-http-rest/feed/</wfw:commentRss>
			<slash:comments>47</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2389</post-id>	</item>
	</channel>
</rss>
