Xây dựng ứng dụng với NodeJs

1 Giới thiệu chung về NodeJs

NodeJs là một nền tảng được phát triển độc lập được xây dựng trên javascript runtime của chrome’s, với NodeJs chúng ta có thể xây dựng được ứng dụng mạng nhanh chóng và dễ dàng mở rộng. Nodejs được xây dựng và phát triển từ năm 2009 và được bảo trợ từ công ty Joyent. Khả năng đáp ứng của NodeJs là rất nhanh bởi NodeJs được viết hầu hết bởi ngôn ngữ C.

NodeJs là một ngôn ngữ Server. Nghĩa là NodeJs có đủ khả năng để tạo mọi website theo nhu cầu. Giống như nhiều ngôn ngữ Server khác, các page được tạo bằng NodeJs cũng sử dụng Html, Css, Javascript còn NodeJs đóng vai trò là code điều khiển.

1.1 Ưu điểm

  • Cú pháp ngắn gọn, dễ nhớ. Đặc biệt dễ học với những ai đã từng làm việc với nhiều với javascript, jquery
  • Xử lý không đồng bộ tốt: ví dụ khi upload file, chương trình không chờ việc upload xong mới xử lý việc tiếp theo. Nghĩa là trong khi xử lý upload file chương trình vẫn tiếp tục xử lý các công việc mới
  • Khả năng xử lý song song tuyệt vời: NodeJs sẽ tận dụng tối đa Unix để hoạt động. Tức là NodeJs có thể xử lý hàng nghìn process và trả ra 1 luồng khiến cho hiệu xuất hoạt động đạt mức tối đa nhất.
  • Có nhiều packages hỗ trợ để tạo nhiều chức năng cho site, các packages được cài đặt bằng câu lệnh giống như cài đặt gem trong ruby on rails
  • Hỗ trợ nhiều template engine để render view
  • Có nhiều framework. Được sử dụng phổ biến nhất là : ExpressJs, SailsJS
  • Khả năng sử dụng lại code: dễ dàng tạo ra các module, helper, library để sử dụng ở nhiều nơi
  • Hỗ trợ security tốt. NodeJs mặc định hỗ trợ chống tấn công Cross-site script

1.2 Nhược điểm

  • Chưa phân tách rõ ràng 3 phần model, view, controller theo mô hình MVC, ngay cả khi sử dụng ExpressJs framework thì vẫn phải thủ công cấu trúc theo MVC
  • Việc truy xuất dữ liệu thông qua nhiều bảng gặp nhiều hạn chế. Ví dụ khi app sử dụng MongoDb, để truy xuất dữ liệu liên quan đến nhiều bảng, buộc phải sử dụng callback để đảm bảo việc truy xuất dữ liệu diễn ra tuần tự theo mong muốn
  • Việc custom url tương đối khó khăn. Ví dụ có url : http://news/sport để tới trang các thông tin thể thao, url khác : http://news/sport/football tới trang các tin tức bóng đá, việc custom url thứ 2 thành http://news/football là khá khó khăn
  • Khi include một module, hay require một class vào một nơi nào đó để dùng cần phải khai báo đường dẫn tuyệt đối, hoặc tương đối tới file chứa class, module đó. Điều này khá bất tiện nếu độ sâu của file chứa class, module lớn
  • Khai báo routing thủ công, nghĩa là muốn một url nào đó có hiệu lực cần phải khai báo thủ công routing cho nó, không có chế độ auto

1.3 Các ứng dụng nên sử dụng NodeJs để phát triển

  • Các chương trình như các kênh chat với tốc độ thời gian thực runtime.
  • Các chương trình upload file
  • Các máy chủ quảng cáo
  • Các dịch vụ đám mây
  • Và bất kỳ ứng dụng dữ liệu thời gian thực nào.

1.4 Mức độ phổ biến

Hiện có nhiều công ty lớn đã sử dụng nodejs để phát triển ứng dụng của họ ở mức độ bộ phận hoặc toàn bộ như:

nodejs.png

2. Tạo ứng dụng quản lý sinh viên bằng NodeJs

2.1 Cài đặt NodeJs

Cài đặt NodeJs trên Ubuntu rất đơn giản

a) Bước 1: cài NodeJs

  sudo apt-get install nodejs

b) Bước 2: Cài npm

  sudo apt-get install npm
  sudo npm install -g npm

npm chính là một công cụ để quản lý các thư viện tích hợp (packages) trong NodeJs. Nó cho phép thêm, xóa, cập nhật một packages từ project

Sau khi đã thực hiện xong 2 bước này, để kiểm tra xem đã cài đặt thành công hay chưa ta dùng 2 lệnh sau:

  node -v
  npm -v

Nếu output không báo lỗi thì có nghĩa là đã cài đặt thành công, và bạn có thể bắt tay vào code NodeJs

2.2 Xây dựng ứng dụng quản lý sinh viên đơn giản

Để cho đơn giản trong ứng dụng này chúng ta sẽ sử dụng LocalStorage để lưu dữ liệu về sinh viên. Trong NodeJs có sử dụng module node-persist để lưu dữ liệu tạm thời trên Server

2.2.1 Khởi tạo project

Đầu tiên tạo thư mục chứa project:

   mkdir manage_student

Tiếp theo tạo file package.json trong thư mục gốc của project

   npm init

init_npm.png

Sau đó nhập các thông tin cấu hình cho project. Nếu muốn để mặc định thì không cần điền gì chỉ cần nhấn Enter là được

fill_init_npm.png

File package.json lưu trữ thông tin cấu hình cũng như các gói packages đang sử dụng trong project. File này cũng tương tự như Gemfile trong Ruby on Rails

Và đây là cấu trúc của file package.json


{
  "name": "manage_student",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \\\"Error: no test specified\\\" && exit 1"
  },
  "author": "[email protected]",
  "license": "ISC",
}

Trong đó:
name: Tên của Project
version: Version của Project
description: Mô tả cho Project
main: File chạy chính (chạy đầu tiên) của Project
scripts: Danh sách các khai báo cấu hình bổ sung cho npm. Như trong chuỗi trên thì giá trị của test chính là câu thông báo và dừng chương trình khi bị lỗi.
author: Tên tác giả của Project
license: License của Project, giá trị mặc định là ISC.

2.2.2 Thêm package node-persist vào project

Để thêm package cho project NodeJs bạn sử dụng cú pháp sau:

  npm install [email protected] --save

Để cài đặt gói node-persist version 0.0.6 vào NodeJs dùng command sau:

  npm install [email protected] –save

install_package.png

Sau khi cài đặt xong, trong thư mục gốc của project sẽ thấy xuất hiện thư mục của package node-persist

folder_include_package.png

Bây giờ mở file package.json lên ta thấy nội dung được thêm như sau:

package-json-file.png

Nghĩa là nó bổ sung thêm thuộc tính dependencies và đây chính là thuộc tính lưu trữ các package đang sử dụng trong Project.

2.2.3 Sử dụng node-persist để xây dựng ứng dụng

Load module node-persist và thiết lập hàm khởi tạo

//Load module node-persist
var storage = require('node-persist');

// Ham khoi tao
storage.initSync({
  dir: 'students'
});

Trước khi sử dụng một module nào thì bạn phải sử dụng hàm require để tạo đối tượng module đó. Sau đó cần phải thiết lập hàm khởi tạo để nó load tất cả các key lưu trữ trong ở cứng. Hàm Khởi tạo init() sẽ có một tham số truyền vào ở dạng Object, trong đó có nhiều key cần chú ý đến 2 key sau:

storage.init({
    dir : "path/to/save",
    ttl : false
});

storage.initSync({
    dir : "path/to/save",
    ttl : false
});

Trong đó key dir là đường dẫn lưu trữ dữ liệu. Nếu không thiết lập thì nó sẽ lưu vào đường dẫn như sau:
node-modules/node-persist/storage/persist
Còn nếu bạn thiết lập thì nó sẽ lưu vào đường dẫn
node-modules/node-persist/storage/duong_dan
Còn ttl (time to live) là thời gian sống của dữ liệu, nếu thiết lập false thì nó sẽ sống vĩnh viễn.

Nếu thiết lập dạng Sync thì dữ liệu sẽ lưu trên disk, vì vậy có thể sử dụng ở các request tiếp theo.
Nếu thiết lập dạng không Sync thì dữ liệu sống trong request đó thôi.

Lấy danh sách sinh viên

function getAllStudents(){
  var students = storage.getItemSync('students');
  if(typeof students === "undefined"){
    return [];
  }
  return students;
}

Tìm một sinh viên theo Id

function getStudent(studentId){
  var students = getAllStudents();
  var matchedStudent = null;
  for(var i=0;i<students.length;i++){
    if(students[i].id === studentId){
      matchedStudent = students[i];
      break;
    }
  }
  return matchedStudent;
}

Thêm một sinh viên vào danh sách

function addStudent(id, fullname, age){
  var students = getAllStudents();
  students.push({
    id: id,
    fullname: fullname,
    age: age
  });
  storage.setItemSync('students', students);
}

Xóa một sinh viên ra khỏi danh sách

function removeStudent(studentId){
  var students = getAllStudents();
  for(var i=0; i<students.length;i++){
    if(students[i] === studentId){
      students.splice(i, 1);
    }
  }
  storage.setItemSync('students', students);
}

Sửa thông tin sinh viên

function editStudent(studentId, studentName, studentAge){
  var students = getAllStudents();
  for(var i=0; i<students.length; i++){
    students[i].fullname = studentName;
    students[i].age = studentAge;
  }
  storage.setItemSync('students', students);
}

Hiển thị thông tin tất cả sinh viên ra terminal

function showStudents(){
  var students = getAllStudents();
  students.forEach(function(student){
    console.log('Student: ' + student.fullname + '. He/she is ' + student.age + ' years old');
  });
}

Thử nghiệm các hàm đã viết bằng cách thêm sinh viên và hiển thị danh sách sinh viên

addStudent(1, 'Cuong', 20);
addStudent(2, 'Kinh', 21);
addStudent(3, 'Chinh', 22);
addStudent(4, 'Quyen', 23);

// Hiển thị danh sách sinh viên
showStudents();
storage.clearSync();

Toàn bộ file student_info.js sẽ có nội dung như sau:

//Load module node-persist
var storage = require('node-persist');

// Ham khoi tao
storage.initSync({
  dir: 'students'
});

function getAllStudents(){
  var students = storage.getItemSync('students');
  if(typeof students === "undefined"){
    return [];
  }
  return students;
}

function getStudent(studentId){
  var students = getAllStudents();
  var matchedStudent = null;
  for(var i=0;i<students.length;i++){
    if(students[i].id === studentId){
      matchedStudent = students[i];
      break;
    }
  }
  return matchedStudent;
}

function addStudent(id, fullname, age){
  var students = getAllStudents();
  students.push({
    id: id,
    fullname: fullname,
    age: age
  });
  storage.setItemSync('students', students);
}

function removeStudent(studentId){
  var students = getAllStudents();
  for(var i=0; i<students.length;i++){
    if(students[i] === studentId){
      students.splice(i, 1);
    }
  }
  storage.setItemSync('students', students);
}

function editStudent(studentId, studentName, studentAge){
  var students = getAllStudents();
  for(var i=0; i<students.length; i++){
    students[i].fullname = studentName;
    students[i].age = studentAge;
  }
  storage.setItemSync('students', students);
}

function showStudents(){
  var students = getAllStudents();
  students.forEach(function(student){
    console.log('Student: ' + student.fullname + '. He/she is ' + student.age + ' years old');
  });
}

// Thêm sinh viên
addStudent(1, 'Cuong', 20);
addStudent(2, 'Kinh', 21);
addStudent(3, 'Chinh', 22);
addStudent(4, 'Quyen', 23);

// Hiển thị danh sách sinh viên
showStudents();
storage.clearSync();

Chạy chương trình và xem kết quả

Trên Terminal gõ lệnh:

node student_info.js

Kết quả:

result_fixed.jpg

3. Kết luận

Do giới hạn của một bài viết, tôi chỉ đi vào xây dựng một ứng dụng quản lý sinh viên đơn giản chạy trên console, những ứng dụng phức tạp chạy trên nền web xin các bạn theo dõi ở các bài viết sau.

Qua bài viết này tôi đã giới thiệu với các bạn khái quát về NodeJs - một ngôn ngữ đang nổi lên trong thời gian gần đây, cũng như ưu nhược điểm của nó. Tôi cũng giới thiệu đến các bạn cách xây dựng một ứng dụng đơn giản dùng NodeJs. Qua đó các bạn có những bước khởi đầu nếu muốn học NodeJs, cũng như thông qua các bước xây dựng ứng dụng bạn có thể tự có những đánh giá của bản thân mình về NodeJs so với các ngôn ngữ lập trình khác.

Cảm ơn các bạn đã theo dõi. Hẹn gặp lại ở các bài viết tiếp theo.

Tài liệu tham khảo
http://www.tutorialspoint.com/nodejs/
http://code.tutsplus.com/series/nodejs-step-by-step--net-20500
http://yournodejs.blogspot.com/2015/05/nodejs-la-gi.html


All Rights Reserved