Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Express.js Database Integration

Integrating databases with Express.js applications allows you to store, retrieve, and manage data efficiently. This guide covers key concepts, examples, and best practices for integrating different databases with Express.js.

Key Concepts of Database Integration

  • Database Drivers: Libraries that enable Node.js applications to communicate with databases.
  • ORM (Object-Relational Mapping): Tools that map database tables to JavaScript objects, simplifying database operations.
  • Connection Pooling: A technique to manage database connections efficiently.
  • Query Builders: Tools that help build SQL queries programmatically.

Setting Up a Database

Install the necessary database driver or ORM for your chosen database. Here, we'll cover examples for MongoDB, MySQL, and PostgreSQL.

Using MongoDB with Mongoose

Installation

npm install mongoose --save

Example: Connecting to MongoDB

// mongodb.js
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const port = 3000;

// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
    console.log('Connected to MongoDB');
});

// Define a schema and model
const userSchema = new mongoose.Schema({
    name: String,
    email: String,
});

const User = mongoose.model('User', userSchema);

// Routes
app.get('/users', async (req, res) => {
    const users = await User.find();
    res.json(users);
});

app.post('/users', async (req, res) => {
    const user = new User(req.body);
    await user.save();
    res.json(user);
});

app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}/`);
});

Using MySQL with Sequelize

Installation

npm install mysql2 sequelize --save

Example: Connecting to MySQL

// mysql.js
const express = require('express');
const { Sequelize, DataTypes } = require('sequelize');
const app = express();
const port = 3000;

// Connect to MySQL
const sequelize = new Sequelize('mydatabase', 'username', 'password', {
    host: 'localhost',
    dialect: 'mysql',
});

// Define a model
const User = sequelize.define('User', {
    name: {
        type: DataTypes.STRING,
        allowNull: false,
    },
    email: {
        type: DataTypes.STRING,
        allowNull: false,
    },
});

// Sync database
sequelize.sync();

// Routes
app.get('/users', async (req, res) => {
    const users = await User.findAll();
    res.json(users);
});

app.post('/users', async (req, res) => {
    const user = await User.create(req.body);
    res.json(user);
});

app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}/`);
});

Using PostgreSQL with pg and knex

Installation

npm install pg knex --save

Example: Connecting to PostgreSQL

// postgresql.js
const express = require('express');
const knex = require('knex')({
    client: 'pg',
    connection: {
        host: 'localhost',
        user: 'username',
        password: 'password',
        database: 'mydatabase',
    },
});
const app = express();
const port = 3000;

// Define routes
app.get('/users', async (req, res) => {
    const users = await knex.select('*').from('users');
    res.json(users);
});

app.post('/users', async (req, res) => {
    const [id] = await knex('users').insert(req.body).returning('id');
    const user = await knex('users').where({ id }).first();
    res.json(user);
});

app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}/`);
});

Best Practices for Database Integration

  • Use Environment Variables: Store database connection details in environment variables for security and flexibility.
  • Connection Pooling: Use connection pooling to manage database connections efficiently.
  • Data Validation: Validate and sanitize user inputs before storing them in the database.
  • Error Handling: Implement robust error handling for database operations to manage runtime exceptions.
  • ORMs and Query Builders: Use ORMs and query builders to simplify database operations and improve code maintainability.

Testing Database Integration

Test your database integration using frameworks like Mocha, Chai, and Supertest:

Example: Testing Database Integration

// Install Mocha, Chai, and Supertest
// npm install --save-dev mocha chai supertest

// test/db.test.js
const chai = require('chai');
const expect = chai.expect;
const request = require('supertest');
const express = require('express');
const mongoose = require('mongoose');

// Connect to MongoDB for testing
mongoose.connect('mongodb://localhost:27017/testdatabase', { useNewUrlParser: true, useUnifiedTopology: true });

const User = mongoose.model('User', new mongoose.Schema({
    name: String,
    email: String,
}));

const app = express();
app.use(express.json());

app.get('/users', async (req, res) => {
    const users = await User.find();
    res.json(users);
});

app.post('/users', async (req, res) => {
    const user = new User(req.body);
    await user.save();
    res.json(user);
});

describe('GET /users', () => {
    it('should return an array of users', (done) => {
        request(app)
            .get('/users')
            .expect('Content-Type', /json/)
            .expect(200)
            .end((err, res) => {
                if (err) return done(err);
                expect(res.body).to.be.an('array');
                done();
            });
    });
});

describe('POST /users', () => {
    it('should create a new user', (done) => {
        request(app)
            .post('/users')
            .send({ name: 'John Doe', email: 'john@example.com' })
            .expect('Content-Type', /json/)
            .expect(200)
            .end((err, res) => {
                if (err) return done(err);
                expect(res.body).to.have.property('_id');
                expect(res.body.name).to.equal('John Doe');
                done();
            });
    });
});

// Define test script in package.json
// "scripts": {
//   "test": "mocha"
// }

// Run tests with NPM
// npm run test

Key Points

  • Database Drivers: Libraries that enable Node.js applications to communicate with databases.
  • ORM (Object-Relational Mapping): Tools that map database tables to JavaScript objects, simplifying database operations.
  • Connection Pooling: A technique to manage database connections efficiently.
  • Follow best practices for database integration, such as using environment variables, connection pooling, data validation, error handling, and using ORMs and query builders.

Conclusion

Integrating databases with Express.js applications allows you to store, retrieve, and manage data efficiently. By understanding and implementing the key concepts, examples, and best practices covered in this guide, you can effectively integrate different databases with your Express.js applications. Happy coding!