Tích Hợp MongoDB

Trong bài học này chúng ta sẽ tích hợp chạy MongoDB database với Node.js để lưu dữ liệu ứng dụng trên server.

Lưu ý: Bạn cần chắc chắn rằng MongoDB đã được cài đặt và đang chạy trên máy. Nếu máy tính của bạn chưa có MongoDB thì bạn có thể tham khảo hướng dẫn cài đặt MongoDB (hoặc hướng dẫn cài đặt MongoDB phiên bản mới nhất trên Ubuntu LTS).

Bước 6.1: Khởi Tạo Dữ Liệu

Ở bước này chúng ta sẽ tạo dữ liệu ban đầu (hay thường gọi là seeding) cho database. Mục đích của việc làm này thường là để kiểm tra các tính năng của ứng dụng vẫn hoạt động bình thường trường hợp không sử dụng DB.

Trong thư mục scripts chúng ta sẽ tạo một tập tin với tên init.mmongo.js với nội dung sau:

#!/usr/bin/mongo

var db = new Mongo().getDB("bugsdb");

db.bugs.remove({});

db.bugs.insert([
  {id: 1, priority: 'P1', status:'Open', owner:'Jessica Bánh Bèo', title:'Jessica Bánh Bèo'},
  {id: 2, priority: 'P2', status:'New', owner:'Eddie Tí Tèo', title:'Thiếu canh lề CSS cho văn bản trong table'},

]);

Trong tập tin trên đầu tiên chúng ta tham chiếu tới Mongo Shell (hay mongo), Mongo Shell cung cấp API hỗ trợ thực hiện các tác vụ quản lý database sử dụng JavaScript (Node.js):

#!/usr/bin/mongo

Sau đó khởi tạo kết nối tới database với tên là bugsdb trên MongoDB server:

var db = new Mongo().getDB("bugsdb"); 

Hai câu lệnh phía trên tương tự như việc bạn kết nối tới MongoDB server sử dụng Mongo Shell client (hay mongo) trên terminal:

$ mongo

Rồi tạo (hoặc sử dụng) database như sau:

> use bugsdb

Nếu bugsdb chưa có Mongo sẽ tạo database này cho chúng ta, ngược lại kết nối sẽ được hình thành giữa server và client. Bấm Ctrl + C để thoát kết nối tới DB server tạo bởi mongo.

Trở lại với tập tin init.mongo.js, ở câu lệnh tiếp theo đó sẽ thực hiện việc xoá toàn bộ dữ liệu có trêhn bugs collection (nếu bạn quên thị nhắc lại trong NoSQL một collection tương tự như một bảng trong cơ sở dữ liệu có quan hệ).

db.bugs.remove({});

Với câu lệnh cuối cùng chúng ta sẽ thực hiện việc thêm 2 document vào bugs collection (document trong NoSQL tương tự như record trong CSDL có quan hệ):

db.bugs.insert([
  {id: 1, priority: 'P1', status:'Open', owner:'Jessica Bánh Bèo', title:'Jessica Bánh Bèo'},
  {id: 2, priority: 'P2', status:'New', owner:'Eddie Tí Tèo', title:'Thiếu canh lề CSS cho văn bản trong table'},

]);

Sau đó lưu nội dung của tập tin và chạy tập tin này sử dụng Node.js trên terminal:

$ node scripts/init.mongo.js

Bạn có thể kiểm tra lại dữ liệu được thêm vào sử dụng mongo client. Kết nối tới database bugsdb trên MongoDB server và chạy câu lệnh sau:

> db.bugs.find();

Bạn sẽ thấy hai document mới được thêm vào hiển thị ở kết quả trả về.

So sánh thay đổi trong source code ở bước 6.1 ở đây.

Bước 6.2: Kết Nối Và Đọc Dữ Liệu

Ở bước này chúng ta sẽ thực hiện việc kết nối tới database và lấy dữ liệu về thông qua sử dụng mô-đun Node.js có tên là mongodb. Đầu tiên chúng ta cần cài đặt mô-đun này sử dụng câu lệnh dưới đây (bạn đừng quên tuỳ chọn --save trong câu lệnh):

$ npm install --save mongodb@2.1.2

Tiếp theo chúng ta sẽ nạp vào MongoDB client sử dụng mô-đun này. Trong tập tin webapp.js ngay dưới dòng khai báo biến bodyParser bạn thêm dòng lệnh sau:

var MongoClient = require('mongodb').MongoClient;

Sau đó dưới dòng khai báo biến app khởi tạo Express framework bạn thêm khai báo biến db dùng để kết nối tới database:

var db;

Cập nhật lại đoạn code khởi tạo server ở cuối tập tin này để thực hiện việc kết nối tới MongoDB server trước khi khởi tạo server:

MongoClient.connect('mongodb://localhost/bugsdb', function(err, dbConnection) {
  db = dbConnection;
  var server = app.listen(3000, function() {
      var port = server.address().port;
      console.log("Started server at port", port);
  });
});

Ở trên sau khi kết nối tới MongoDB server thành công chúng ta gán lại giá trị của biến db khai báo trước đó bằng đối tượng dbConnection rồi sau đó mới thực hiện việc khởi tạo và chạy app server.

Một công việc cuối cùng ở bước này chúng ta cần làm đó là lấy dữ liệu trong bugs collection mà mới được thêm ở bước 6.1. Trong webapp.js cập nhật lại đoạn code API dùng để lấy về danh sách bug thành như sau:

app.get('/api/bugs', function(req, res) {
  db.collection("bugs").find().toArray(function(err, docs) {
    res.json(docs);
  });
});

Sau khi lưu thay đổi bạn cần khởi động lại Node.js server để các thay đổi này có hiệu lực. Sau đó kiểm tra lại bằng cách truy cập vào địa chỉ http://localhost:300/api/bugs. Nếu làm theo đúng hướng dẫn bạn sẽ thấy dữ liệu của hai document trả về theo kiểu format JSON.

Tuy nhiên bạn cũng để ý trong dữ liệu trả về thì Mongo sử dụng trường _id để lưu trữ ID của document thay vì id. Do đó bạn cần cập nhật đoạn code trong khi render BugRow component:

<td>{this.props.bug._id}</td>

Tương tự cập nhật cho phương thức render() trong BugTable component:

<BugRow key={bug._id} bug={bug} />

So sánh thay đổi trong source code ở bước 6.2 ở đây.

Bước 6.3: Viết Dữ Liệu Lên DB

Ở bước 6.2 chúng ta đã cập nhật API để thực hiện việc kết nối và lấy dữ liệu từ MongoDB database. Ở bước này chúng ta sẽ tiếp tục cập nhật API để khi thêm vào một bug thì dữ liệu của bug thêm vào này sẽ được lưu vào database.

Trong tập tin webapp.js cập nhật Post API xử lý request tạo thêm bug thành như sau:

app.post('/api/bugs/', function(req, res) {
  console.log("Req body:", req.body);
  var newBug = req.body;
  db.collection("bugs").insertOne(newBug, function(err, result) {
    var newId = result.insertedId;
    db.collection("bugs").find({_id: newId}).next(function(err, doc) {
      res.json(doc);
    });
  });
});

Trong đoạn code trên đầu tiên chúng ta sẽ lấy ra dữ liệu của request body:

var newBug = req.body;

Lúc này giá trị của newBug sẽ là một object với thuộc tính là các trường và dữ liệu tương ứng gửi từ request. Ví dụ:

{
    title: "AAA",
    status: "open",
    priority: "P1"
    ...
}

Sau đó thêm một docuemtn vào bugs collection với dữ liệu lấy từ newBug và trả về response là dữ liệu document mới thêm vào dưới dạng format JSON:

...
    db.collection("bugs").insertOne(newBug, function(err, result) {
      var newId = result.insertedId;
      db.collection("bugs").find({_id: newId}).next(function(err, doc) {
        res.json(doc);
      });
    });
...

Ở trên đây bạn cũng lưu ý do MongoDB là cơ sở dữ liệu dạng NoSQL nên không có bất cứ ràng buộc nào về tên cũng như số lượng trường (field hay column) được thêm vào document. Trong các ứng dụng thực tế chúng ta sẽ cần phải thực hiện một bước validate dữ liệu trước khi lưu vào DB.

So sánh thay đổi trong source code ở bước 6.3 ở đây.

Nội dung không được để trống

Hướng Dẫn Liên Quan