Quarkus: exponer una interfaz GraphQL

0
231

Crear un servidor de GraphQL con Quarkus es muy muy fácil. En este artículo veremos como crear una interfaz GraphQL en java, con sus queries, sus mutaciones, su esquema y con una interfaz gráfica que nos ayuda con todo eso.

Índice de contenidos

1. Introducción.

Estamos acostumbrados a usar API REST, pero empieza a ser cada vez más habitual que usemos otras opciones como gRPC o GraphQL.

En este caso veremos como exponer información a través de una interfaz GraphQL.

Este tipo de interfaces tienen algunas ventajas sobre REST:

  • tiene un schema, es tipado
  • puedes conocer facilmente los métodos que expone la API.
  • puedes pedir sólo los datos que necesitas
  • reduce número de peticiones y optimiza el uso de red

2. Antes de empezar

Partimos del ejercicio anterior con Quarkus, donde exponemos un API REST de la tabla periódica, que no deja de ser un CRUD de los de siempre.

Quarkus: como crear microservicio con REST y MongoDB

Como ahora, ya no tengo docker, necesito levantar un contenedor con un servidor de MongoDB.

Y lo voy a hacer con el equivalente OpenSource, podman, de licencia Apache 2.0.

Arrancamos la maquina de podman

y ejecutamos

Ya tenemos nuestro mongo arriba.

Si ejecutamos

levantamos el proyecto en modo desarrollo

Pero eso ya lo hemos hecho en la versión anterior.

3. Adiós API REST. Hola Interfaz GraphQL

Ahora lo que queremos es quitar los endpoint REST y dotar al microservicio de un API GraphQL

Para ello, quitaremos del POM

y añadiremos

En ElementResource anotaremos la clase con @GraphQLApi y expondremos las queries y las mutaciones que deseemos.

Empecemos por una query que nos dé un elemento químico por su símbolo

Simplemente, por haber anotado el resource con @GraphQLApi, y por haber anotado ese método con @Query, la implementación del microprofile de GraphQL, que en este caso es el sabor SmallRye, nos ha generado un esquema.

Si vamos a http://localhost:8080/q/graphql-ui nos ofrece una interfaz de usuario con las consultas y mutaciones que podemos hacer, y qué campos podemos pedir.

Interfaz de GraphQL con las consultas y mutaciones que podemos hacer

A la derecha, en «Docs» podemos consultar el schema que se va construyendo a medida que vamos añadiendo consultas.

4. Añadiendo test RestAssured

Antes de añadir consultas adicionales, vamos a familiarizarnos con esto de GraphQL. Y qué mejor manera que añadiendo algún test.

Al final una petición GraphQL no deja de ser una petición POST al endpoint /graphql

Lo primero de todo es que inyectamos un spy del servicio, para verificar que llamamos al método get().

Antes de cada test, en el @BeforeEach, mockeamos todas las entidades de mongodb, para no tener que levantarnos un testcontainer.

Pero por lo demás, este test no es un unitario aislado, si no que es colaborativo, ya que no está confinado a una única clase. Atraviesa todas las capas hasta llegar a la de persistencia que es la única mockeada.

Empezamos entrenando la consulta findBySymbol(«H») para que nos devuleva un mock del hidrógeno.

La petición RestAssured, extraemos el body de la respuesta, y proyectamos lo que está en el jsonPath «data.element» sobre un objeto de tipo Element y nos lo guardamos, para hacer algunas aserciones sobre él.

Verificamos, que cuando llamamos al endpoint con esa query, se acaba llamando al método get del servicio con «H», y verificamos que lo que nos devuelve el json, es lo que esperamos.

Ejecutamos los test y vemos que pasa en verde.

5. Mutaciones de creación, actualización y borrado

Venga, vamos a añadir algunas consultas adicionales

Pero claro, habrá que implementar los métodos del servicio

Como tenemos arrancado Quarkus en modo desarrollo, con mvn quarkus:dev podremos consultar lo que ha cambiado. Refrescamos la pantalla del navegador, y vemos que el texto predictivo del interfaz nos ayuda con las consultas y mutaciones que podemos hacer.

Vamos a hacer una mutación para crear el Hidrógeno.

Interfaz GraphQL con la mutación de creación del hidrógeno

Pero claro también queremos poder consultarlo. Vamos a hacer la consulta por su símbolo

Interfaz GraphQL con la query de consulta del hidrógeno

Ojo, que ha aparecido un ID que no está en nuestro modelo.

Como Element es una entidad que extiende de PanacheMongoEntity resulta, que el id es una propiedad que se refiere al objectID de Mongo.
Es el identificador único de la tupla en Mongo.

Ahora vamos a probar la mutación de actualización, y vamos a cambiar el nombre de Hydrogen por Hidrógeno

mutación de actualización

Y consultamos el elemento para ver que los cambios se han persistido correctamente.

consulta correspondiente al elemento modificado

Las mutaciones, no tienen por qué hacerse de una en una. De hecho, voy a hacer una mutación múltiple para dar de alta todos los elementos de la tabla periódica.

mutación múltiple de todos los elementos

La única diferencia cuando hacemos más de una mutación en una única request/operación es que debemos dar un alias a cada mutación.
Así que le ponemos el prefijo que veis en el ejemplo anterior a cada una de las mutaciones.

Si ahora consultamos todos los elementos veremos que nos devuelve el JSON que le pedimos

consulta de todos los elementos

En el fondo, cuando nos pidan información no usarán la interfaz gráfica, si no que nos harán una petición parecida a ésta.

curl con la consulta de todos los elementos

6. Conclusiones

Hemos aprendido que hacer una interfaz GraphQL es realmente sencillo con Quarkus. De hecho, podemos usar los mismos servicios para atender una API REST o para atender una API GraphQL.

Por supuesto, no lo he contado pero si en lugar de Element, nuestros servicios devolvieran Uni, ya sólo por eso, serían reactivos y podríamos programarlos como tal. Al venir de serie con Quarkus, se puede compilar a nativo sin problema, con las ventajas que eso aporta.

7. Enlaces y referencias

Dejar respuesta

Please enter your comment!
Please enter your name here