Trong bài này, chúng ta sẽ hướng dẫn bạn phát triển các thao tác Tạo, Đọc, Cập nhật và Xóa (CRUD) cho API RESTful sử dụng Express.js và MongoDB làm cơ sở dữ liệu.

Các thao tác CRUD là các chức năng cơ bản của một hệ thống cơ sở dữ liệu cho phép tạo, đọc, cập nhật và xóa các bản ghi được lưu trữ trong cơ sở dữ liệu.

Trong hướng dẫn này, chúng tôi sẽ sử dụng Node.js, Express.js và MongoDB để triển khai các thao tác CRUD.

Yêu cầu trước khi bắt đầu

Trước khi bắt đầu, bạn nên có hiểu biết cơ bản về các khái niệm sau:

  • Node.js
  • Express.js
  • MongoDB
  • REST API

Xem bài trước: Học lập trình Node.js: Xây dựng RESTful API với Node.js và Express.js

Hiểu về các thao tác CRUD

CRUD là viết tắt của Create (Tạo), Read (Đọc), Update (Cập nhật) và Delete (Xóa).

Các thao tác này rất quan trọng trong bất kỳ hệ thống cơ sở dữ liệu nào, bao gồm cả cơ sở dữ liệu NoSQL như MongoDB. Trong API RESTful, các thao tác CRUD tương ứng với các phương thức HTTP, như sau:

Phương thức HTTP Thao tác
POST Tạo
GET Đọc
PUT Cập nhật
DELETE Xóa

 

Thiết lập dự án

Hãy bắt đầu bằng cách thiết lập dự án của chúng ta. Chúng ta sẽ sử dụng các gói thư viện sau:

  • Express.js – Một framework web nhanh và tối giản cho Node.js.
  • Mongoose – Một thư viện ORM (Object-Relational Mapping) cho MongoDB.

Tạo một thư mục mới cho dự án của bạn có tên là node-express-mongodb-crud với lệnh sau:

mkdir node-express-mongodb-crud cd node-express-mongodb-crud npm init -y

Tiếp theo, chúng ta sẽ cài đặt các gói thư viện cần thiết:

npm install express mongoose body-parser --save
  • Gói express được sử dụng để tạo máy chủ và xử lý các yêu cầu HTTP
  • Gói mongoose được sử dụng để kết nối với MongoDB và xác định mô hình dữ liệu.
  • Gói body-parser được sử dụng để phân tích và lấy data từ phần thân (body data) của yêu cầu gửi từ trình duyệt, với thuộc tính có sẵn t req.body.

Kết nối đến CSDL MongoDB

Trước khi chúng ta có thể sử dụng MongoDB trong dự án, chúng ta phải kết nối với Mongo server.

Tạo một thư mục mới có tên config ở thư mục gốc của dự án. Trong thư mục đó, tạo một tệp có tên database.js. Copy đoạn mã sau vào tệp này:

module.exports = { url: 'mongodb://localhost:27017/mydb' };

Đoạn mã này xác định URL cho máy chủ MongoDB mà chúng ta sẽ sử dụng. Bạn nên thay đổi URL để phù hợp với cấu hình máy chủ MongoDB của bạn.

Tiếp theo, hãy tạo một tệp mới có tên server.js ở gốc dự án của bạn. Copy đoạn mã sau vào tệp này:

const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');

const app = express();

const dbConfig = require('./config/database');

mongoose.Promise = global.Promise;

// Kết nối đến cơ sở dữ liệu
mongoose.connect(dbConfig.url, {
  useNewUrlParser: true,
  useUnifiedTopology: true
}).then(() => {
  console.log('Kết nối thành công đến cơ sở dữ liệu');
}).catch(err => {
  console.log('Không thể kết nối đến cơ sở dữ liệu. Thoát app...');
  process.exit();
});

// Phân tích các yêu cầu có loại nội dung - application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }))

// Sử dụng các yêu cầu có loại nội dung - application/json
app.use(bodyParser.json())

// Xác định một route đơn giản
app.get('/', (req, res) => {
  res.json({'message': 'Chào mừng đến với ứng dụng của tôi'});
});

// Lắng nghe các yêu cầu
app.listen(3000, () => {
  console.log('Máy chủ đang lắng nghe trên cổng 3000'); 
});

Ở đây, chúng ta đã tạo một máy chủ Express.js mới và kết nối đến máy chủ MongoDB của chúng ta bằng cách sử dụng Mongoose. Chúng ta cũng định nghĩa một route đơn giản có thể truy cập bằng cách gửi một yêu cầu GET đến URL gốc.

Bạn có thể chạy máy chủ này bằng cách sử dụng lệnh sau:

node server.js

Nếu mọi thứ được thiết lập chính xác, bạn sẽ thấy thông báo sau trong cửa sổ terminal của bạn:

Máy chủ đang lắng nghe trên cổng 3000. Kết nối thành công đến cơ sở dữ liệu

Định nghĩa mô hình dữ liệu (data model)

Trước khi chúng ta có thể bắt đầu triển khai các thao tác CRUD, chúng ta cần định nghĩa một mô hình dữ liệu.

Đối với hướng dẫn này, chúng ta sẽ tạo một mô hình đơn giản để quản lý người dùng. Tạo một thư mục mới có tên models ở thư mục gốc của dự án và trong thư mục đó, tạo một tệp có tên user.js.

Copy đoạn mã sau vào tệp này:

const mongoose = require('mongoose');

const UserSchema = mongoose.Schema({
  name: String,
  age: Number,
  email: String
}, {
  timestamps: true
});

module.exports = mongoose.model('User', UserSchema);

Đoạn mã này định nghĩa model User, bao gồm các trường name, ageemail. Tùy chọn timestamp trong model tạo các trường createdAtupdatedAt. Model này sau đó được xuất ra dưới dạng một mô hình Mongoose.

Triển khai các thao tác CRUD

Bây giờ khi chúng ta đã xác định mô hình dữ liệu (data model), chúng ta có thể bắt đầu triển khai các thao tác CRUD để quản lý người dùng.

Tạo người dùng mới

Đầu tiên, triển khai thao tác Tạo/CREATE. Chúng ta sẽ sử dụng phương thức POST để tạo một người dùng mới.

Thêm đoạn mã sau vào tệp server.js của bạn:

const User = require('./models/user');

// Tạo một người dùng mới
app.post('/users', (req, res) => {
// Tạo một người dùng mới
const user = new User({
  name: req.body.name || 'Người dùng không tên', 
  age: req.body.age || 0, 
  email: req.body.email
});

// Lưu người dùng vào cơ sở dữ liệu
user.save()
  .then(data => { res.send(data); })
  .catch(err => { 
    res.status(500).send({
      message: err.message || 'Đã xảy ra lỗi trong quá trình tạo người dùng'
    }); 
  }); 
});

Ở đây, chúng ta định nghĩa một route mới để tạo người dùng mới bằng cách sử dụng phương thức POST. Chúng ta tạo một đối tượng User mới với dữ liệu được cung cấp từ phần thân yêu cầu và sau đó lưu nó vào cơ sở dữ liệu bằng cách sử dụng phương thức save().

Nếu người dùng được tạo thành công, chúng ta gửi dữ liệu người dùng mới trong phản hồi. Nếu không, chúng ta trả lại thông báo lỗi.

Truy xuất tất cả người dùng

Tiếp theo, hãy triển khai thao tác Đọc/READ. Chúng ta sẽ sử dụng phương thức GET để truy xuất tất cả người dùng. Thêm đoạn mã sau vào tệp `server.js` của bạn:

// Truy xuất tất cả người dùng

app.get('/users', (req, res) => { 
  User.find()
    .then(users => {
      res.send(users); })
    .catch(err => {
      res.status(500).send({
        message: err.message || 'Đã xảy ra lỗi trong quá trình truy xuất người dùng'
      }); 
    }); 
});

Ở đây, chúng ta định nghĩa một route mới để truy xuất tất cả người dùng bằng cách sử dụng phương thức GET. Chúng ta sử dụng phương thức find() để truy xuất tất cả người dùng từ cơ sở dữ liệu.

Nếu người dùng được truy xuất thành công, chúng ta gửi chúng trong phản hồi. Nếu không, chúng ta trả lại thông báo lỗi.

Truy xuất một người dùng duy nhất

Chúng ta cũng có thể truy xuất một người dùng duy nhất dựa trên ID của user đó.

Chúng ta sẽ sử dụng phương thức GET một lần nữa cho thao tác này.

Thêm đoạn mã sau vào tệp server.js của bạn:

// Truy xuất một người dùng duy nhất với id
app.get('/users/:userId', (req, res) => {
  User.findById(req.params.userId).then(user => {
    if(!user) {
      return res.status(404).send({
        message: 'Không tìm thấy người dùng với id ' + req.params.userId
      }); 
    }

    res.send(user); 
  }).catch(err => {
    if(err.kind === 'ObjectId') {
      return res.status(404).send({
        message: 'Không tìm thấy người dùng với id ' + req.params.userId }); 
    }
    return res.status(500).send({
      message: 'Lỗi trong quá trình truy xuất người dùng với id ' + req.params.userId
    }); 
  }); 
});

Ở đây, chúng ta định nghĩa một route mới để truy xuất một người dùng duy nhất bằng cách sử dụng phương thức GET với một tham số động cho ID người dùng.

Chúng ta sử dụng phương thức findById() để truy xuất người dùng với ID được cung cấp.

Nếu người dùng được tìm thấy, chúng ta gửi dữ liệu người dùng trong phản hồi. Nếu không, chúng ta trả lại thông báo lỗi. Nếu ID được cung cấp không hợp lệ hoặc không tìm thấy người dùng, chúng ta trả lại thông báo lỗi thích hợp.

Cập nhật người dùng

Tiếp theo, hãy triển khai thao tác Cập nhật/UPDATE.

Chúng ta sẽ sử dụng phương thức PUT để cập nhật người dùng hiện có.

Thêm đoạn mã sau vào tệp `server.js` của bạn:

// Cập nhật người dùng với id

app.put('/users/:userId', (req, res) => { 
  // Tìm người dùng và cập nhật nó với nội dung yêu cầu
  User.findByIdAndUpdate(req.params.userId, 
    { 
      name: req.body.name || 'Người dùng không tên', 
      age: req.body.age || 0, 
      email: req.body.email
    }, {
      new: true
    })
  .then(user => {
    if(!user) {
      return res.status(404).send({ message: 'Không tìm thấy người dùng với id ' + req.params.userId }); 
    }
    res.send(user); 
  })
  .catch(err => {
    if(err.kind === 'ObjectId') {
      return res.status(404).send({ message: 'Không tìm thấy người dùng với id ' + req.params.userId }); 
    }
    return res.status(500).send({ message: 'Lỗi trong quá trình cập nhật người dùng với id ' + req.params.userId });
  });
});

Ở đây, chúng ta định nghĩa một route mới để cập nhật người dùng bằng cách sử dụng phương thức PUT với một tham số động cho ID người dùng.

Chúng ta sử dụng phương thức findByIdAndUpdate() để tìm người dùng với ID được cung cấp và cập nhật dữ liệu của họ với dữ liệu mới từ phần thân yêu cầu.

Nếu người dùng được cập nhật thành công, chúng ta gửi dữ liệu người dùng đã cập nhật trong phản hồi. Nếu không, chúng ta trả lại thông báo lỗi.

Xóa người dùng

Cuối cùng, hãy triển khai thao tác Xóa/DELETE. Chúng ta sẽ sử dụng phương thức DELETE để xóa người dùng hiện có.

Thêm đoạn mã sau vào tệp server.js của bạn:

// Xóa người dùng với id
app.delete('/users/:userId', (req, res) => {
  User.findByIdAndRemove(req.params.userId).then(user => {
    if(!user) {
      return res.status(404).send({
        message: 'Không tìm thấy người dùng với id ' + req.params.userId
      });
    }
    res.send({message: 'Người dùng đã được xóa thành công!'});
  })
  .catch(err => {
    if(err.kind === 'ObjectId' || err.name === 'NotFound') {
      return res.status(404).send({
        message: 'Không tìm thấy người dùng với id ' + req.params.userId
      });
    }
    return res.status(500).send({
      message: 'Không thể xóa người dùng với id ' + req.params.userId
    });
  });
});

Ở đây, chúng ta định nghĩa một route mới để xóa người dùng bằng cách sử dụng phương thức DELETE với một tham số động cho ID người dùng.

Chúng ta sử dụng phương thức findByIdAndRemove() để tìm người dùng với ID được cung cấp và loại bỏ record đó khỏi cơ sở dữ liệu.

Nếu người dùng được xóa thành công, chúng ta trả lại thông báo thành công trong phản hồi. Nếu không, chúng ta trả lại thông báo lỗi.

Kết luận

Trong hướng dẫn này, chúng ta đã tìm hiểu cách triển khai các thao tác CRUD cho API RESTful bằng cách sử dụng Node.js, Express.js và MongoDB. Với kiến thức này, bạn sẽ có thể tạo API của riêng mình và quản lý dữ liệu bằng những công cụ mạnh mẽ và thông dụng này.

Chúng tôi hy vọng bạn đã tìm thấy hướng dẫn này hữu ích. Nếu bạn có bất kỳ câu hỏi hoặc phản hồi nào, vui lòng để lại bình luận dưới đây.

BÀI TIẾP THEO: NodeJS: Triển khải bảo mật cho API với JWT và Passport.js

Leave a Reply

Discover more from Bệ Phóng Việt

Subscribe now to keep reading and get access to the full archive.

Continue reading