Key-Value Store Using Node.js and Redis¶
In this tutorial, we'll create a simple key-value store application using Node.js and Redis. This application will allow you to set and get key-value pairs via HTTP requests. Additionally, we'll place this Node.js application behind an NGINX reverse proxy to demonstrate a common production setup.
Overview: System Architecture¶
This system facilitates setting and retrieving key-value pairs through HTTP requests. To mimic a realistic production environment, the Node.js application is configured to operate behind an NGINX reverse proxy. The system architecture comprises the following components:
Node.js Application: Serves as the core of our key-value store, providing an API to set and get key-value pairs.
Redis Server: Acts as the data storage layer, optimized for high-performance key-value data operations. Redis stores the data set and retrieves operations requested by the Node.js application.
NGINX Server: Configured as a reverse proxy, NGINX forwards incoming HTTP requests to the Node.js application. This layer adds an additional level of security and load balancing, making the application more robust and scalable.
The integration of these components creates a seamless workflow where NGINX handles incoming requests and directs them to the Node.js application, which in turn interacts with Redis to perform data operations. This setup is indicative of modern web application architectures, offering scalability, flexibility, and enhanced security.
Data Storage: Setting up Redis¶
Start a Redis server on UCloud. We assume Redis is served on the default port 6379
.
Web Server: Setting up NGINX¶
Start a new NGINX web server on UCloud with the optional parameters:
Connect to other jobs: Select the Job ID of the running Redis instance and specify a hostname.
Configure custom links to your application: Add a public URL which will be used to connect to the key-value store.
In the following we will fix the parameters:
Redis hostname:
redis-server
Public link:
app-mykvstore.cloud.sdu.dk
Node.js Connectivity: Establishing the Interface¶
Open a terminal window inside the running NGINX instance.
Initialize the project¶
Create a new directory for the project and initialize a new Node.js application:
$ mkdir key-value-store && cd key-value-store
$ npm init -y
Install dependencies¶
Install express
for the web server framework and redis
for interacting with Redis:
$ npm install express redis
Create the application¶
In the project directory, open a terminal editor and create a new file named app.js
with the following content:
const express = require('express');
const redis = require('redis');
const app = express();
app.use(express.json());
const redisClient = redis.createClient({
url: 'redis://redis-server:6379'
});
redisClient.on('error', (err) => console.log('Redis Client Error', err));
redisClient.connect();
app.post('/set', async (req, res) => {
const { key, value } = req.body;
await redisClient.set(key, value);
res.send(`Key ${key} set with value ${value}`);
});
app.get('/get/:key', async (req, res) => {
const { key } = req.params;
const value = await redisClient.get(key);
if (value) {
res.send(`Value for key ${key} is ${value}`);
} else {
res.send(`Key ${key} not found`);
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
The app is served by default on port 3000
.
Note
The connection string to the Redis server contains the hostname (in this case redis-server
) defined when we submitted the NGINX instance.
Run the application¶
Start the Node.js application with:
$ nohup node app &
The application runs in background.
NGINX Configuration: Proxy Setup¶
Edit the default NGINX configuration file /etc/nginx/nginx.conf
to reverse proxy requests to the Node.js application:
# /etc/nginx/nginx.conf
worker_processes auto;
error_log /dev/stdout info;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server {
listen 8080 so_keepalive=on;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
After configuring NGINX, remember to reload the NGINX configuration:
$ nginx -t
$ nginx -s reload
Evaluation: Testing the Store¶
Open a terminal window on your local host and use curl
to test the set and get functionalities.
To set a value:
$ curl -X POST https://app-mykvstore.cloud.sdu.dk/set -H "Content-Type: application/json" -d '{"key":"myKey", "value":"myValue"}'
To get a value:
$ curl https://app-mykvstore.cloud.sdu.dk/get/myKey
Conclusion: Reflecting on the Build¶
We have created a simple key-value store application using Node.js and Redis, accessible through an NGINX reverse proxy. This setup demonstrates how to integrate a Node.js application with a Redis data store running on UCloud and how to use NGINX to manage incoming traffic from a remote host to your application.
Contents