Spring Data Couchbase

0
595

Índice de contenidos

Introducción

Couchbase es una base de datos no SQL, distribuida y orientada a documentos usada por aplicaciones como Amadeus, Ebay, Betfair, LinkedIn, etc.

Couchbase está diseñada para responder a millones de operaciones de forma rápida, con alta disponibilidad y escalado, realizadas por muchos usuarios concurrentes.

Podemos leer un tutorial introductivo en https://www.adictosaltrabajo.com/2018/12/11/primeros-pasos-con-couchbase-server/.

Como siempre Spring nos ofrece una abstracción para facilitarnos el trabajo con Couchbase y reducir significativamente la cantidad de código necesario para configurar y trabajar con esta base de datos. Dentro del proyecto Spring Data nos encontramos con Spring Data Couchbase que nos proporciona integración con la base de datos Couchbase Server con un modelo que nos permite interactuar con los Buckets y escribir fácilmente la capa de acceso a datos.

En este tutorial veremos cómo hacer una aplicación que consuma e inserte datos en un bucket de Couchbase.

Entorno

Este tutorial está escrito usando el siguiente entorno:

  • Hardware: MacBook Pro 15’ (2,5 GHz Intel Core i7, 16GB DDR3)
  • Sistema operativo: macOS Mojave 10.14.1
  • Versiones del software:
    • Docker: 18.09.0
    • Couchbase Server: 5.0.1
    • Java: 8
    • Spring Boot: 2.1.1.RELEASE

Preparación de la base de datos

Arrancamos Couchbase:

Dentro del servidor de Couchbase nos encontramos con el bucket de ejemplo “travel-sample” con casi 32000 items donde dentro de ellos podemos encontrar aeropuertos, aerolíneas, rutas etc.

Vistas

Las vistas en Couchbase nos permiten extraer campos e información y crear índices sobre éstos. Las vistas creadas nos permitirán iterar, seleccionar y consultar información sobre ellas.

Debido a la naturaleza del clúster de Couchbase y al tamaño de los conjuntos de datos que puede almacenar, se debe controlar el impacto que puede tener el desarrollo de una vista. Crear una vista implica la creación del índice que puede ralentizar el rendimiento del servidor mientras éste se genera. Debido a este posible impacto, para admitir tanto la creación y pruebas de vistas, como el despliegue de éstas en producción, Couchbase Server soporta dos tipos de vistas: las vistas de desarrollo y las vistas de producción. Los dos tipos de vista funcionan de manera idéntica, pero tienen diferentes propósitos y restricciones en sus operaciones.

Ahora vamos a crear una vista con los aeropuertos. Para ello vamos a la sección Indexes y en la columna vistas pinchamos sobre “ADD VIEW” y creamos las vista “all” con nombre de documento “airport“. Estos son los valores con los que funcionará por defecto el CrudRepository de Spring para saber hacer ciertas operaciones.

En el Map de la vista añadimos el siguiente código Javascript:

Tras crear y probar la vista la publicamos para que pase a producción y tengamos acceso a ella desde la aplicación que vamos a desarrollar.

Seguridad

Para que la aplicación tenga acceso al bucket vamos a crearle un usuario. En la consola de Couchbase, en la sección Security creamos el usuario “travel-sample” con contraseña “travel-sample1234” y en los roles le damos Bucket Full Access sobre el bucket “travel-sample”.

Creación de la aplicación

Creamos una aplicación Spring Boot con maven:

Lo primero que vamos a hacer es modelar la entidad que respalde la representación de aeropuertos que tenemos en el buckettravel-sample” de nuestro servidor Couchbase.

Vemos como al no estar en camel case el nombre del aeropuerto, le tenemos que indicar el nombre en base de datos dentro de la anotación @Field.

Una vez tenemos modelada la entidad pasamos a configurar los repositorios. Simplemente tenemos que crear una clase de configuración que extienda a AbstractCouchbaseConfiguration, donde activemos los repositorios con @EnableCouchbaseRepositories y donde especifiquemos:

  • La lista de nodos Couchbase para iniciar (no hace falta puerto, sólo IP o nombre del host).
  • El nombre del bucket.
  • La contraseña que le hemos dado al usuario de la aplicación que anteriormente hemos creado en Couchbase con el mismo nombre del bucket.

Con esta configuración ya podemos probar a arrancar la aplicación y comprobar que se conecta correctamente a la base de datos. Si todo va bien, podemos pasar a crear el repositorio.

Consultas basadas en vistas

A partir de la versión 2 de Spring Couchbase las consultas con vista de respaldo han evolucionado y se ha introducido soporte para N1QL. Las consultas con vistas de respaldo son mucho más limitadas debido a que cada método personalizado de consulta necesitaría su propia vista que debe prepararse de antemano en el clúster. Como regla general los siguientes métodos todavía requieren una vista de respaldo:

  • Iterable findAll()
  • long count()
  • void deleteAll()

Como nosotros ya hemos creado la vista ya podemos crear el repositorio para listar todos los aeropuertos.

Creamos el servicio:

Si creamos ahora un controlador ya podemos listar todos los aeropuertos llamando a http://localhost:8080/airport/ . Si no tuvieramos la vista airport/all Spring lanzaría un error indicando que no la encuentra.

Podemos realizar más consultas basadas en vistas con la anotación @View en cada método que definamos en el repositorio.

Consultas N1QL

A partir de la versión 4.0, Couchbase Server tiene un nuevo lenguaje de consultas llamado N1QL. En “Spring-Data-Couchbase 2.0″ es la forma preteterminada de hacer consultas y de derivar éstas a partir del nombre de los métodos.

Ahora vamos a añadir una consulta para listar todos los aeropuertoes de un país.

En la consulta hemos usado “#n1ql.selectEntity” uno de los valores que SpEL (Spring Expression Language) tiene para dar soporte a N1QL. Con esto nos aseguramos que se seleccionen todos los campos del bucket actual. La consulta que hemos puesto sería equivalente a:

Podemos ver en el log las consultas generadas estableciendo en application.properties:

Otro SpEL que es recomendable usar es “#n1ql.filter” para que nos añada el discriminador del documento sobre el que estamos seleccionando:

En este caso la consulta generada sería del tipo:

Nosotros para discriminar tenemos la propiedad “type = ‘airport‘” y como vemos Spring usa la propiedad “_class” y como valor el nombre de la clase. El nombre de la propiedad se puede cambiar sobrescribiendo el método “typeKey()” en la configuración de AbstractCouchbaseConfiguration. El problema es que Spring no permite todavía cambiar el valor, y siempre nos pone el nombre de la clase. Existen dos soluciones:

  • No usar “#{#n1ql.filter}” y poner siempre “type = ‘airport‘”.
  • Añadir la columna en base de datos.

Como “#{#n1ql.filter}” también nos añade filtros de paginación, vamos a optar por la segunda opción. Vamos ahora al Couch Server y ejecutamos la consulta:

Ahora ya podemos quitar el filtrado manual de tipos y añadir paginado:

El servicio nos quedaría:

Y el controlador:

Si queremos, en vez de escribir nosotros mismos la consulta N1QL en el repositorio, podemos hacer que Spring nos la genere a través del nombre del método, por lo que el repositorio quedaría:

Haciendo desde el navegador consultas a http://localhost:8080/airport/United%20States?pageNumber=0&pageSize=10 o a http://localhost:8080/airport/France?pageNumber=0&pageSize=10 comprobamos como se listan los aeropuertos filtrados por país. También podemos observar que las consultas tardan un poco en ejecutarse y que en el log de la aplicación sale constantemente el aviso:

Así que vamos a optimizar la consulta creando un índice sobre el campo “country”.

Ahora sí que vemos que la consulta se ejecuta mucho más rápidamente y que deja de salir el aviso en el log.

Inserción de registros

Como podemos observar, el identificador de las entidades de la base de datos es la concatenación del campo type con el campo id, por lo que para insertar registros en base de datos vamos a añadir a nuestra entidad una clave autogenerada.

Ya podemos escribir el comando de creación y el servicio.

Por último creamos el controlador:

Haciendo POST a la url con un JSON en el cuerpo de la petición deberíamos comprobar que el identificador se crea correctamente:

Por último vamos a añadir validaciones en nuestra entidad. Como es lógico las validaciones JSR a nivel de controlador seguirán funcionando en Spring MVC, ahora lo que vamos a probar es el soporte de la librería Spring Data Couchbase con las validaciones JSR 303 a nivel de entidad.

Para que las validaciones funcionen tenemos que añadir a nuestro proyecto la librería JSR-303 y alguna de sus implementaciones, por ejemplo la de Hibernate.

También debemos añadir dos Beans a nuestra clase de configuración CouchbaseConfig.

En nuestro caso no necesitamos definir el Bean ValidatingCouchbaseEventListener debido al starter spring-boot-starter-data-couchbase que tenemos que ya nos lo define.

Ahora ya podemos anotar la entidad Airport. Si la validación fallara en el save() se lanza la excepción ConstraintViolationException.

Se puede descargar el código completo desde:

Conclusiones

Como nos tiene acostumbrados, Spring nos da soporte para poder trabajar de forma transparente con bases de datos Couchbase, por lo que podemos configurar la base de datos rápidamente y de forma sencilla en nuestra aplicación.

Además, gracias al nuevo soporte de consultas N1QL nos quita la gran dependencia que tenía de tener que crear vistas en base de datos para luego crear las operaciones del repositorio de nuestra aplicación sobre ellas.

Referencias

Dejar respuesta

Please enter your comment!
Please enter your name here