Access Aerospike from Spring Boot Based gRPC App Built with Gradle

Nur
4 min readAug 25, 2020

--

Aerospike is a flash-optimized in-memory open source NoSQL database. Unlike another popular NoSQL storage Redis, Aerospike is multithreaded and supports cross data center replication(XDR). In this tutorial we will explore how to build a gRPC service with spring boot and gradle that uses aerospike as the backend.

Bootstrap The Project

Bootstrap The Project

We will start by generating project structure using Spring Initializr. On the spring Initializr page, select the following,

  • Project — Gradle Project
  • Language — Java
  • Spring Boot — 2.33
  • Packaging — Jar
  • Java — 11
  • Dependencies
    Lombok
    Spring Security
    Spring Boot Actuator (Optional)
    Spring REST Docs (Optional)
    Spring Web

Generate the project structure, download the code and open it in Intellij (You may use your editor of choice)

Gradle Configuration

We need to make few changes in the build.gradle file to enable protobuf support for gRPC and Aerospike. Full gradle configuration can be found here

gRPC Support

For gRPC, we will use proto compiler to auto-generate java code from .proto file.

  • Add following in the plugins
id 'com.google.protobuf' version '0.8.12'
  • Add a sourceSets section to define where to find auto-generated classes
sourceSets { main{  java {   srcDir 'src/main/protoGen'  } }}
  • Add a protobuf section to for protobuf compiler
  • Add following code in gradle dependencies
implementation 'io.github.lognet:grpc-spring-boot-starter:3.5.6'

Aerospike Support

We will use spring-data-aerospike to access aerospike storage. Add following in the gradle dependencies

implementation 'org.springframework.data:spring-data-commons' implementation 'com.aerospike:spring-data-aerospike:2.4.0.RELEASE'

Project Structure

The project contains 3 main directories for proto file, auto-generated code and other java classes.

main/Java

Java directory contains 4 packages.

  • com.nur.spring.aerospike.configuration
    configuration packages, as the name implies, contains various configuration classes. AerospikeRepositoryConfiguration is used to configure target aerospike cluster, user credentials and namespace. SecurityConfiguration controls url permission.
  • com.nur.spring.aerospike.domain
    domain classes are populated by the repositories with data fetched.
  • com.nur.spring.aerospike.repository
    contains repository interface definition. It is worth noting that there is no need to provide implementation classes of these interfaces. Proxy implementations are generated during compilation.
  • com.nur.spring.aerospike.service
    Service classes implement business logic. There are two types of service classes.
    1. GrpcService - GrpcService classes are annotated with @GrpcService. They intercept incoming requests.
    2. Service — Service classes are annotated with @Service. They implement business logic.

main/proto

proto directory contains .proto files.

main/protoGen

protoGen directory contains all the classes generated by proto compiler.

Execution Flow

As usual the execution flow is initiated by the client. Client request is intercepted by GrpcService class. Grpc service class calls various service classes to process the request. Services needing data from aerospike calls repository.

Access Aerospike

As mentioned before the project uses spring data aerospike to access aerospike storage. Spring-data-aerospike is built on spring data API. Much of the complexity is abstracted away and is taken care of by the library leaving simple repository interfaces to interact with aerospike backend.

  • The library provides AerospikeRepository<T, ID> where

T — the domain type the repository manages

ID — the type of the id of the entity the repository manages

  • The interface can be extended to create a new interface to manage specific domain types.
  • Domain type T is used as the aerospike set name.
  • ID is the key to query
  • Each field in the domain type represents a bin in aerospike.
public interface StorefrontProductRepository extends AerospikeRepository<StorefrontProductDocument, String> {}

Declaration above creates an interface that lets us query aerospike by string type key into a set represented by document entity GreeterDocument.

Defining document entity

Document entity represents the domain model. In the context of aerospike, a set represents domain (similar to a table that represents a domain in relational database world). Following example explains how the document entity is mapped to the aerospike set and bin.

@Value // (1)
@Document(collection = “my_aerospike_set”) // (2)
@AllArgsConstructor
public class GreeterDocument {
@Field(“my_aerospike_greeting_bin”) // (3)
String GreetingText;
}

Explanation

  1. @Value — makes the class immutable, all fields are made private and final, toString(), equals(), hashCode(), field getters and all args constructor are generated.
  2. @Document(collection = “my_aerospike_set”) — @Document marks a class as an entity to be persisted in aerospike, By default, class name is used as the aerospike set name but this can be overridden by collection element as is done in the example above.
  3. @Field(“my_aerospike_greeting_bin”) — configures the name of a field to be used when persisting the document. This value will be used as a bin name instead of the original field name.

Source code

The full source code can be found in github.

--

--

Nur

Software Engineer, Tech Enthusiast