Hoy vamos a ver como hacer un CRUD service básico con Apache Camel. Pero antes, comentemos un poco sobre Apache Camel:
- Es un framework de integración open source.
- Permite varias formas de configuración y desarrollo. Pero mayormente esta hecho en Java.
- Tiene un largo conjunto de componentes que permiten la integración con otros softwares.
- Se puede integrar y desplegar con ayuda de Spring boot, quarkus, de forma standalone y en la nube.
- Permite la transformación fácil de un formato a otro.
En este post veremos como hacer un sencillo REST service con Camel, Spring Boot y apoyandonos en REST DSL. Camel tiene varios DSL (lenguaje de dominio específico), los cuales permiten la configuración, el enroutado y la generación del servicio REST. En este servicio crearemos puntos de entrada, realizaremos determinada lógica y devolveremos el valor pertinente. Los datos los obtendremos de un mock de BBDD.
Para empezar debemos crear una clase que extienda de RouteBuilder y sobrescribir su método configure. Dentro de ese método tendremos que realizar dos tareas principales:
- Configurar el funcionamiento de los servicios REST a través de Apache Camel. Indicando el componente a utilizar (servlet, http-netty, jetty, etc), que producir (a través de bindingMode) y otros detalles.
- Crearemos los puntos de entrada (a través del método rest()). A partir de este punto de entrada podemos indicar el funcionamiento del servicio a crear.
- Con el método get() indicamos que vamos habilitar un servicio asociado a un método HTTP GET y con el contexto book.
- Con el método produces() indicamos que vamos a producir.
- Con el método router() vamos a redirigir el flujo.
- Con el método bean() podremos asociar que el mensaje sea tratado por objeto y método concreto.
restConfiguration().component("servlet").bindingMode(RestBindingMode.json_xml); rest().get("book").produces(MediaType.APPLICATION_JSON_VALUE).route()
.bean(DBMockRepository.class, "getAll(})");
Ya solo nos queda invocarlo y obtener el resultado:
curl --location --request GET 'http://localhost:9090/book' [{"id":1,"name":"Dune","author":"Frank Herbert"},
{"id":2,"name":"The stars my destination","author":"Alfred Bester"}]
Ahora veremos como hacer el método GET de un objeto concreto. Pero en este caso devolverá un objeto XML, solo para que veamos como hacerlo.
rest().get("book/{id}").description("Details of an book by id").outType(Book.class) .produces(MediaType.APPLICATION_XML_VALUE).route() .bean(DBMockRepository.class, "findById(${header.id})");
Aquí podemos dos nuevos métodos:
- description() con el cual podemos asociar una descripción no sólo al propio método en sí, sino también a los parámetros. Útil para documentar con mayor detalle el swagger asociado.
- outType() con el que podemos indicar el tipo de objeto de respuesta.
También podemos ver como pasar los path params al método de backend, a través de ${header}. Y como devolver en formato XML la respuesta. Para esto último debemos tener en cuenta dos cuestiones:
- Hay que indicar como dependencia la librería camel-jaxb (a igual que para JSON asociamos camel-jackson).
- El objeto de salida debe contener anotaciones de jaxb.
Ahora veremos un método POST y como podemos logar un mensaje:
rest().post("book").type(Book.class).produces(MediaType.APPLICATION_JSON_VALUE).route() .routeId("postBookRoute").bean(DBMockRepository.class, "create(${body})") .log("---creating a book---");
Este método post tendrá asociado un identificador de enrutado y podremos pasar el payload a través del parámetro ${body} al método de backend.
Por último veremos el método PUT, en el cual podremos validar los parámetros de entrada a través de los métodos simple() y otherwise(). Y como podremos devolver una respuesta apropiada a través del objeto Exchange.
@Override public void configure() throws Exception { // .... rest().put("book/{id}").type(Book.class).produces(MediaType.APPLICATION_JSON_VALUE).route().choice() .when().simple("${header.id} < 1").bean(BookRouter.class, "negativeId")
.otherwise().bean(DBMockRepository.class, "update(${header.id}, ${body})"); } public void negativeId(final Exchange exchange) { exchange.getIn().setBody("{\"msg\":\"id can not be negative\"}"); exchange.getIn().setHeader(Exchange.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400); }
Puedes ver todo el código aquí.
No hay comentarios:
Publicar un comentario