Skip to main content

Express

Express is a lightweight and flexible Node.js Web framework renowned for its simplicity and high scalability. It features a concise API design with middleware support, enabling rapid development of RESTful APIs or full-stack applications. With a rich plugin ecosystem, Express seamlessly integrates functionalities like databases and authentication while maintaining high performance and low learning curve, making it a top choice among Node.js developers.

This guide describes how to deploy an Express application on CloudBase HTTP cloud functions.

Prerequisites

Before you begin, make sure you have:

  • Have Node.js 18.x or later versions installed
  • Have a Tencent Cloud account with CloudBase service activated
  • Have basic knowledge of Node.js and Express development

Step 1: Create an Express Application

💡 Tip: If you already have an Express application, you can skip this step.

Create a Project Directory

mkdir express-cloudbase
cd express-cloudbase

Use Express Generator to Create an Application

# Use Express Generator to Create an Application
npx express-generator --view=pug express-app

# Go to the project directory
cd express-app

# Install dependency.
npm install

This will create an Express application using Pug as the view engine.

Test the Application Locally

Start up the development server:

npm start

Open a browser and visit http://localhost:3000, you should see the Express welcome page.

Step 2: Add API Routes

Let's create a RESTful API to demonstrate the features of Express.

Create User Routes

Create the users.js file in the routes directory:

const express = require('express');
const router = express.Router();

// Mock user data
const users = [
{ id: 1, name: 'zhangsan', email: 'zhangsan@example.com' },
{ id: 2, name: 'lisi', email: 'lisi@example.com' },
{ id: 3, name: 'wangwu', email: 'wangwu@example.com' }
];

/* GET users listing */
router.get('/', function(req, res, next) {
const { page = 1, limit = 10 } = req.query;
const startIndex = (page - 1) * limit;
const endIndex = startIndex + parseInt(limit);

const paginatedUsers = users.slice(startIndex, endIndex);

res.json({
success: true,
data: {
total: users.length,
page: parseInt(page),
limit: parseInt(limit),
items: paginatedUsers
}
});
});

/* GET user by ID */
router.get('/:id', function(req, res, next) {
const userId = parseInt(req.params.id);
const user = users.find(u => u.id === userId);

if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}

res.json({
success: true,
data: user
});
});

/* POST create user */
router.post('/', function(req, res, next) {
const { name, email } = req.body;

if (!name || !email) {
return res.status(400).json({
success: false,
message: 'Name and email are required'
});
}

const newUser = {
id: users.length + 1,
name,
email
};

users.push(newUser);

res.status(201).json({
success: true,
data: newUser
});
});

module.exports = router;

Create Health Check Route

Create the health.js file in the routes directory:

const express = require('express');
const router = express.Router();

/* GET health check */
router.get('/', function(req, res, next) {
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
framework: 'Express',
version: process.env.npm_package_version || '1.0.0',
node_version: process.version
});
});

module.exports = router;

Update Application Configuration

Edit the app.js file to add new routes and middleware:

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var healthRouter = require('./routes/health');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('combined'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// Route Configuration
app.use('/', indexRouter);
app.use('/api/users', usersRouter);
app.use('/health', healthRouter);

// 404 Error Handling
app.use(function(req, res, next) {
next(createError(404));
});

// Global Error Handling
app.use(function(err, req, res, next) {
// Set error message to provide detailed errors only in development environment
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// Return error message in JSON format
if (req.path.startsWith('/api/') || req.path.startsWith('/health')) {
res.status(err.status || 500).json({
success: false,
message: err.message,
error: req.app.get('env') === 'development' ? err.stack : undefined
});
} else {
// Render error page
res.status(err.status || 500);
res.render('error');
}
});

module.exports = app;

Modify Startup Configuration

Edit the bin/www file to ensure the application listens on the correct port:

#!/usr/bin/env node

/**
* Module dependencies.
*/

var app = require('../app');
var debug = require('debug')('express-app:server');
var http = require('http');

/**
* Get port from environment and store in Express.
*/

var port = normalizePort(process.env.PORT || '9000');
app.set('port', port);

/**
* Create HTTP server.
*/

var server = http.createServer(app);

/**
* Listen on provided port, on all network interfaces.
*/

server.listen(port, '0.0.0.0');
server.on('error', onError);
server.on('listening', onListening);

/**
* Normalize a port into a number, string, or false.
*/

function normalizePort(val) {
var port = parseInt(val, 10);

if (isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// port number
return port;
}

return false;
}

/**
* Event listener for HTTP server "error" event.
*/

function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}

var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;

// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}

/**
* Event listener for HTTP server "listening" event.
*/

function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
console.log('Express server listening on ' + bind);
}

Step 3: Test Locally

⚠️ Important Notice: CloudBase HTTP cloud function requires the application to listen on port 9000.

Start up the application:

npm start

Test API interfaces:

# Test Health Check
curl http://localhost:9000/health

# Test User List
curl http://localhost:9000/api/users

# Test Pagination
curl "http://localhost:9000/api/users?page=1&limit=2"

# Test Obtain Single User
curl http://localhost:9000/api/users/1

# Test User Creation
curl -X POST http://localhost:9000/api/users \
-H "Content-Type: application/json" \
-d '{"name":"New User","email":"newuser@example.com"}'

Step 4: Create a Startup Script

Create the scf_bootstrap file (without extension):

#!/bin/bash
export PORT=9000
npm start

Grant execute permission to the startup script:

chmod +x scf_bootstrap

💡 Note:

  • scf_bootstrap is the startup script for CloudBase cloud functions
  • Set the PORT=9000 environment variable to ensure the application listens on the correct port
  • Use npm start to start up the application

Step 5: Prepare Deployment Files

Ensure your project directory structure is as follows:

express-app/
├── bin/
│ └── www # Startup files
├── public/ # Static resources
├── routes/ # Route files
│ ├── index.js
│ ├── users.js
│ └── health.js
├── views/ # View templates
├── app.js # Main application file
├── package.json # Project configuration
├── package-lock.json # Lock file
└── scf_bootstrap # Startup script

Step 6: Deploy to CloudBase HTTP Cloud Function

Deploy via the Console

  1. Log in to the CloudBase Console
  2. Select your environment and go to the [Cloud Function] page
  3. Click [New Cloud Function]
  4. Select [HTTP cloud function]
  5. Fill in the function name (for example: express-app)
  6. Select runtime: Node.js 18.x (or other supported versions)
  7. Select submission method: Local folder upload
  8. Select the express-app directory for function code upload
  9. Automatic Dependency Installation: Enable this option
  10. Click the "Create" button and wait for the deployment to complete.

Deploy via CLI (Coming Soon)

Package and deploy

If you need to package manually:

# Create Deployment Package (excluding development files)
zip -r express-app.zip . -x "node_modules/*" ".git/*" "*.log"

Step 7: Access Your Application

After successful deployment, you can refer to Accessing Cloud Functions via HTTP to configure custom domain access for

You can test the following APIs:

  • Root Path: / - Express Welcome Page
  • Health Check: /health - View Application Status
  • User List: /api/users - Get User List
  • User Details: /api/users/1 - Obtain a Specific User
  • Create User: POST /api/users - Create a New User

Frequently Asked Questions

Q: Why must I use port 9000?

A: The CloudBase HTTP cloud function requires the application to listen on port 9000, which is the standard configuration of the platform.

Q: How do I handle static files?

A: The static file middleware of Express automatically processes static resources in the public directory.

Q: How do I view application logs?

A: On the CloudBase console's cloud function page, click the function name to go to the details page and view the running logs.

Q: Which Node.js versions are supported?

A: CloudBase supports Node.js versions such as 16.x, 18.x, 20.x, etc. It is recommended to use the latest LTS version.

Q: How do I handle CORS cross-origin issues?

A: You can use the cors middleware or manually set response headers to handle cross-origin requests.

Best Practices

1. Environment Variable Management

Add environment variable support in app.js:

// Load environment variables
require('dotenv').config();

// Use environment variables
const isDevelopment = process.env.NODE_ENV === 'development';
const port = process.env.PORT || 9000;

2. Adding CORS Support

Install and configure the CORS middleware:

npm install cors
const cors = require('cors');

// Configure CORS
app.use(cors({
origin: process.env.ALLOWED_ORIGINS?.split(',') || '*',
credentials: true
}));

3. Request Log

Use the Morgan middleware to log request logs:

const morgan = require('morgan');

// Configure log format
app.use(morgan(process.env.NODE_ENV === 'production' ? 'combined' : 'dev'));

4. Error Handling

Implement global error handling middleware:

// Global Error Handling
app.use((err, req, res, next) => {
console.error(err.stack);

res.status(err.status || 500).json({
success: false,
message: err.message,
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
});
});

5. Security Configuration

Install and configure the Helmet middleware:

npm install helmet
const helmet = require('helmet');

// Configure security headers
app.use(helmet());

Advanced Features

Database Integration

Integrate MongoDB or MySQL:

npm install mongoose
# Or
npm install mysql2

Authentication

Add JWT Authentication:

npm install jsonwebtoken bcryptjs

API Documentation

Use Swagger to generate API documentation:

npm install swagger-jsdoc swagger-ui-express

Next Steps