<?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-RS &#8211; Oscar Blancarte &#8211; Software Architecture</title>
	<atom:link href="https://www.oscarblancarteblog.com/tag/jax-rs/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.oscarblancarteblog.com</link>
	<description>Software Architect &#38; FullStack developer</description>
	<lastBuildDate>Fri, 03 Jul 2020 00:54:59 +0000</lastBuildDate>
	<language>es-MX</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.12</generator>

<image>
	<url>https://www.oscarblancarteblog.com/wp-content/uploads/2019/03/cropped-ob-32x32.png</url>
	<title>JAX-RS &#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[<p>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;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/21/valores-por-defecto-con-defaultvalue/">Valores por defecto con @DefaultValue</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/defaultvalues-1024x575.jpg" alt="Default Values con @DefaultValues" class="wp-image-2749"/></figure>



<p>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"><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><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>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><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>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>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 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>Podemos comprobar que se han retornado los primeros 10 resultados. </p>



<p>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 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>Conclusiones</h2>



<p>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>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/21/valores-por-defecto-con-defaultvalue/">Valores por defecto con @DefaultValue</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/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[<p>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;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/17/bean-params/">Bean Params con @BeanParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/beanparam-1024x575.jpg" alt="Bean Params con @BeanParam" class="wp-image-2736"/></figure>



<p>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"><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><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>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>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><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><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>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><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>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>Adicional, agregaremos la cookie token directamente desde el inspector de chrome:</p>



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



<p><br>Y obtendremos el siguiente resultado:</p>



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



<h2>Conclusiones</h2>



<p>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"/>
		<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/17/bean-params/">Bean Params con @BeanParam</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/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[<p>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;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/15/cookie-params-con-cookieparam/">Cookie params con @CookieParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/cookieparam-1024x575.jpg" alt="Cookie params con @CookieParam" class="wp-image-2728"/></figure>



<p>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"><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><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>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>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 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>Recuperar las Cookies con JAX-RS</h2>



<p>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>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>Establecer una nueva Cookie</h2>



<p>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>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 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>Conclusiones</h2>



<p>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"/>
		<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/15/cookie-params-con-cookieparam/">Cookie params con @CookieParam</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/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[<p>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;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/10/header-params-con-headerparam/">Header params con @HeaderParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/headerpram-1024x575.jpg" alt="Header params con @HeaderParam" class="wp-image-2720"/></figure>



<p>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"><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><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>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>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>Si ejecutamos el ejemplo anterior, podemos ver el siguiente resultado:</p>



<figure class="wp-block-image"><img 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>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>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><br>Ahora veamos una ejecución de prueba:</p>



<figure class="wp-block-image"><img 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>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>Agregar headres en la respuesta</h2>



<p>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>Conclusiones</h2>



<p>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"/>
		<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/10/header-params-con-headerparam/">Header params con @HeaderParam</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/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[<p>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;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/07/path-params-con-formparam/">Path params con @FormParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/formparam-1024x575.jpg" alt="" class="wp-image-2701"/></figure>



<p>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"><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>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>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>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>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>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>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>Probando el servicio</h2>



<p>Lo primero será abrir el la página HTML para verlo de la siguiente manera:</p>



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



<p>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 src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/response.jpg" alt="" class="wp-image-2705"/></figure>



<p>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>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>Conclusiones</h2>



<p>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>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>
		<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/07/path-params-con-formparam/">Path params con @FormParam</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/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[<p>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;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/03/java-query-param/">Query params con @QueryParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/queryparam-1024x575.jpg" alt="" class="wp-image-2684"/></figure>



<p>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><br><br></p>



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



				
<blockquote class="wp-block-quote"><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><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><em>http://myapi.com/customers?<strong>name=oscar</strong></em></p>



<p><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>http://myapi.com/customers?<strong>firstname=oscar</strong>&amp;l<strong>astname=blancarte</strong>&amp;<strong>status=active</strong></p>



<p><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>Recuperar los Query params con JAX-RS</h2>



<p>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>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><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>Veamos ahora un ejemplo del ejecución de este método:</p>



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



<p>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>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>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><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 src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoke2-1024x599.jpg" alt="" class="wp-image-2695"/></figure>



<p>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>Conclusiones</h2>



<p>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>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"/>
		<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/03/java-query-param/">Query params con @QueryParam</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/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>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[<p>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;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/05/entendiendo-los-metodos-http-jax-rs/">Entendiendo los métodos HTTP (JAX-RS)</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 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 loading="lazy" 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>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/05/entendiendo-los-metodos-http-jax-rs/">Entendiendo los métodos HTTP (JAX-RS)</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/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[<p>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;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/03/metodos-http-rest/">Métodos HTTP (REST)</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 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" 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" 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" 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" 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" 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>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/03/metodos-http-rest/">Métodos HTTP (REST)</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/03/metodos-http-rest/feed/</wfw:commentRss>
			<slash:comments>47</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2389</post-id>	</item>
		<item>
		<title>Creando un API REST en Java (parte 1)</title>
		<link>https://www.oscarblancarteblog.com/2018/06/25/creando-un-api-rest-en-java-parte-1/</link>
					<comments>https://www.oscarblancarteblog.com/2018/06/25/creando-un-api-rest-en-java-parte-1/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Mon, 25 Jun 2018 16:51:59 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaEE]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2081</guid>

					<description><![CDATA[<p>Sin lugar a duda, los servicios REST ya se han convertido en la principal tecnología para construir servicios, superando con creces a los servicios SOAP o comúnmente conocidos como Web Services. A pesar de que REST ya es visiblemente la tendencia en el desarrollo de servicios, sigue existiendo una gran discusión acerca de si SOAP [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/06/25/creando-un-api-rest-en-java-parte-1/">Creando un API REST en Java (parte 1)</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/06/jax-rs-1-1024x575.jpg" alt="Creando un API REST en Java (parte 1)" class="wp-image-2408"/></figure></div>



<p>Sin lugar a duda, los servicios REST ya se han convertido en la principal tecnología para construir servicios, superando con creces a los servicios SOAP o comúnmente conocidos como Web Services. A pesar de que REST ya es visiblemente la tendencia en el desarrollo de servicios, sigue existiendo una gran discusión acerca de si SOAP es mejor que REST o al revés, sin embargo, no quiera tocar este tema ahora, pues no es el tema central de este artículo, para eso he creado el artículo “<a href="https://www.oscarblancarteblog.com/2017/03/06/soap-vs-rest-2/">SOA vs REST</a>” donde discutimos sobre estas dos tecnologías y sus ventajas y desventajas.</p>



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



<blockquote class="wp-block-quote"><p>NOTA: Este artículo es parte de un tutorial completo para crear API REST con JAX-RS,&nbsp;<a href="https://www.oscarblancarteblog.com/api-rest-java-jax-rs/">si quieres ver el índice completo entra aquí</a>.</p></blockquote>



<p>Antes de comenzar, te cuento que puedes descargar el código completo en&nbsp;<a href="https://github.com/oscarjb1/blog-tutorial-jaxrs/tree/master/M%C3%A9todos%20HTTP/api" target="_blank" rel="noopener noreferrer">https://github.com/oscarjb1/blog-tutorial-jaxrs/tree/master/M%C3%A9todos%20HTTP/api</a></p>



<h2>Configurando el proyecto</h2>



<p>Dicho este, pasemos ahora si a implementar un API REST con Java, para esto, será indispensable crear un proyecto de tipo WEB en tu IDE favorito, en este caso, vamos a crear un “Dynamic web project” en Eclipse, para esto nos dirigimos a file -&gt; new -&gt; Other en el menú superior:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/06/1-dynamic-web-project.jpg" alt="" class="wp-image-2084"/></figure></div>



<p>Seleccionamos la opción Dynamic web Project y presionamos Next para iniciar con la configuración de la aplicación:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/06/2-configure-project.jpg" alt="" class="wp-image-2085"/></figure></div>



<p>Una vez aquí, escribimos “<em>api</em>” como nombre del proyecto y seleccionamos nuestro servidor de aplicaciones de preferencia, en nuestro caso, utilizamos Wildfly 11 pero podrías utilizar cualquier otro que tengas disponible. Finalmente, presionamos “<em>Finish</em>” para concluir con la creación del proyecto. El siguiente paso será convertir nuestro proyecto a un proyecto Maven, con la finalidad de administrar más fácilmente nuestras librerías. Para ello, nos posicionaremos sobre el proyecto creado y presionaremos “<em>click derecho</em>“ para abrir las opciones del proyecto, estando allí, nos dirigimos a <em>configure -&gt; convert to Maven Project</em>, tras presionar esto, saldrá una ventana para configurar el proyecto, a lo que simplemente daremos finalizar.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/06/3-proyecto-creado.jpg" alt="" class="wp-image-2086"/></figure></div>



<p>Tras realizar los pasos anteriores deberás ver el proyecto tal y como se ve en la imagen anterior. Podrás observar una pequeña “M” en el ícono del proyecto, señal de que se trata de un proyecto Maven.</p>



<p>El siguiente paso es configurar las librerías de JavaEE y Wildfly con la finalidad de que estén disponibles en nuestro proyecto, por lo que tendremos que ir al archivo pom.xml y agregar las siguientes dos librerías: </p>



<pre class="wp-block-code"><code lang="" class=" line-numbers">&lt;dependency> 
    &lt;groupId>javax&lt;/groupId> 
    &lt;artifactId>javaee-api&lt;/artifactId> 
    &lt;version>7.0&lt;/version> 
    &lt;scope>provided&lt;/scope> 
    &lt;type>jar&lt;/type> 
&lt;/dependency> 
&lt;dependency> 
    &lt;groupId>org.wildfly.core&lt;/groupId> 
    &lt;artifactId>wildfly-server&lt;/artifactId> 
    &lt;version>2.2.0.Final&lt;/version> 
    &lt;scope>provided&lt;/scope> 
&lt;/dependency></code></pre>



<p>Guardamos los cambios y tendremos que esperar un momento hasta que Eclipse descarga todas las dependencias necesarias, para esto, verás un indicador de progreso en la parte inferior derecha de Eclipse. Una vez que ha finalizado, estamos listos para empezar a desarrollar.</p>



<h2>Iniciando el desarrollo</h2>



<p>Lo primero que debemos de hacer para iniciar nuestra API REST es indicarle el Path base desde el cual estará respondiendo nuestra API. Este path corresponde a la URL a partir de la cual se expondrá nuestros servicios. Para lograr esto, será necesario crear una clase que extienda de “Application”, esta clase puede llamarse como sea y puede colocarse en cualquier paquete, lo único importante es que extienda de Application y defina la anotación <code>@ApplicationPath</code>. En nuestro caso crearemos la clase <code>RestApplication</code> en el package api. </p>



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

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

@ApplicationPath("/") 
public class RestApplication extends Application { 
}</code></pre>



<p>Como podemos ver, hemos definido “/” como URL base, es decir que los servicios responderán a partir de la raíz del proyecto, pero tu podrías remplazarla por la URL base que más te guste, como por ejemplo “/api” o “/services”.</p>



<p>El siguiente paso será crear nuestro primer servicio, para lo cual deberemos crear una nueva clase, en este caso, crearemos la clase <code>HelloWorldRest</code> en el mismo paquete:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">package api; 
import javax.ws.rs.Consumes; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 

@Path("/helloworld") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public class HelloWorldRest {               

    @GET  
    public Response sayHello() {     
        return Response.ok("Hello World desde el API REST",MediaType.APPLICATION_JSON).build();   
    } 
}</code></pre>



<p>Como podrás observar, esta es una clase común y corriente pero que tiene algunas anotaciones, las cuales serán reconocidas por el servidor de aplicaciones para finalmente exponer el servicio, analicemos para que esta cada una de ellas.</p>



<p>La anotación <code>@Path</code> indica la URL en la cual responderá este servicio, cabe mencionar que esta anotación se puede poner a nivel de clase y método, en este caso, al estar a nivel de clase, afecta a todos los servicios que definamos, pero eso lo vamos a analizar más adelante.</p>



<p>Las siguientes dos anotaciones son para indicar que tipo de mensaje esperamos como entrada (consumes) y que tipo de mensaje vamos a responder (produces). En este caso, estamos indicando que esperamos JSON como entrada y que vamos a responder igualmente con JSON.</p>



<p>Finalmente, siguen los métodos, una clase puede tener más de un método, y cada método se puede exponer como un servicio independiente, sin embargo, en esta primera introducción empezaremos con uno. La anotación <code>@GET</code> le indica al servidor de aplicaciones que el método responde por el método GET únicamente. Adicional tenemos anotaciones para los demás métodos, como <code>@POST</code>, <code>@PUT</code>, <code>@DELETE</code>, etc. pero estos los estaremos analizando más adelante.</p>



<p>Podrás observar que el método responde con un tipo llamado Response, esta es una clase de utilidad que nos proporciona el API de JAX-RS para convertir fácilmente un objeto en un JSON en nuestro caso. Esta clase nos proporciona el método ok, el cual nos crea una respuesta con status 200, es decir, respuesta exitosa, la cual recibe el mensaje que queremos responder y el tipo de datos del mensaje, en nuestro caso JSON.</p>



<h2>Probando nuestro Hello World</h2>



<p>En este punto hemos terminado nuestro primer servicio, por lo que solo resta desplegarlo y probarlo. Para desplegarlo, basta con presionar el click derecho sobre el proyecto y presionar Run As -&gt; Run on Server, presionar siguiente y finalizar.</p>



<p>Si la aplicación desplego correctamente, podremos probar el servicio en la URL <a href="http://localhost:8080/api-0.0.1-SNAPSHOT/helloworld">http://localhost:8080/api-0.0.1-SNAPSHOT/helloworld</a>, esta URL la podrás ejecutar directamente sobre el navegador:</p>



<p>En este punto te estarás preguntando como es que se generó esta URL, por lo que explico a continuación:</p>



<p>La URL se forma con la siguiente formula: &lt;server_path&gt;:&lt;port&gt;/&lt;app_context&gt;/&lt;app_path&gt;/&lt;service_path&gt;</p>



<p>La sección &lt;server_path&gt; y &lt;port&gt; corresponde al host del servidor y el puerto en el cual responde, esto corresponde a Wildfly.</p>



<p>La sección &lt;app_context&gt; corresponde a la URL base que nos asigna el servidor de aplicaciones cuando desplegamos.</p>



<p>La sección &lt;app_path&gt; fue la que definimos en la anotación <code>@ApplicationPath</code>. En nuestro caso, al definirla como “/” quiere decir que responderá a partir de la raíz del proyecto.</p>



<p>Finalmente, &lt;service_path&gt; corresponde a la URL definida en la anotación <code>@Path</code>, la cual se definió como “helloworld”.<br><br></p>



<div class="wp-block-image"><figure class="aligncenter"><a href="https://codmind.com/courses/api-rest-con-spring-boot" target="_blank" rel="noreferrer noopener"><img loading="lazy" width="800" height="450" src="https://www.oscarblancarteblog.com/wp-content/uploads/2019/08/banner-lg.jpg" alt="" class="wp-image-3146" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2019/08/banner-lg.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2019/08/banner-lg-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2019/08/banner-lg-768x432.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>Te invito a que veas mi curso Mastering API REST con Spring Boot</figcaption></figure></div>



<h2>Conclusiones</h2>



<p>Hasta este punto hemos aprendido a crear un proyecto web y configurarlo para que responda a nuestras solicitudes como un API REST, por lo que en la siguiente sección de esta guía aprenderemos a utilizar los demás métodos (POST, DELETE, PUT) y aprenderemos a configurar nuestras URL para responder a URL más complejas, por lo que te invito a que te suscribas a mi blog para hacerte llegar las actualizaciones.</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/06/25/creando-un-api-rest-en-java-parte-1/">Creando un API REST en Java (parte 1)</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/06/25/creando-un-api-rest-en-java-parte-1/feed/</wfw:commentRss>
			<slash:comments>60</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2081</post-id>	</item>
	</channel>
</rss>
