7. Express Framework
7.3 Router trong Express Framework
7.3.1 Router là gì?
Router là cách để máy chủ xác định và đáp ứng yêu cầu của máy khách. Mỗi router có thể có một hoặc nhiều hàm điều khiển, được thực thi khi các yêu cầu trùng khớp.
Ví dụ có một máy khách gửi yêu cầu bằng phương thức GET, POST, PUT hoặc DELETE cho các đường dẫn khác nhau, chẳng hạn như một URL được hiện thị bên dưới.
http://localhost:3000/users
Nếu yêu cầu bằng phương thức GET được thực hiện cho URL này, thì bên máy
chủ sẽ phản hồi một danh sách tất cả người dùng.
Vì vậy, dựa trên URL được truy cập, một chức năng trên máy chủ sẽ được gọi và theo đó các phản hồi sẽ được gửi đến máy khách.
7.3.2 Sử dụng Router
Sử dụng Router bằng cách sử dụng các phương thức của đối tượng app (thể hiên
của express).
Cú pháp:
app.METHOD(path, callback_handler)
Trong đó
METHODlà một phương thức yêu cầu HTTP (GET, POST, PUT hoặc DELETE)
pathlà một đường dẫn trên máy chủ
callback_handlerlà hàm được thực thi khi router khớp với path
Ví dụ
Tạo ra 3 router để đáp ứng yêu cầu sau.
1 router với path là /user sẽ hiện thị nội dung “Đây là trang thành viên“
1 router với path là /admin sẽ hiện thị nội dung “Đây là trang quảntrị“
1 router với path là / sẽ hiện thị nội dung “Đây là trang chủ“
Tạo file server.js với nội dung
var express = require('express'); var app = express();
app.get('/', function(request, response){ response.send("Đây là trang chủ"); });
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 29 app.get('/user', function(request, response){
response.send("Đây là trang thành viên"); });
app.get('/admin', function(request, response){ response.send("Đây là trang quản trị"); });
app.listen(3000)
Bây giờ các bạn chạy ứng dụng của mình lên bằng command lệnh. node server
Tiếp theo các bạn hãy mở trình duyệt và truy cập vào các đường dẫn http://localhost:3000,http://localhost:3000/admin,http://localhost:3000/user để xem kết quả nhé.
Ở đoạn code trên các bạn có thể thấy tối dùng app.get để truyền xử lý yêu cầu
của các router /, /admin, /user thì get ở đây chính là phương thức dùng để xử lý các
yêu cầu HTTP GET. Ngoài ra các bạn có thể dùng post, put, delete … hoặc các
phương thức khác để xửlý các yêu cầu HTTP tương ứng.
7.3.3 Tham số router
Tham số router là các phân đoạn URL được sử dụng để nắm bắt các giá trị được chỉ định tại vị trí của chúng trong URL. Các giá trị sẽ được chuyển đổi trong đối
tượng request.params , với tên của tham số router được chỉ định trong đường dẫn
router.
Cú pháp
app.METHOD('/:param1/:param2.../:paramN, callback_handler);
Ví dụ: Với đường dẫn users/Id trong đó Id là một tham số động của đường dẫn.
Tạo file server.js với nội dung sau.
var express = require('express'); var app = express();
app.get('/user/:Id', function(request, response){ response.send(request.params.Id);
});
app.listen(3000)
Chạy ứng dụng bằng command lệnh. node server
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 30
Lúc này bạn vào đường dẫn http://localhost:3000/user/15 để kiểm tra hoặc bạn
có thể nhập một ký tự bất kỳ .
7.4 Template Engine trong Express 7.4.1 Template Engine là gì ? 7.4.1 Template Engine là gì ?
Template engine là công cụ giúp chúng ta tạo ra các HTML template bằng những
đoạn mã được tối giản. Ngoài ra nó có thể đưa dữ liệu vào HTML template ở phía máy khách và tạo ra các đoạn mã HTML.
Hiện nay có rất nhiều template engine cho Node.js. Mỗi template engine sử dụng
các ngôn ngữ , cú pháp khác nhau để xác định cácHTML templte và đưa dữ liệu vào.
7.4.2 Danh sách các loại template engine.
Jade Vash EJS Mustache Dust.js Nunjucks Handlebars atpl haml
7.4.3 Ưu điểm khi sử dụng Template Engine
Cải thiện năng suất của các lập trình viên Cải thiện khả năng đọc, bảo trì code Hiêu suất nhanh hơn
Tối đa hóa cho xử lý phía khách hàng. Một template có thể dùng trong nhiều trang.
7.4.4 Sử dụng Template Engine trong Express
Để hiện thị các tệp template engine chúng ta phải thiết lập trong ứng dụng của chúng ta 2 thành phần.
Đường dẫn chứa tệp template
Khai báo loại template engine muốn sử dụng.
Để thiết lập trong ứng dụng chúng ta sẽ có phương thức app.set() của đối
tượng app
Cú pháp:
Thiết lập đường dẫn chứa tệp template: app.set('views', folder)
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 31 Trong đó:
viewslà từ khóa được quy đinh để thiết lập đường dẫn chứa template
folderlà một chuỗi dùng để cung cấp đường dẫn thư mục chứa file template. Mặc định là “./views”
Thiết lập loại tempalate engine
app.set('view engine', template_engine_name) Trong đó.
view enginelà từ khóa quy định để thiết lập loại template engine muốn sử dụng.
template_engine_nametên loại template enigne sẽ sử dụng.
7.4.5 Kết hợp EJS template với Express
Như đã liệt kê ở phần đầu, trong node.js có rất nhiều loại template engine có thể
kết hợp, và một trong số đó là EJS.
Cài đặt EJS
Trước tiên để sử dụng EJS các bạn vui lòng tải module này xuống bằng trình
quản lý package của Node.js npm install ejs
Kết hợp với express
Để kết với express thì trước tiên các bạn tạo cho tôi một server đơn giản bằng
express và được nghe trên cổng 3000. File server.js
var express = require('express'); var app = express();
app.get('demoejs', function(request, response){
response.send('chào mừng các bạn đến với học viện công nghệ VietPro');
});
app.listen(3000)
Tiếp theo, tại thư mục gốc của dự án các bạn tạo cho tôi thư mục "views" đây là
thư mục sẽ chứa toàn bộ các file template của chúng ta.
Bây giờ chúng ta sẽ kết hợp EJS vào Express .
Trước tiên các bạn tạo cho tôi một file với tên demo.ejs ở trong thư
mục views với nội dung.
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 32
Bây giờ bạn chỉnh lại file server.js như sau.
var express = require('express'); var app = express();
app.set('views', './views'); //1 app.set('view engine', 'ejs'); //2
app.get('/', function(request, response){ response.render('demo'); //3
});
app.listen(3000)
Lúc này bạn sẽ thấy tôi có chỉnh và thêm vài dòng code.
Dòng thứ 1, Đây làđoạn code dùng để thiết lập thư mục chứa template.
Dòng thứ 2, Đây là đoạn code dùng để thiết lập loại template engine muốn sử dụng.
Dòng thứ 3, Dòng code này sẽ dùng để biên dịch một file templte engine để chuyển thành mã HTML
Bây giờ các bạn tiến hành chạy thử ứng dụng lên bằng command lệnh node server
và truy cập vào đường dẫn http://localhost:3000
Các bạn sẽ nhận được nội dung từ file template engine được biên dịch sang mã HTML
7.5 Middleware Express
Trong ngành công nghiệp phần mềm, middleware là một thuật ngữ dùng để mô tả một lớp phần mềm nằm giữa các ứng dụng và hệ điều hành. Nhằm cung cấp dịch vụ cho các ứng dụng phần mềm ngoài những ứng dụng có sẵn từ hệ điều hành…
7.5.1 Middleware trong ứng dụng web
Trong lập trình web middleware đóng vai trò trung gian giữa yêu cầu của người
dùng và phản hồi của máy chủ (request và response).
Ở trong các freamwork của các ngôn ngữ lập trình middleware là các hàm dùng để xử lý các request trước khi đưa vào xử lý logic của ứng dụng web.
7.5.2 Middleware trong Express
Ở trong express middleware là các hàm thực thi trong suốt vòng đời của một yêu cầu (request) tới máy chủ Express. Mỗi middleware đều có quyền truy cập vào request và response của mỗi router được gắn vào.
Middleware trong express sẽ thực hiện 4 công việc sau.
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 33
Thực hiện thay đổi đối với request và response
Kết thúc chu kỳ request-reponse
Gọi middleware tiếp theo .
7.5.3 Cấu trúc middleware trong express
Một middleware trong express sẽ như thế nào?
Bên dưới là cấu trúc của một middleware ở trong express. function middlewareExample(request, response, next){ //Mã xử lý
next() }
Trong cấu trúc trên các bạn có thể thấy rằng middleware trong express khá đơn
giản, nó chỉ là một hàm nhận vào 3 tham số request , response và next. Với 3 tham số
này chắc các bạn cũng đoán được 2 tham số request và response là gì rồi. Còn đối
với next() nó được sử dụng để gọi các middleware tiếp theo.
Ví dụ
Tôi sẽ ví dụ cho các bạn một middleware đơn giản sau đó chúng ta sẽ tìm hiểu
các cách sử dụng middleware. File server.js
var express = require('express'); var app = express();
function myLogger(request, response, next){
console.log(`Có 1 client truy cập vào đường dẫn: ${request.url}` ); next();
}
app.use(myLogger);
app.get('/*', function(request, response){ response.send('Hello');
})
app.listen(3000)
Với ví dụ này tối viết một middleware để ghi khi một người nào đó truy cập vào ứng dụng.
Hàm myLogger sẽ có chức năng là in ra đường dẫn mà client đang truy cập tới.
Để sử dụng middleware tôi sử dụng app.use() của express và chỉ đinh các chức năng
của middleware, cụ thể ở đây là chức năng myLogger .
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 34 node server
sau đó thử truy cập đường dẫn:
http://localhost:3000/abc, http://localhost:3000/xyz, http://localhost:3000 và thử
kiểm tra hoạt độngcủa middleware .
7.5.4 Sử dụng middleware trong expressSử dụng middleware ở cấp ứng dụng Sử dụng middleware ở cấp ứng dụng
Khi bạn khởi tạo một ứng dụng Web với Express một đối tượng đại diện cho ứng
dụng của chúng ta đó là app (tùi theo mỗi người mà tên đối tượng này có thể sẽ
khác). Chúng ta có thể sử dụng đối tượng này để khai báo middleware thông qua các hàm app.use() hoặc app.METHOD METHOD ở đây chính là các phương thức của request .
Ví dụ với middleware khi không có đường dẫn. Với kiểu khai báo như thế này thì mỗi khi có yêu cầu tới middleware sẽ được thực thi.
File server.js
var express = require('express'); var app = express();
app.use(function(request, response, next){ console.log('Time:' + Date.now()) next();
});
app.get('/', function(request, response){
response.send('Chào mừng các bạn đến với học viện công nghệ VietPro');
});
app.listen(3000)
Ví dụ này sẽ gắn một middleware vào đường dẫn /user/:id . Middleware sẽ được
thực thi khi có một yêu cầu truy cập vào /user/:id
File server.js
var express = require('express'); var app = express();
app.use('/user/:id', function(request, response, next){ console.log('Time:' + Date.now())
next(); });
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 35 app.get('/*', function(request, response){
response.send('Chào mừng các bạn đến với học viện công nghệ VietPro');
});
app.listen(3000)
Ví dụ khi một người dùng truy cập đường dẫn bằng phương thức GET.
File server.js
var express = require('express'); var app = express();
app.get('/user/:id', function(request, response, next){
response.send('Chào mừng các bạn đến với học viện công nghệ VietPro');
});
app.listen(3000)
Khi chúng ta muốn khai báo một lúc nhiều middleware cho một đường dẫn, các bạn có thể viết liên tiếp nhiều hàm là các tham số phía sau tham số đường dẫn.
app.use('/user/:id', function (req, res, next) { console.log('Request URL:', req.originalUrl) next()
}, function (req, res, next) {
console.log('Request Type:', req.method) next()
})
Trong trường hợp các bạn có nhiều router được xác định cho một đường dẫn. Ví dụ
app.get('/user/:id', function (req, res, next) { console.log('ID:',req.params.id) next() },function(req,res,next){ res.send('User Info') }) app.get('/user/:id',function(req,res,next){ res.end(req.params.id)
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 36 })
Trong trường hợp trên khi một client truy cập vào /user/:id thì phía express sẽ tự
động đẩy vào User Info và không thể nào chuyển tiếp tới req.params.id . Để có thể
chuyển tiếp tới req.params.id thì ở hàm next() chúng ta phải khai báo thêm tham
số 'router' thì nó sẽ tự động chuyển về router cuối cùng trong danh sách router
Ví dụ dưới đây mô tả trường hợp khi truy cập vào đường dẫn /user/:id với id
khác 0 thì sẽ chuyển tới req.params.id
File server.js
var express = require('express'); var app = express();
app.get('/user/:id', function (req, res, next) { console.log('ID:', req.params.id)
if (req.params.id == 0) { next('router');
} else next()
}, function (req, res, next) { res.send('User Info') })
app.get('/user/:id', function (req, res, next) { res.end(req.params.id)
})
app.listen(3000)
Sử dụng middleware ở cấp Router
Các middleware của Router về cách thức hoạt động không khác gì so với middleware cấp ứng dụng. Nhưng thay vì sử dụng đối tượng đại diện cho ứng dụng, chúng ta sẽ sử dụng thể hiện của Router.
var router = express.Router()
ở trong đối tượng router cũng có những phương thức tương tự như ở trong đối
tượng app của ứng dụng. Bao gồm router.use() và router.METHOD .
Ví dụ:
File server.js
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 37 var app = express();
var router = express.Router();
router.use('/user/:id', function(request, response, next){ console.log('Time: ' + Date.now());
next(); });
router.get('/user/:id', function(request, response, next){
response.send('Chào mừng các bạn đến với học viện công nghệ VietPro');
});
app.use(router) app.listen(3000)
Sử dụng middleware xử lý lỗi
Một trong những điều quan trọng nhất trong xây dựng web là xử lý lỗi. Vì hệ thông sẽ phụ thuộc vào các dịch vụ , cơ sở dữ liệu khác, cũng như người sử dụng dịch vụ đó. Cơ sở dữ liệu không kết nối được, dịch vụ sẽ không hoạt động và người dùng sẽ không thể nào truy cập tới được các đường dẫn của chúng ta.
Để phòng chống những tính huống như vậy bạn phải xử lý các lỗi đúng cách. Trước khi đi vào ví dụ đơn giản về xử lý lỗi thì chúng ta cùng xem cú pháp khai báo một middleware xử lý lỗi trong expres.
Cú pháp
app.use(function(error, request, response, next){ })
Như các bạn thấy thì middleware xử lý lỗi thì chúng ta sẽ có thêm 1 tham số đó là error. Chính là đối tượng chứa thông báo lỗi của chúng ta.
Ví dụ thông báo lỗi đơn giản. File server.js
var express = require('express'); var app = express();
app.get('/user/:id', function(request, response, next){ if (request.params.id == 0) {
var error = {
title: "Không tìm thấy ID", httpStatusCode: 400
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 38 } return next(error); } response.end(request.params.id); });
app.use(function(error, request, response, next){
response.status(error.httpStatusCode).send(error.title) })
app.listen(3000)
Trong ví dụ trên tôi viết ra một middleware xử lý lỗi đơn giản. Ở trong router /user/:id tôi viết đoạn code đơn giản để kiểm tra tham số id bằng 0 thì tạo ra một đối tượng chứa thông tin lỗi sau đó tiến hành chuyển tiếp thông tin lỗi đến middleware xử lý lỗi để tiếp tục xử lý.
Để chạy thửví dụ các bạn chạy command với lệnh
node server
Sử dụng middleware tích hợp
Middleware tích hợp là các middleware đã được cài đặt sẵn ở trong đối tượng express.
Express có các midleware tích hợp sau:
express.static: dùng để sử dụng các tập tin tĩnh như các tập tin css, javascript hay image
express.json:phân tích các yêu cầu gửi lên bằng JSON
express.urlencode: phân tích các yêu cầu của được mã hóa theo url.
Sử dụng middleware của bên thứ ba
Ngoài những middleware các bạn tự xây dụng hay các middleware tích hợp sẵn
các bạn có thể cài các middleware của các bên thứ 3 ở trên kho NPM.
7.5.5 Truy cập file tĩnh trong express
Như các bạn đã biết mỗi đường dẫn để chúng ta truy cập ở trong server express đều được lắng nghe và điều hướng bởi router.
Chính vì thếkhi muốn ứng dụng của chúng ta có thể truy cập được các file tĩnh ở
trên server chúng ta cũng phải tạo ra router cho các file ấy.
Việc tạo router cho một vài file thì không có gì khó, nhưng bạn thử hình dụng xem trong ứng dụng của chúng ta có thể có tới hàng chục hàng trăm file tĩnh mà ứng dụng cần phải truy cập, thì việc tạo router thực sự rất khó khăn.
Hiểu thấu được sự khó khăn của các bạn nên express đã cung cấp thêm cho các
Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 39
Cấu hình và sử dụng
Việc cấu hình để truy cập file tĩnh trong express khá đơn giản. Cú pháp
express.static(root, [options]) Mô tả tham số
expressthể hiện của express khi được yêu cầu.
rootđường dẫn gốc lưu trữ các file tĩnh
options các thiết lập khác
Ví dụ sau đây sẽ dùng để chia sẻ các tập tin tĩnh ở trong thư mục public.
var express = require('express'); var app = express();
app.use(express.static('public')) app.listen(3000)
Bây giờ các bạn có thể truy cập các file có trong thư mục public. http://localhost:3000/images/logo.jpg
http://localhost:3000/css/style.css http://localhost:3000/js/app.js http://localhost:3000/images/bg.png http://localhost:3000/hello.html
Express sẽ tìm kiếm các tệp liên quan đến thư mục chứa file tĩnh, vì vậy tên của thư mục chứa file sẽ không có trong URL.
Để sử dụng nhiều thư mục chứa file tĩnh. Bạn có thể thể gọi bằng express.static nhiều lần.