Ya hemos visto varios frameworks que nos pueden ayudar a crear un servicio web y su cliente. Hoy veremos RESTEasy que es un framework de JBoss, el cual ofrece una implementación para las especificaciones JAX-RS 2.0 y 2.1. Y como es normal, aunque esta pensado para una integración perfecta con WildFly, también nos ofrecerá la posibilidad de desplegarlo en cualquier otro contenedor de servlets como Tomcat o Jetty.
Empecemos con el Web Service, el cual será muy básico, lo necesario como para mostrar como poder montar uno más complejo. Lo primero será indicar cuales son las dependencias mínimas necesarias:
- resteasy-servlet-initializer
- resteasy-jackson2-provider
@ApplicationPath("/library") public class LibraryApplication extends Application { }
- @Path: Nos permite indicar un path común para todos los métodos.
- @POST, @GET, @DELETE o @PUT: Indica a que método HTTP esta asociado el método.
- @Produces, @Consume: Permite indicar que formato tendrá la entrada o salida. JSON o XML.
- @PathParam, @QueryParam: Permite indicar como recibiremos parámetros a través de la URL de invocación.
Si queremos devolver un objeto en un formato concreto no necesitaremos nada más que devolver dicho objeto. Pero si queremos devolver una respuesta más personalizada, donde indiquemos cookies, código de respuesta, etc, lo haremos a través del objeto javax.ws.rs.core.Response. Ejemplo:
@Path("/book") public class BookServiceImple { private static Map<Integer, Book> library = new HashMap<Integer, Book>(); static { library.put(1, new Book(1, "Ender's Game", "Orson S. Card")); library.put(2, new Book(2, "The stars my destination", "Alfred Bester")); } @POST @Path("/") @Produces({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON }) public Response create(final Book book) { if (null != library.get(book.getId())) { return Response.status(Response.Status.NOT_MODIFIED).entity("Book is already in the library.").build(); } library.put(book.getId(), book); return Response.status(Response.Status.CREATED).build(); } @GET @Path("/{id}") @Produces({ MediaType.APPLICATION_JSON }) public Book read(@PathParam("id") final Integer id) { if (library.containsKey(id)) { return library.get(id); } else { return null; } } }
Si queremos utilizarlo, deberemos invocar el comando Maven: clean package y desplegar el fichero .war generado en nuestro servidor de contenedores o aplicaciones favorito. Y ya podremos utilizarlo invocando el siguiente comando:
curl --location --request GET 'http://localhost:8080/RestEasyService/library/book/1'
Nuestro siguiente paso será crear el cliente. El cual podremos crearlo de dos formas diferentes, pero siempre haciendo uso de la clase de utilidad ResteasyClientBuilder. La cual cuenta con un método básico de creación del cliente pero que también aporta métodos para la configuración de dicho cliente, además de permitirnos crear un objeto de tipo WebTarget.
Una vez en este punto, podemos realizar la invocación del Web Service de dos formas diferentes. La primera de ellas, será algo más rudimentaria y necesitará de una mayor configuración para cada una de las llamadas, así como indicar la URL exacta a la hora de crear el objeto WebTarget. Este objeto nos permitirá hacer las llamadas REST correspondiente a través de sus métodos get() o post() e indicando que tipo de objeto vamos a recibir.
public class BookClient { final static String path = "http://localhost:8080/RestEasyService/library/"; public Book read_target(final Integer id) { Book retorno = null; WebTarget target = ClientBuilder.newClient().target(path + "book/" + id); try (Response response = target.request().get()) { retorno = response.readEntity(Book.class); } return retorno; } }
Para la segunda manera de crear el cliente utilizaremos el framework de RESTEasy Proxy. El cual nos permitirá realizar invocaciones más sencillas pero como punto negativo tendremos que crear una Interface que cumpla con el contrato del Web Service. El mayor inconveniente de esta interface es que tendremos que crearla manualmente a través de anotaciones JAX-RS, pero lo más positivo es podremos crear clientes de Web Services que no tienen porque haber sido generados a su vez por JAX-RS. Un ejemplo:
@Path("/book") public interface BookService { @POST @Path("/") @Produces({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON }) Response create(final Book book); @GET @Path("/{id}") @Produces({ MediaType.APPLICATION_JSON }) Book read(@PathParam("id") final Integer id); }
Para crear un objeto de tipo proxy, lo podremos obtener a través del objeto WebTarget, indicando la interfaz que tiene el contrato del Web Service. Para este caso no necesitaremos indicar la URL exacta de cada uno de los métodos y las invocaciones y tratamientos de la respuesta, la realizaremos de una forma más natural y comprensible.
public class BookClient { final static String path = "http://localhost:8080/RestEasyService/library/"; private static BookService proxy; static { WebTarget target = ClientBuilder.newClient().target(path); proxy = ((ResteasyWebTarget) target).proxy(BookService.class); } public Book read_proxy(final Integer id) { return proxy.read(id); } }
Con esto ya sabemos crear un Web Service y su cliente pero vamos a ver un último detalle importante como es la configuración a través de la clase MicroProfile Config.
Esta clase nos permitirá cumplir con la metodología de 12factor, permitiéndonos configurar el cliente o servicio a través de variables de entorno, propiedades del sistema o un fichero de configuración específico. A continuación veremos como podemos modificar la creación del cliente anterior para que obtenga la dirección del servicio a través de una variable de entorno.
static { Config config = ConfigProvider.getConfig(); String path = config.getValue("BOOKWS_URL", String.class); WebTarget target = ClientBuilder.newClient().target(path); proxy = ((ResteasyWebTarget) target).proxy(BookService.class); }
Por prioridad primero intentará obtener el valor de una propiedad del sistema, después de una variable del entorno y por último lo buscará en el fichero del classpath META-INF/microprofile-config.properties. Aunque estas valores de prioridad y orígenes de información también son configurables. Esto nos permitirá mantener el código de la aplicación inmutable en cada entorno en el cual despleguemos nuestra aplicación.
Y hasta aquí las nociones básicas para crear Web Services y clientes con el framework de JBoss. Si quieres puedes ver el código fuente aquí.
No hay comentarios:
Publicar un comentario