Trong bài viết này chúng ta sẽ tiếp tục xây dựng việc kết nối với cơ sở dữ liệu và thực hiện một số truy vấn CRUD  đơn giản để hiểu về cách mà NodeJS tương tác với MongoDB.

Để tiếp tục theo bài viết này, bạn cần  cài đặt MongoDB nếu bạn chưa cài nó, tiếp theo hãy mở cmd lên và gõ mongo. Sau đó dùng cú pháp


use mean

để tạo database mới tên là mean

2015-07-25_065417

Ok, vậy là đã tạo db xong, tiếp theo hãy quay lại thư mục mean-tutorial của chúng ta. Để tương tác với MongoDb, mình sẽ sử dụng thư viện mongoose. Thêm “mongoose”: “~3.8.18” vào dependencies và chạy npm update. Hãy lưu ý dấu “,” giữa các dòng khai báo thư viện, mục dependencies sẽ thành thế này:

"dependencies": {
   "bower": "*",
   "express": "~4.5.1",
   "mongoose": "~3.8.18"
}

Bây giờ, hãy qua thư mục config và tạo mới file database.js, file này sẽ thiết lập kết nối với MongoDB.

module.exports = {
   url : 'mongodb://127.0.0.1:27017/mean'
}

Bạn có thể sẽ thấy một số trang nó viết phần này phức tạp hơn như kết nối thành công thì thông báo hay báo lỗi khi không kết nối được, nhưng trong tutorial này thì mình thấy điều đó không cần thiết, sao cho dễ hiểu là được. Bạn có thể viết xử lý thêm cho nó sau này.

Sửa lại nội dung file server.js

var mongoose = require('mongoose');
var db = require('./config/database');
mongoose.connect(db.url);

Ở đây mình đã đơn giản hóa việc kết nối tới mongo, chỉ cần require thư viện mongoose, file config và dùng hàm connect để kết nối, vậy là xong, quá đơn giản phải không nào 😀

Tiếp theo hãy vào thư mục app/models và tạo file post.js, trong file này ta sẽ khai báo cấu trúc của bảng posts dùng để lưu trữ các bài viết.


'use strict';

// require thư viện tương tác với mongo

var mongoose = require('mongoose');

// tạo cấu trúc bảng posts dùng hàm Schema 

var schema = mongoose.Schema({
 title:        {type: 'String', required: true, index:true},
 description:  {type: 'String', required: true},
 content:      {type: 'String', required: true},
 creationDate: {type: 'Date', required: true}

});

// export vào app với tên model là Post

module.exports = mongoose.model('Post', schema);

Ở đây cú pháp khai báo khá là đơn giản, trong đó, type là kiểu dữ liệu có thể là String, Number, Date, Boolean … Bạn có thể xem thêm về các kiểu schema type trên trang docs của nó http://mongoosejs.com/docs/schematypes.html .

Tiếp theo hãy qua app/routes/index.js. Chúng ta sẽ viết một số xử lý đơn giản, thao tác CRUD trên MongoDB. Đầu tiên ta cần require model Post trong route này, file index.js của chúng ta sẽ thành thế này.

var Post = require('../models/post');

module.exports = function (app) {

//app.get('*', function(req, res){
//res.sendfile('public/index.html');
//});
};

Tạm thời hãy ẩn đoạn code trỏ toàn bộ hàm app.get(‘*’, function(req, res){… này đi nhé, chúng ta sẽ sử dụng lại nó sau này khi làm việc với AngularJS để tạo ra ứng dụng MEAN Stack hoàn chỉnh.

Tiếp theo, hãy bắt đầu với truy vấn Create (tạo mới bài viết). Hãy thêm đoạn code này trước app.get(‘*’…


app.get('/api/post/create', function(req, res){
 var newPost = new Post();
 // tạo đối tượng thể hiện lại của model Post và gán giá trị cho các thuộc tính của nó
 newPost.title = 'This is a title';
 newPost.description = 'This is a description for this post';
 newPost.content = 'Short content, just use for demo';
 newPost.creationDate = new Date();
 newPost.save(function(err, post) {
 // sử dụng phương thức save để insert
 // đối tượng xuống database
 if (err) {
   res.send(err); // nếu có lỗi sẽ trả về thông báo lỗi
 }
 else {
   res.json(post);
 }
 // nếu thêm thành công sẽ trả về giá trị mà ta mới chèn vào dưới dạng json
 });
});

Về thực tế thì thao tác tạo mới ta phải dùng phương thức POST, tuy nhiên đây chỉ là demo và chúng ta không lấy dữ liệu từ form, vậy nên mình viết dùng phương thức GET cho dễ thực hiện.

Để chạy thử, hãy bật server lên và truy cập vào đường dẫn http://localhost:3000/api/post/create và kết quả nhận được sẽ như thế này:


{
  "__v":0,
  "creationDate":"2015-07-25T00:51:54.010Z",
  "content":"Short content, just use for demo",
  "description":"This is a description for this post",
  "title":"This is a title",
  "_id":"55b2ddaace90ba680add6091"
}

Trong đó, _id là trường mà mongo tự thêm, nó là duy nhất trong bảng posts, chúng ta sẽ dùng nó cho các thao tác sau này.

Để hiển thị bài viết này, Ta sẽ viết tiếp xử lý cho thao tác Read (đọc nội dung bài viết), thao tác này khá là đơn giản:


app.get('/api/post/list', function(req, res){
 Post.find({}).sort({creationDate: -1}).exec(function(err, posts) {
   if (err) {
     res.send(err);
   }
   else {
     res.json(posts);
   }
 });
});

Hàm find() với tham số rỗng sẽ tìm tất cả các record trong bảng posts và sắp xếp theo thứ tự ngày giảm dần, sau đó hiển thị lên dưới dạng json.

Hãy truy cập vào đường dẫn để xem kết quả. Đây là trường hợp đọc toàn bộ danh sách bài viết. Ta sẽ qua đọc 1 bài viết cụ thể.

app.get('/api/post/detail/:post_id', function(req, res){
 Post.findById(req.params.post_id).exec(function(err, post){
  if (err) {
    res.send(err);
  }
  else {
    res.json(post);
  }
 });
});

Trong đó tham số post_id truyền vào chính là _id của record mà lúc nãy ta chèn vào, truy cập vào đường dẫn http://localhost:3000/api/post/detail/55b2ddaace90ba680add6091 để xem kết quả, do chỉ có 1 record nên nó cũng giống với list ra toàn bộ thôi, hãy tự thêm một số record nữa để xem rõ hơn nha 😀

Một lưu ý là 55b2ddaace90ba680add6091 là trường _id của dòng mà ta mới thêm vào ở thao tác tạo mới nhé, lúc bạn tạo mới thì _id nó không giống cái này đâu 🙂

Tiếp theo, viết hàm xử lý thao tác Update (sửa bài viết).


app.get('/api/post/edit/:post_id', function(req, res){
 Post.findById(req.params.post_id, function(err, data){
   // Tìm record có _id là tham số truyền vào trên đường dẫn trong bảng posts
   if(err) {
     res.send(err); // nếu lỗi thì trả về thông báo lỗi ngược lại ta sẽ sửa các cột của nó
   }
   else {
     data.title = 'Title after edit';
     data.description = 'Description has many changes';
     data.content = 'Content is here';
     data.save(function(err, post) { // Lưu lại đối tượng xuống db
       if (err) {
         res.send(err);
       }
       else {
         res.json(post); // trả về thông tin sau khi chỉnh sửa
       }
     });
   }
 });
});

Chạy thử nào, hãy truy cập vào đường dẫn http://localhost:3000/api/post/edit/55b2ddaace90ba680add6091 nếu thành công sẽ hiển thị thế này:

 {
  "_id":"55b2ddaace90ba680add6091",
  "creationDate":"2015-07-25T00:51:54.010Z",
  "content":"Content is here",
  "description":"Description has many changes",
  "title":"Title after edit",
  "__v":0
} 

Bây giờ chúng ta sẽ đến với thao tác cuối cùng là Delete (xóa bài viết):


app.get('/api/post/delete/:post_id', function(req, res) {
  Post.remove({_id : req.params.post_id}, function(err) {
    if (err) {
      res.send(err);
    }
    else {
      res.json({message: "Xóa thành công!"});
    }
  });
});

Bạn có thể truy cập vào đường dẫn http://localhost:3000/api/post/delete/55b2ddaace90ba680add6091 kết quả sẽ thế này

{"message":"Xóa thành công!"}

Bạn có thể xác nhận lại việc đã xóa thành công chưa bằng cách truy cập vào trang hiển thị danh sách toàn bộ bài viết http://localhost:3000/api/post/list.

Vậy là đã xong, chúng ta đã đi qua hết các thao tác kết nối và truy vấn CRUD giữa NodeJS và MongoDB. Điểm cuối cùng mình xin lưu ý các bạn là, trên thực tế khi thực hiện thao tác Create ta phải dùng phương thức là POST, Update thì dùng PUT và Delete thì dùng DELETE. Trong bài này chỉ là demo nên mình dùng GET cho tất cả để dễ chạy thử thôi.

Trong bài này chúng ta cũng chưa thấy được sự kết nối giữa ngôn ngữ server NodeJS và AngularJS, tuy nhiên bạn có thể thấy chúng ta đã trả về kiểu dữ liệu là Json vậy nên chắc các bạn cũng đoán được là tiếp theo chúng ta sẽ dùng AngularJs để đọc đoạn json này đúng không nào 🙂 Đó sẽ là nội dung trong bài viết tiếp theo của mình, kết hợp với AngularJS để tạo ứng dụng MEAN Stack hoàn chỉnh.

Cuối cùng, cám ơn bạn đã theo hết bài viết này, hãy follow blog của mình để cập nhật các bài viết tiếp theo trong serie này nhé 😀

 

Mình là 1 developer mới vào nghề, chưa có nhiều kinh nghiệm với lập trình web nhưng luôn muốn chia sẻ những hiểu biết của mình với các lập trình viên khác.
  • Địa chỉ: Hồ Chí Minh