Building a Spring-Boot API with a Multi-Model Database (OrientDB) on Alibaba Cloud

By Dassi Orleando, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud’s incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.

Prerequisites

  1. Basic knowledge of Linux command line
  2. Understanding of ECS security groups
  3. Java installed & environment variable setting up
  4. Basis Spring-Boot knowledge

Overview

OrientDB is an open source Java Multi-Model NoSQL database management technology that supports Graph, Document, Key-Value, GeoSpatial and Reactive models while managing queries with the well-known SQL syntax.

Installing OrientDB on Alibaba Cloud ECS

First, we need to create an ECS. For the sake of the demo, I will be using an Ubuntu one with 1 Core and 0.5 GB of memory. Log in via ssh/console as described into this guide:

Image for post
Image for post
curl https://s3.us-east-2.amazonaws.com/orientdb3/releases/3.0.8/orientdb-3.0.8.tar.gz --output orientdb-3.0.8.tar.gz
JAVA_HOME=/usr/lib/jvm/java-8-oracle
ORIENTDB_HOME=/opt/orientdb-3.0.8
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games :$ORIENTDB_HOME/bin"
  1. orientdb.sh start: to start the server
  2. orientdb.sh stop: to shut down the server
Image for post
Image for post
Image for post
Image for post

Creating a Database

OrientDB’s multi-model capability allows to manage many types of database with the same engine, here we can manage:

  1. Document Database
Image for post
Image for post
  1. Schema-Less: classes are created with no specific property so we can further update/add others as we want, it’s the default mode
  2. Schema-Hybrid: a merge of the two above where we can create a class with pre-defined fields but let the record to define other custom ones

Building a Spring Boot API

Initializing the Project

As stated at the beginning of this article, the end result is to have a fully working API (only some CRUD operations) where Spring-Boot and OrientDB are both in actions on Alibaba Cloud ECS.

Image for post
Image for post

Configure OrientDB

OrientDB is entirely written in Java, meaning we can immediately use its Java API’s without the need to add anymore drivers or adapters.

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>

<orientdb.version>3.0.5</orientdb.version>
</properties>
<!-- OrientDB -->
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-core</artifactId>
<version>${orientdb.version}</version>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-client</artifactId>
<version>${orientdb.version}</version>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-object</artifactId>
<version>${orientdb.version}</version>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-graphdb</artifactId>
<version>${orientdb.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
  1. orientdb-client: to talk to a remote OrientDB installation
  2. orientdb-server: Only if you’re embedding a server within your project
  3. orientdb-object: furnishes the Object database API (document database)
  4. orientdb-distributed: if you’re working with a server cluster
  5. orientdb-tools: to execute console commands from your application, for console application
  6. orientdb-graph: for graph database
/**
* Basic OrientDB configuration class
* To configure and provide the bean to inject later for database interactions
* @author dassiorleando
*/
@Configuration
public class OrientDBConfiguration {
// The orientdb installation folder
private static String orientDBFolder = System.getenv("ORIENTDB_HOME");
/**
* Connect and build the OrientDB Bean for Document API
* @return
*/
@Bean
public ODatabaseDocumentTx orientDBfactory() {
return new ODatabaseDocumentTx("plocal:" // or remote
+ orientDBFolder + "/databases/alibabacloudblog")
.open("username", "userpwd");
}
}
return new ODatabaseDocumentTx("remote:server_ip/alibabacloudblog").open("admin", "admin");

Create an Article

Here the Class (entity in a relational word) are being created automatically as the default database mode is Schemaless:

/**
* To create an article
* @param article
* @return article
*/
public Article save(Article article) {
// Specify to use the same db instance for this thread
ODatabaseRecordThreadLocal.instance().set(db);
// The Class will be automatically created into Orient Studio
ODocument doc = new ODocument(Article.class.getSimpleName()); // The entity name is provided as parameter
doc.field("title", article.getTitle());
doc.field("content", article.getContent());
doc.field("author", article.getAuthor());
doc.save();
return article;
}

Update an Article

Here is a concrete example of how the SQL can be perfectly used with OrientDB regardless the type of database we opted for, let’s update an article based on its title:

/**
* To update an article
* @param article
* @return boolean true if it was successfully updated
*/
public boolean update(Article article) {
// Specify to use the same db instance for this thread
ODatabaseRecordThreadLocal.instance().set(db);
// Data
String title = article.getTitle().trim();
String content = article.getContent();
String author = article.getAuthor();
// The sql query
String query = "update Article set content = '" + content +
"', author = '" + author + "' where title = '" + title + "'";
int resultInt = db.command(
new OCommandSQL(query)).execute();
if(resultInt != -1) return true;
return false;
}

Find an Article by Title

The query of a single Article by its title can be done in this way with another basic SQL command:

/**
* Find a single article by title
* @param title
* @return article if found null else
*/
public Article findOne(String title) {
// SQL query to have the ones that match
List<ODocument> results = db.query(
new OSQLSynchQuery<ODocument>("select * from Article where title = '" + title + "'"));
// For the sake of the test, pick the first found result
if(!results.isEmpty()) {
ODocument oDocument = results.get(0);
return Article.fromODocument(oDocument);
}
return null;
}

Find All Articles

Now, accessing the list of all articles could be done in two ways, either with SQL or with a special database instance function as shown below:

/**
* Find all saved articles so far
* @return
*/
public List<Article> findAll() {
// List of resulting article
List<Article> articles = new ArrayList<>();
// Load all the articles
for (ODocument articleDocument : db.browseClass("Article")) {
Article article = Article.fromODocument(articleDocument);
articles.add(article);
}
return articles;
}

Article Deletion

Deleting an Article could be made with an SQL command also:

/**
* Delete a single article by its title
* @param title
* @return boolean true if it was deleted successfully
*/
public boolean delete(String title) {
title = title.trim(); // The title of the article to delete
int resultInt = db.command(
new OCommandSQL("delete * from Article where title = '" + title + "'")).execute();
if(resultInt != -1) return true;
return false;
}

Count Articles

Counting all the articles is a simple call as follow:

long size = db.countClass("Article");

The Rest Resource: ArticleResource

The API need a front gate to serve the query, here we’re using Spring RestController annotation to define a Rest controller. The full source code of the project is available on Github:

/**
* Article controller for CRUD operations
* @author dassiorleando
*/
@RestController
public class ArticleResource {
private final Logger log = LoggerFactory.getLogger(ArticleResource.class);
private final ArticleService articleService; public ArticleResource(ArticleService articleService) {
this.articleService = articleService;
}
/**
* To create an article
* @param article
* @return
*/
@PostMapping("/article")
public Article create(@RequestBody @Valid Article article) {
log.debug("Create an article with the properties {}", article);
return articleService.save(article);
}
/**
* To update an article
* @param article
* @return
*/
@PutMapping("/article")
public boolean update(@RequestBody @Valid Article article) {
log.debug("Update the article of title {} with the properties {}", article.getTitle(), article);
return articleService.update(article);
}
/**
* Get the list of all articles
* @return
*/
@GetMapping("/article")
public List<Article> list() {
log.debug("We just get the list of articles one more time");
return articleService.findAll();
}
/**
* We asynchronously find an article by his title
* @param title
* @return
*/
@GetMapping("/article/{title}")
public Article findByTitle(@PathVariable @NotNull String title) {
log.debug("Load the article of title: {}", title);
return articleService.findOne(title);
}
/**
* Delete an article by its title
* @param title
*/
@DeleteMapping("/article/{title}")
public boolean deleteById(@PathVariable @NotNull String title) {
log.debug("Delete the article of title: {}", title);
return articleService.delete(title);
}
}

Running the API

A basic script is available to run your API on your ECS or locally on any Linux/Mac computer as a bash file (startup.sh), supposing the port 8080 is the one used. Here’s the file content:

echo "RUN THE PROJECT IN THE SERVER/LOCAL"echo "Compiling while skipping tests ..."
./mvnw clean install -DskipTests
echo "Compilation finished"
echo "Kill the process on port 8080, to undeploy the former version if existing"
sudo kill $(sudo lsof -t -i:8080)
echo "Let's deploy the new version silently"
nohup ./mvnw spring-boot:run &

OrientDB Studio Query

Here’s an example of SQL query from the OrientDB dashboard to have all the saved Articles:

Image for post
Image for post
Image for post
Image for post

Conclusion

In this long article, we’ve seen how to build a Spring-Boot API using OrientDB as the database management system with its Java APIs and how to set it up all on an Alibaba Cloud ECS.

Written by

Follow me to keep abreast with the latest technology news, industry insights, and developer trends.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store