Update: We’ve recently developed a number of sample projects to help you get started with ScyllaDB. For repos and tutorials, go to our DevHub.
This article is the first of a series that walks you through how to get started building a backend application withScyllaDB.
In this article, we will review the basics of ScyllaDB, then create a cluster and deploy on AWS using ScyllaDB Cloud (NoSQL DBaaS).
What’s a CRUD App?
CRUD stands for Create, Read, Update and Delete. In this article, we will build a simple application that will connect to our database and do just that using NodeJS and ScyllaDB Cloud.
Why Should You Care?
JavaScript is and has been the most popular programming language for the past decade. With the evolution of JavaScript compilers, frameworks, and languages such as typescript, NodeJS has become one of the most popular choices to build backend applications and REST APIs. ScyllaDB on the other hand is one of the hottest NoSQL databases in the market today because of its lightspeed performance.
Whether you’re a junior or an experienced developer, this article will help you understand the building blocks and NodeJS application and how to connect it a ScyllaDB cluster running in the cloud.
Getting Started
To start, we will first open the terminal and run the following command to clone the project starter repository:
git clone https://github.com/raoufchebri/getting-started.git
Let’s then change directory:
cd getting-started/nodejs/starter
The project is split into two applications: client and server.
Client
The client application is a simple ReactJS Todo application that allows users to add, mark as complete, and remove tasks.
To run the application, move to the client directory and run the following commands:
npm install
npm start
It’s available, the application will run on http://localhost:3000.
The client application is not connected to any server. If you refresh your browser, you will notice all the tasks that you added disappear. In this article, we will create and connect our client app to the server and store the data in ScyllaDB Cloud.
Server
Let’s now move to the server directory and create implement the CRUD functions.
The application is structured as follow:
– src
—- api
—--- index.js
—--- items.js
—- index.js
– .env
– package.json
The package.json file lists all of the project dependencies:
"dependencies": {
"cassandra-driver": "^4.6.3",
"cors": "^2.8.5",
"dotenv": "^16.0.0",
"express": "^4.17.2",
"nodemon": "^2.0.15"
}
In the server directory, let’s install all project dependencies by running the following command:
npm install
We will then start the application by running:
npm run dev
By default, the application will run on http://localhost:3001. If for any reason you would like to change the port, you can do so by updating the .env file and re-run the application.
Open http://localhost:3001 on your browser, and you should see the following message:
{
"message": "Welcome to ScyllaDB 😉"
}
http://localhost:3001/api should return the following object:
{
"message": "Welcome to API 🚀"
}
Let’s now move to /api/items.js
file explore the code:
const express = require('express');
const router = express.Router();
// Create one item
router.post('/', async (req, res, next) => {
try {
res.json({ message: 'Create one item' });
} catch (err) {
next(err);
}
});
// Get all items
router.get('/', async (_, res, next) => {
try {
res.json({ message: 'Get all item' });
} catch (err) {
next(err);
}
});
// Delete one item
router.delete('/:id', async (req, res, next) => {
try {
const { id } = req.params;
res.json({ message: `Delete one item ${id}` });
} catch (err) {
next(err);
}
});
// Update one item
router.put('/:id', async (req, res, next) => {
try {
const { id } = req.params;
res.json({ message: `Update one item ${id}` });
} catch (err) {
next(err);
}
});
module.exports = router;
In items.js, we have defined the post, get, put and delete middlewares with their respective callback functions.
We can test the API by sending a GET
request through the following command:
curl -v http://localhost:3001/api/items
You should expect the following result:
* Trying ::1:3001...
* Connected to localhost (::1) port 3001 (#0)
> GET /api/items HTTP/1.1
> Host: localhost:3001
> User-Agent: curl/7.77.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Access-Control-Allow-Origin: *
< Content-Type: application/json; charset=utf-8
< Content-Length: 26
< ETag: W/"1a-wtLtpakh/aHZijHym0cXyb81o1k"
< Date: Mon, 14 Feb 2022 10:22:12 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
* Connection #0 to host localhost left intact
{"message":"Get all item"}
The GET
request runs the callback function implemented the router.get middleware in items.js.
Creating a Cluster Using ScyllaDB Cloud
The next step is to create an account on https://cloud.scylladb.com. You can use the free trial account to follow along. The home page shows the running clusters. You will probably have an empty page if you are new to ScyllaDB Cloud. Let’s go ahead and create a new cluster by clicking on the “Create a New Cluster” card.
On the new cluster page, enter the name of your cluster. I will name mine “my scylla cluster”. I will also leave the provider to AWS and use the ScyllaDB Account to deploy the cluster.
If you scroll down a little bit, you will see the list of machines available to you. If you are using a free trial account, you will likely use a t3.micro, which is plenty for our example here. If you want to explore other machines, be aware of the cost per node when you create your cluster. To deploy your app on ScyllaDB Cloud, you can use available tools to have an estimate of the cost associated with a cluster.
Let’s scroll to the bottom of the page and create the cluster. You might take this opportunity to have a small break and get a cup of coffee, as this process usually takes a few minutes.
Great! You’re back energized and ready to explore. First, click on the connect button or go to the connect tab on your cluster’s main page. You will notice the IP addresses of your nodes along with your credentials. That information is critical to access your database and should not be made public or accessible in your app. We will use the dotenv library and a .env file to hide our credentials later on.
Create a Keyspace and Table using CQLSH
Let’s now test it out. Click on the “Cqlsh” item on the left side menu and follow the instructions to connect to your cluster.
I will use docker since I do not have cqlsh installed on my machine.
docker run -it --rm --entrypoint cqlsh scylladb/scylla -u [USERNAME] -p [PASSWORD] [NODE_IP_ADDRESS]
Note that you will need to replace the USERNAME
, PASSWORD
, and NODE_IP_ADDRESS
with your own.
The above command instructs docker to create a new container with the scylladb/scylla image and run cqlsh, which is short for the Cassandra Query Language Shell. You will then be at the shell prompt.
Let’s create a new keyspace. A keyspace is a location where the data is stored. I’m using the code provided in the connect tab under Cqlsh.
CREATE KEYSPACE todos WITH replication = {'class': 'NetworkTopologyStrategy', 'AWS_US_EAST_1' : 3} AND durable_writes = true;
Let’s then use the newly created keyspace.
USE todos;
Then create table items
. Note that in ScyllaDB, it is mandatory to have a PRIMARY KEY
. More about that on ScyllaDB University in this lesson.
CREATE TABLE items ( id uuid PRIMARY KEY, name text, completed boolean);
Let’s now insert some values.
INSERT INTO items (id, name, completed) VALUES (uuid(), 'my first task',false);
And run a SELECT query to make sure we correctly saved the data.
SELECT * FROM items;`
id | completed | name
--------------------------------------+-----------+---------------
0536170a-c677-4f11-879f-3a246e9b032d | False | my first task
Connect the Server App to ScyllaDB Cloud
In the server directory, locate and open the .env file, and provide the cluster information that you can find on ScyllaDB Cloud:
USERNAME=""
PASSWORD=""
DATA_CENTER=""
NODE_IP=""
KEYSPACE="todos"
The reason we’re using environment variables is to hide sensitive information that you might pass to the client.
In items.js file, Let’s import the cassandra-driver and the dotenv config like so:
const cassandra = require('cassandra-driver');
require('dotenv').config();
The reason we’re using the cassandra-driver package is that it is fully compatible with ScyllaDB, which is convenient to migrate from Apache Cassandra to ScyllaDB.
We will also add our environment variables to the items.js file and create an instance of Client using the following code:
const { NODE_IP, DATA_CENTER, USERNAME, PASSWORD, ITEMS_KEYSPACE } =
process.env;
const cluster = new cassandra.Client({
contactPoints: [NODE_IP],
localDataCenter: DATA_CENTER,
credentials: { username: USERNAME, password: PASSWORD },
keyspace: KEYSPACE,
});
Et voilà!
Congratulations! You’ve created your first ScyllaDB cluster and succeeded your first cluster deployment on the cloud.
In this article, we cloned the todo-app project and installed its dependencies. We looked at both the client and server structure and tested the frontend and the API. We also create a cluster using ScyllaDB Cloud, and connected it to NodeJS using the cassandra-driver and cqlsh. In the next article, we will see how to implement the CRUD operations.