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.
NOTA: Este artículo es parte de un tutorial completo para crear API REST con JAX-RS, si quieres ver el índice completo entra aquí.
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.
Uno de los principales usos de los header es para enviar los tokens de
autenticación, como es el caso de JSON Web Token (JWT), el cual lo establecemos en el header Authorization
, dicho lo anterior, veremos como recuperar este header mediante el API JAX-RS de Java.
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();
}
}
Los header pueden ser recuperados anotando los parámetros con @HaderParam
, por lo que vamos a requerir un parámetro en Java por cada header que esperamos recibir en el API.
Si ejecutamos el ejemplo anterior, podemos ver el siguiente resultado:
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.
Otra de las formas de recuperar los header es por medio de la clase HttpHeaders
, la cual podemos inyectar a nuestro método mediante la anotación @Context
. 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:
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();
}
}
Ahora veamos una ejecución de prueba:
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.
Agregar headres en la respuesta
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:
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();
}
}
Conclusiones
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.
Muy interesante este tema de los @HeaderParam, muchas gracias por compartirnos tus conocimientos.
Saludos Oscar.