Getting Started — Accessing Oracle NoSQL Database using Express.js

Dario Vega
Oracle Developers
Published in
5 min readJul 4, 2024
Photo by Marc Sendra Martorell on Unsplash

Let’s use the express.js framework in your application to manage JSON collection data in Oracle NoSQL Database.

The sample application will show how to store, retrieve, update, query, and delete records in a NoSQL Database using Node.js for Oracle NoSQL Database.

Do you want your Node.js application to access data with predictable single-digit millisecond response times at a massive scale in a highly available elastic scaling store? Do you want to be able to move your application between on-premises and the cloud at a moment’s notice? Then, let’s embark together on a 15-minute quick tutorial.

Understanding Express.js

Express is a lightweight and flexible routing framework with minimal core features meant to be augmented through the use of Express middleware modules. It provides a thin layer of fundamental web application features.

Oracle NoSQL Database Data Model

Proper modeling of your data is crucial to application performance, extensibility, application correctness, and finally, the ability for your application to support rich user experiences.

Unlike the relational database world with purely fixed schemas, NoSQL Database is largely about schema flexibility — that is the ability to easily change how data is organized and stored.

Oracle NoSQL Database 23.3+ supports JSON Collection tables. This is particularly useful for applications that store and retrieve their data purely as documents. JSON Collection tables are created to simplify the management and manipulation of documents. When you insert data into the table, each row is inserted as a single document containing any number of JSON fields.

CREATE TABLE if NOT EXISTS blogtable(
id STRING AS UUID GENERATED BY DEFAULT, PRIMARY KEY(id)
) AS JSON COLLECTION

In JavaScript, object is a mapping between the keys and values. In object, keys are strings and values can be anything.

Write and Read your JSON collection data

Using JSON collection allows flexibility in the use of data as the data in the JSON collection does not have predefined schema in the database. To put data, we just need to provide either an object or a JSON string as the value. In this case, the id is auto-generated.

// Create a new blog
app.post('/', async (req, res) => {
try {
const result = await client.put("BlogTable", req.body );
res.json({ result: result});
} catch (err) {
console.error('failed to insert data', err);
res.status(500).json({ error: err });
}
});
// Get a blog by id
app.get('/:id', async (req, res) => {
const { id } = req.params;
try {
const result = await client.get("BlogTable", { id })
res.json(result.row);
} catch (err) {
console.error('failed to get data', err);
res.status(500).json({ error: err });
}
});

Note: If using TypeScript, you can still specify row schema using an Interface to validate the data in your application. But it will be used only on the client side by TypeScript compiler. A topic for a new blog.

interface Person {
id: number;
name: string;
}

// Using uncondintional put
// You can also use putIfAbsent, putIfPresent, putIfVersion
let result = await client.put<Person>(
tableName,
{ id: 1, name: 'John' }
);

SQL for Oracle NoSQL Database

Welcome to SQL for Oracle NoSQL Database. This query language provides statetements that can be used from the Oracle NoSQL Database SDKs. A convenient way to iterate over query results is to use queryIterable API. This API returns an iterable object that you can iterate over with for-await-of loop.

app.get('/', async function (req, resW) {
let statement = `SELECT * FROM blogtable`;
const rows = [];

try {
for await(let result of client.queryIterable(statement)) {
rows.push.apply(rows, result.rows);
}
resW.send(rows)
} catch(error) {
console.error('failed to select data', err);
resW.sendStatus(500).json({ error: err });
}
});

As you can see in this example, each document has his own “structure”

$ curl -X GET http://localhost:3000/ | jq
[
{
"id": "1d70cf5d-8847–4ec2-aa74–447f0035266b",
"blog": "Updating an empty blog from Node.js"
},
{
"id": "3912c873–35ad-46ce-a946–9ad2e10d8ed7",
"author": "Dario Vega",
"blog": "Creating a blog with an author"
},
{
"id": "3f1ad780-bce2-4fab-982d-b6c56942203c",
"blog": "Creating a blog with nested objects",
"author": {
"name": "Dario Vega",
"title": "Product Manager"
},
"keywords": [
"nosql",
"express",
"json collection"
]
}
]

The SQL for Oracle NoSQL Database data model supports flat relational data, hierarchical typed (schema-full) data, and schema-less JSON data. SQL for Oracle NoSQL Database is designed to handle all such data in a seamless fashion without any “impedance mismatch” among the different sub models.

sql-> SELECT * FROM blogtable t WHERE t.author = "Dario Vega";
{
"id" : "3912c873-35ad-46ce-a946-9ad2e10d8ed7",
"author" : "Dario Vega",
"blog" : "Creating a blog with an author"
}
1 row returned

sql-> SELECT * FROM blogtable t WHERE t.author.name = "Dario Vega";
{
"id" : "3f1ad780-bce2-4fab-982d-b6c56942203c",
"author" : {
"name" : "Dario Vega",
"title" : "Product Manager"
},
"blog" : "Creating a blog with JSON nested objects",
"keywords" : ["nosql", "express", "json collection"]
}
1 row returned

sql-> SELECT * FROM blogtable t WHERE t.keywords[] =ANY "nosql";
{
"id" : "3f1ad780-bce2-4fab-982d-b6c56942203c",
"author" : {
"name" : "Dario Vega",
"title" : "Product Manager"
},
"blog" : "Creating a blog with an author",
"keywords" : ["nosql", "express", "json collection"]
}
1 row returned

sql-> SELECT * FROM blogtable t WHERE t.IdontKnow = 0;
0 row returned

sql-> SELECT * FROM blogtable t WHERE t.author."Prénom" = 0;
0 row returned

You need 15 minutes and

Step1. Start a container image using Oracle NoSQL Database KVLite CE

docker pull ghcr.io/oracle/nosql:latest-ce
docker tag ghcr.io/oracle/nosql:latest-ce oracle/nosql:ce
docker run -d --name=kvlite --hostname=kvlite --env KV_PROXY_PORT=8080 \
-p 8080:8080 oracle/nosql:ce

Step 2. Clone the Github oracle/nosql-examples repository or just retrieve the express-oracle-nosql-example.zip file

# Clone the Github repository
# git clone https://github.com/oracle/nosql-examples.git
# cd nosql-examples
# Use the express-oracle-json-collection.zip file from the GitHub Repository
curl -L https://github.com/oracle/nosql-examples/raw/master/zips/express-oracle-json-collection.zip -o express-oracle-json-collection.zip
unzip express-oracle-json-collection.zip
rm express-oracle-json-collection.zip
cd examples-nosql-node-sdk/express-oracle-json-collection

Step 3. Install the required packages using npm

$ node -v
v16.20.2
$ npm -v
8.19.4
$ npm install express --save
$ npm install oracle-nosqldb --save
$ npm install fs --save

Step 4. Review the application code

$ cat express-oracle-nosql.js

Step 5. Running the express App

$ export NOSQL_ENDPOINT=localhost
$ export NOSQL_PORT=8080
$ node create-table.js
$ node express-oracle-nosql.js

Step 6. Test the API Endpoints

  • POST: to create data
curl -X 'POST' \
'http://localhost:3000/' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{ "blog": "Creating an empty blog from Node.js"}'

use the generatedValue returned as a UUID for GET and DELETE

  • GET: to read data
curl -X 'GET' \
'http://localhost:3000/b39eff21-14ed-4bbc-b86c-f8a76823244f' \
-H 'accept: application/json'
curl -X 'GET' \
'http://localhost:3000/?page=0&limit=10' \
-H 'accept: application/json'
  • POST: to update data
curl -X 'POST' \
'http://localhost:3000/' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": "1d70cf5d-8847-4ec2-aa74-447f0035266b",
"blog": "Updating an empty blog from Node.js"}
}'
  • DELETE: to delete data
curl -X 'DELETE' \
'http://localhost:8000/b39eff21-14ed-4bbc-b86c-f8a76823244f'

Oracle Developers and Oracle OCI Free Tier

Join our Oracle Developers channel on Slack to discuss this and other topics!

Build, test, and deploy your applications on Oracle Cloud — for free! Get access to OCI Cloud Free Tier!

--

--

Dario Vega
Oracle Developers

Product Manager ☁️ noSQL | inMemory | OCI | cloud-native | serverless | Architecture | Development | Open Source | DevRel