Diseño de aplicaciones

Procesamiento de consultas GraphQL con Java, Spring Boot y NoSQL

Durante los últimos meses he estado aprendiendo sobre GraphQL y cómo utilizarlo como alternativa al desarrollo de API RESTful. Hasta ahora me había centrado en GraphQL y Golang así como GraphQL y Node.js. Puede que haya exprimido todo lo que he podido esos dos lenguajes de desarrollo, así que he decidido cambiar de marcha y probar suerte con algo de Java.

En este tutorial, vamos a ver cómo poner rápidamente en marcha GraphQL utilizando Java y el popular framework Spring Boot.

Antes de entrar en materia, quiero dar crédito a quien lo merece. Prithviraj Pawar escribió un gran artículo titulado, Cómo poner en marcha su servidor GraphQL Java en un abrir y cerrar de ojos, que me dio muchas ideas aunque había cosas que desear, como una base de datos en lugar de datos simulados. Os animo a leer su artículo después de leer a través de la mía.

Requisitos

Hay algunos requisitos previos que deben cumplirse antes de saltar a la GraphQL y el lado de desarrollo de las cosas.

Vamos a asumir que ya tienes Couchbase instalado, configurado y funcionando. Cualquier cosa después de Couchbase Server 5.0 servirá porque sólo vamos a utilizar las características básicas.

También vamos a suponer que has descargado un proyecto base de Spring Boot. La página Sitio web de Spring Boot tiene un gran generador que te permite definir las dependencias. Si quieres mantener la coherencia con mi guía, tendrás que crear un proyecto Gradle en lugar de Maven.

Definición de las dependencias del proyecto Gradle

Cuando tengas una plantilla de Spring Boot a mano, probablemente estará muy desnuda. Necesitamos incluir las dependencias que planeamos usar en nuestra configuración de Gradle.

Abra el archivo build.gradle e incluya lo siguiente:

Usaremos Spring Boot para servir nuestro endpoint GraphQL, el SDK Java de Couchbase para interactuar con nuestra base de datos, y el plugin GraphQL para procesar nuestras consultas.

Bootstrapping de la API Java con RESTful Endpoints

Con las dependencias en su lugar, podemos empezar a desarrollar nuestra API. A pesar de que estamos utilizando GraphQL como un reemplazo a todas las cosas comunes API RESTful, esto no significa que REST está completamente fuera de la ecuación. Todavía necesitamos un punto final para enviar nuestras consultas GraphQL a.

Dependiendo de cómo haya llamado a su proyecto, paquete, etc., abra el archivo que contiene su principal e incluyen lo siguiente:

Recuerde que su paquete y nombre de clase pueden no coincidir con los míos. Rellene los huecos donde corresponda.

Usted notará que tenemos dos puntos finales, donde uno es completamente opcional. He creado el rootEndpoint para comprobar que mi API RESTful funcionaba. El sitio graphql es donde vamos a pasar nuestro tiempo. Espera una petición POST así como un cuerpo de petición. El cuerpo de la solicitud con el tiempo será una consulta GraphQL real, pero por ahora podemos dejarlo como está.

Diseño de un documento de esquema GraphQL

Hasta ahora sólo hemos hecho un trabajo básico de preparación de Spring Boot y nada realmente relacionado con GraphQL. Para que GraphQL sea posible, necesitamos conocer un esquema definido que explique las consultas que están disponibles así como los tipos de datos con los que estamos trabajando. Hay numerosas maneras de hacer esto, pero vamos a centrarnos en un documento de esquema.

Dentro del recursos de su proyecto, incluya un archivo esquema.graphql que contiene lo siguiente:

Por si no es obvio, vamos a trabajar con datos de Pokemon. En el archivo anterior hemos definido las consultas que están disponibles y los dos tipos de datos que están disponibles.

Hay una gran variedad de juegos Pokemon en el mercado y hay diferentes Pokemon en cada uno de los juegos, de ahí la relación que hemos definido. Si eres un verdadero fan de Pokemon sabrás que hay un poco más que esto, pero para este ejemplo es suficiente.

Desarrollo de la lógica de obtención para la base de datos NoSQL Couchbase

Con el esquema definido, tenemos que idear la lógica de base de datos que se ejecutará cuando se ejecute una consulta y esa lógica de base de datos debe devolver resultados que coincidan con cada uno de los dos tipos de datos.

Para hacer nuestra vida un poco más fácil cuando se trata de mantenimiento del proyecto, vamos a crear un archivo separado para la gestión de la base de datos. Dentro de tu paquete, crea un archivo Base de datos.java que contiene lo siguiente:

En su mayor parte, el conjunto anterior de funciones debe parecer familiar porque los hemos definido de alguna manera para que coincida con lo que teníamos en nuestro archivo de esquema GraphQL.

Antes de empezar a rellenar cada una de las funciones, hay que tener en cuenta algunas cosas:

  1. El cubo se definirá en nuestro archivo de proyecto principal poco después de definir nuestra lógica.
  2. GraphQL espera un determinado tipo de respuesta, de ahí la etiqueta extractResultOrThrow que hemos creado.

Dicho esto, empecemos por crear la función envoltorio. El extractResultOrThrow se utilizará sólo en las consultas N1QL y tiene el siguiente aspecto:

Básicamente, estamos recorriendo un conjunto de resultados de N1QL y creando un archivo Lista de Mapa de él.

Suponiendo que tenemos los datos del juego en nuestra base de datos, podemos consultarlos en la función getGamesData función:

Con N1QL podemos buscar documentos que coincidan con los criterios tipo de juego y procesar los resultados con nuestra función envoltorio. Si realmente quieres ser estricto, en lugar de utilizar un asterisco comodín, podrías definir las propiedades que coincidan con tu esquema.

La siguiente función, getPokemonDatanos permitirá consultar nuestros datos Pokemon de forma similar a como lo hicimos con los datos de los juegos.

Observará que no hemos hecho nada nuevo más allá de cambiar el tipo propiedad. Aquí es donde las cosas pueden ponerse interesantes. Tenemos una relación de datos para Pokemon con respecto a los datos del juego. Podríamos recuperarla en nuestra consulta actual o dividirla para que sea más modular y potencialmente más ligera. Vamos a optar por la opción modular y ligera.

Esto nos lleva a nuestro getGameData función:

En la función anterior ocurren dos cosas, ninguna de las cuales utiliza N1QL.

En nuestro esquema hemos definido una consulta basada en argumentos para los datos del juego, así como una relación de datos en los datos de Pokemon. Vamos a acomodar ambos escenarios en la misma función.

Utilización de la environment.getSource() podemos ver si hay algún dato padre que acompañe a la petición. Un ejemplo de estos datos padre podría ser cuando consultamos datos de Pokemon. El juego se refiere al campo getGameData mientras que los demás datos, como el nombre, el peso u otros, se refieren a los datos principales. En la base de datos, la información del juego se almacena como un id, por lo que después de extraerlo de los datos de los padres, podemos hacer una búsqueda de datos del juego.

El otro escenario es si pasamos un argumento que representa un id de juego.

Ambos son válidos y ambos hacen cosas diferentes. Al final, sólo queremos un único resultado en lugar de una matriz de resultados.

Cableado de la aplicación para un procesamiento GraphQL satisfactorio

Estamos en la recta final. Tenemos nuestra API y nuestra lógica de base de datos en su lugar. El último paso es conectar el esquema GraphQL a la lógica de la base de datos y ver los resultados en todo su esplendor.

¿Recuerdas que en el paso anterior mencioné la configuración de la información de nuestro cubo? Vamos a ocuparnos de eso primero. Abra el proyecto aplicación.propiedades que se encuentra en el archivo recursos directorio. Incluya lo siguiente:

La información de mi base de datos es sólo un ejemplo. Asegúrese de reemplazarla con la información que está utilizando para su instancia de Couchbase.

De vuelta en el archivo principal del proyecto, podemos asignar los valores y conectarnos a nuestra instancia:

Observa que hemos creado dos Judía y usamos la información de nuestro archivo de propiedades. Así de fácil estamos conectados a Couchbase.

El siguiente paso es inicializar nuestro esquema GraphQL. Hay numerosas maneras de hacer esto, pero me pareció más fácil usando la anotación de Spring Boot para cuando se inicia la aplicación:

En init será llamada cuando se inicie la aplicación. Cargará nuestro archivo de esquema desde el directorio recursos y definir el cableado. Por ejemplo, sabemos que pokemons, juegosy game(id: cadena) son todos tipos de consultas. Cada una se mapea a la función apropiada de la base de datos y se pasa el cubo abierto. Entonces establecemos un mapeo de juego a la Pokemon tipo. Estamos definiendo más o menos cómo se vinculan los campos y las consultas a la interacción con la base de datos.

Una vez construido el esquema podemos vincularlo a nuestra variable de clase. Con el esquema construido, podemos finalizar nuestro punto final GraphQL RESTful:

En nuestro endpoint tomamos la cadena de consulta que se pasó con la petición y la ejecutamos con nuestro esquema construido. El resultado será lo que el cliente haya solicitado en la consulta.

¿Qué aspecto tiene una consulta? Tomemos el siguiente ejemplo:

La consulta anterior probablemente no sea algo que nadie necesite ejecutar nunca, pero podrías hacerlo si quisieras. En el ejemplo anterior estamos consultando todos los datos de Pokemon y el juego del que forman parte. También estamos consultando todos los juegos, así como un juego específico. Las tres partes de la consulta no están relacionadas, pero existen en la misma consulta.

Como dato curioso, en el pokemons si elegimos no consultar los datos del juego, la función de la base de datos nunca será llamada. GraphQL sólo ejecutará las funciones cuando sean necesarias.

Conclusión

Acabas de ver cómo construir una aplicación GraphQL usando Spring Boot, Java y Couchbase Server como base de datos NoSQL. Como has visto en mi consulta de ejemplo, hemos sido capaces de consultar muchas piezas diferentes de datos no relacionados en una sola solicitud, algo que habría requerido varias en una API RESTful.

Para obtener más información sobre el uso del SDK de Java con Couchbase, consulte la página Portal para desarrolladores de Couchbase.

Comparte este artículo
Recibe actualizaciones del blog de Couchbase en tu bandeja de entrada
Este campo es obligatorio.

Autor

Publicado por Nic Raboy, Defensor del Desarrollador, Couchbase

Nic Raboy es un defensor de las tecnologías modernas de desarrollo web y móvil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y móvil más fácil de entender.

Deja un comentario

¿Listo para empezar con Couchbase Capella?

Empezar a construir

Consulte nuestro portal para desarrolladores para explorar NoSQL, buscar recursos y empezar con tutoriales.

Utilizar Capella gratis

Ponte manos a la obra con Couchbase en unos pocos clics. Capella DBaaS es la forma más fácil y rápida de empezar.

Póngase en contacto

¿Quieres saber más sobre las ofertas de Couchbase? Permítanos ayudarle.