Expressjs là gì? Tất tần tật về Express.js

2326

Nếu đã từng vào nhà hàng kiểu ngồi (sit-down restaurant), bạn sẽ hiểu được những kiến thức cơ bản về Express. Nhưng nếu chỉ mới build backend Node.js lần đầu thì… bạn sẽ gặp khá nhiều khó khăn.

Yes, nếu đã làm việc với Javascript bạn sẽ học Node nhanh hơn. Nhưng thách thức đối mặt khi xây dựng backend hoàn toàn khác với những thách thức khi sử dụng Javascript ở frontend.

Khi học Node, tôi đã chọn 1 cách học khó nhằn là nghiên cứu eBooks, các tài liệu hướng dẫn, videos.. cứ như vậy cho đến khi thực sự hiểu tại sao mình lại làm những gì mình đang làm.

Nhưng có 1 cách dễ hiểu hơn, là sử dụng câu chuyện so sánh liên quan đến nhà hàng kiểu ngồi để giải thích 4 phần quan trọng nhất trong app Express đầu tiên của bạn. Express.js là 1 framework dùng để sắp xếp code nổi tiếng, thường được các bạn mới bắt đầu code sử dụng.

Bài viết sẽ tập trung vào 4 phần chính sau:

  1. Require statements
  2. Middleware
  3. Routing
  4. App.listen()/ Starting the server

Trong phép so sánh này, bạn sẽ là chủ nhà hàng đang muốn tuyển Manager chung – người tạo nên tất cả quy trình và quản lý nhà hàng 1 cách trơn tru nhất, đem lại cho khách hàng những trải nghiệm vui vẻ, hạnh phúc. .

Tổng quan bài viết như sau:

Expressjs là gì?

Expressjs là một framework được xây dựng trên nền tảng của Nodejs. Nó cung cấp các tính năng mạnh mẽ để phát triển web hoặc mobile. Expressjs hỗ trợ các method HTTP và midleware tạo ra API vô cùng mạnh mẽ và dễ sử dụng.

Cấu trúc expressjs

Tổng hợp một số chức năng chính của Expressjs như sau:

  • Thiết lập các lớp trung gian để trả về các HTTP request.
  • Define router cho phép sử dụng với các hành động khác nhau dựa trên phương thức HTTP và URL.
  • Cho phép trả về các trang HTML dựa vào các tham số.

Dưới đây là một ví dụng để bạn sẽ hiểu được chức năng của mỗi phần trong 1 ứng dụng Express cơ bản.

Bước 1: thuê Manager (require statements)

Nếu muốn nhà hàng hoạt động hiệu quả, bạn sẽ cần 1 người giúp nhân viên làm việc hiệu quả ở mức tối đa. Express sẽ là “nhân vật” Manager như thế.

Cũng giống như bất kì package NPM nào khác, bạn cần phải npm install module express, sau đó sử dụng lệnh require để load module.

Khác với nhiều NPM packages khác, bạn cũng cần viết line sau:

Phải viết line này vì cần có 1 biến số để giữ Express application mới của mình. Express không phải là phần mặc định của Node.

Bước 2: đưa ra các quyết định quản lý ở nhà hàng (middleware)

Theo bạn, đâu là hoạt động thường diễn ra ở mọi nhà hàng? Đó sẽ là 3 hoạt động sau:

  1. Mời khách đến ghế ngồi
  2. Lấy order
  3. Tính tiền

Với mỗi hoạt động như vậy, sẽ có 1 loạt thứ phải chạy trước khi thực hiện được hoạt động đó. Ví dụ, trước khi mời khách vào ngồi, bạn cần biết:

  1. Họ có đang mặc sơ mi và mang giày không? Nếu không thì sẽ không được ngồi.
  2. Nếu họ muốn ngồi ở quán bar thì đã đủ 21 tuổi chưa? (nếu bạn đang ở Mỹ)

Tương tự với code, bạn sẽ cần phải xác nhận rằng các requests đảm bảo 1 chuẩn mực nào đó trước khi tiếp tục. Ví dụ, nếu ai đó cố gắng đăng nhập vào site thì:

  1. Họ có tài khoản chưa?
  2. Họ nhập password đúng chưa?

Đây là lý do concept middleware đã xuất hiện. Các hàm Middleware cho phép chúng ta thực hiện hành động trước request bất kì và modify nó trước khi gửi lại response.

Trong nhà hàng của bạn, cần hàng loạt các nguyên tắc để đưa ra quyết định xem liệu bạn có nên mời khách vào ghế hay không. Nguyên tắc ở đây là: họ có mang áo sơ mi & giày không?

Đầu tiên, hãy bắt đầu với app.use(). Đây là những rules đơn giản cần phải áp dụng để thực hiện các bước tiếp theo. Những rule này không phải GET, POST, PUT hay DELETE.

Ở line 4, có 1 hàm ẩn danh với các thông số req, res và next. Xét trong code block này, bạn chỉ đang kiểm tra request (req) để xem liệu có áo sơ mi & giày hay không.

Cuối cùng, bạn cũng cần phải sử dụng hàm next() vì ở đây bạn chỉ đang xác nhận trang phục. Các bước tiếp theo, bạn sẽ cho phép khách được thực sự vào bàn ăn.

Ở line 5 & 6, bạn sẽ kiểm tra liệu các khách hàng đó có mặc áo và mang giày không.

Và ở line 7–9, bạn chỉ tiếp tục nếu các vị khách có cả 2 là mặc áo & mang giày.

Code block ở trên bị thiếu 1 thứ quan trọng là path. Đây là string riêng đi chung với request. Và bởi vì thiếu path, nó sẽ chạy theo mỗi single request.

Bạn có thể tưởng tượng được không? Khi khách vào nhà hàng, gọi món, tính tiền, nhân viên sẽ phải nhìn họ trên dưới để đảm bảo là họ có mặc đồ! Nghe thật vô lý & trái với nguyên tắc kinh doanh.

 

Vì vậy, chúng ta đã thay đổi line 4 trong ví dụ ở trên. Bây giờ, chúng ta chỉ chạy đoạn code này khi 1 user truy vấn cùng route ‘/table’.

Chi tiết có thể xem hình bên dưới:

Bước 3: thực hiện các routines (routing)

Tiếp tục với ví dụ về việc mời vào chỗ ngồi. Cho đến lúc này, chúng ta chỉ biết được cách để xác thực liệu ai đó có nên được ngồi vào ghế hay không. Nhưng tôi thực sự không biết cách nào để đưa họ vào bàn và mời họ ngồi.

Chính lúc này, routes đã xuất hiện. Routes cho phép chúng ta soạn thảo (script) các hành động dựa trên path. Các options sẽ là GET, POST, PUT & DELETE, nhưng hiện tại chúng ta sẽ tập trung vào GET và POST.

Trong bối cảnh nhà hàng, chúng ta cần phải tạo 1 request GET để chọn 1 bàn ăn cụ thể và mời khách ngồi. GETs không modify hay thêm vào database của bạn. Chúng chỉ lấy thông tin dựa trên các thông số cụ thể.

Trong trường hợp này, bạn sẽ cần tạo 1 quy trình để sắp xếp chỗ ngồi cho 1 buổi tiệc với 2 khách. Số 2 xuất phát từ request của khách hàng.

Đúng vậy, đây chỉ là hành động gửi đi 1 tin nhắn vào lúc cuối. Nó vẫn chưa thực sự tìm được 1 bàn cụ thể để mời khách ngồi. Tôi sẽ cần phải tìm 1 array cho 1 bàn ăn còn trống và xử lý tình huống bên lề – tình huống nằm ngoài tầm giải quyết của tutorial này.

Ở line 12, chúng ta define quy trình này để tìm kiếm bàn ăn khi 1 vị khách requests cùng route ‘/table’. Cũng giống như ví dụ về middleware ở trên, chúng ta có sẵn các thông số request & response, có 1 parameter mà trong ví dụ này là hai.

Trên thực tế, mọi thứ đằng sau function declaration ở line 12 về mặt kỹ thuật là middleware vì nó modify user request. Bạn sẽ thấy điều đó trong biểu đồ ở dưới.

Ở line 13, chúng ta tiếp cận 1 số lượng người trong bữa tiệc từ các parameters của request object. Nó không được declare ở bất kì đâu vì request đến từ user và chúng ta không có dòng code frontend nào. Vì vậy nếu đây là 1 ứng dụng thực sự thì request sẽ trông như thế này:

ở line 13, biến party tiếp cận property của object params trong request ở trên.

Cuối cùng ở line 14, chúng ta gửi 1 response trở lại với khách hàng: chúng ta đang tìm kiếm bàn ăn có kích cỡ vừa phải.

Đây là biểu đồ tóm gọn lại mọi thứ:

Bước 3.5: khai thác tối đa nhà hàng (router)

Bây giờ, bạn có thể truy dấu vết của toàn bộ đường đi từ request đến response. Nhưng khi app của bạn tăng về kích cỡ, bạn sẽ không muốn code những nguyên tắc này độc lập cho mỗi route. Bạn sẽ nhận ra 1 vài routes chia sẻ cùng các rules, vì vậy cần phải tìm cách để ứng dụng 1 set các rules vào nhiều routes.

Nói riêng việc mời khách vào chỗ ngồi, bạn có thể mời khách vào quầy bar hoặc vào bàn ăn. Chúng đều có những nguyên tắc chung như áo sơ mi + giày, nhưng muốn ngồi ở quầy bar thì các thành viên của bữa tiệc phải đủ 21 tuổi.

Và, xét trên câu chuyện phục vụ khách hàng, bạn sẽ cần phải dùng đến 1 quy trình khác đi 1 chút như phục vụ món khai vị, món chính và yến tiệc. Tuy nhiên, 3 routes đó đều có nhiều điểm giống nhau.

Lúc này, router sẽ giúp bạn bằng cách nhóm các routes để từ đây bạn có thể tạo các nguyên tắc chung.

Chúng ta cần phải tạo middleware để giải quyết hết mỗi trường hợp này. Bạn sẽ chỉ cần xử lý các trường hợp mời chỗ ngồi vì nó sẽ overwrite đoạn code ở trên.

Trích dẫn toàn bộ code ở trên:

Tôi sẽ giải thích riêng biệt mỗi phần.

Ở line 4, chúng ta declare router.

Ở lines 6 & 14, chúng ta hiện có seatingRouter.use() thay thế cho app.use() để chỉ ra rằng middleware này chỉ liên quan đến các routes seatingRouter.

Cuối cùng, ở line 21, chúng ta thêm middleware, cho thấy rằng mỗi seatingRouter route bắt đầu với ‘/seating’. Vì vậy, nếu ai đó yêu cầu 1 ghế ngồi ở quầy bar, toàn bộ path sẽ là ‘/seating/bar.’ Nghe có vẻ lệch quy trình nhưng bạn có thể đang mong là path sẽ được define khi bạn tạo router ở line 4.

Bình thường thôi, hãy xem form biểu đồ sau:

Và, khi thêm 1 route GET, nó sẽ ở trên statement cuối – nơi bạn chỉ định các routes đến router.

Bước 4: bắt đầu kinh doanh (ports)

Bạn đã thuê manager, xác định những gì phải làm trước khi chấp nhận customer requests, và xác định những gì phải làm với các customer request cụ thể khi chúng xuất hiện. Bây giờ, chúng ta chỉ cần xác định chính xác địa chỉ cho địa điểm diễn ra tất cả các bước này.

Server của bạn có các ports, tương tự như địa chỉ của chính nhà hàng. Vì server có thể xử lý nhiều loại nhà hàng (hoặc các script server-side) cùng 1 lúc, nên bạn cần phải cho server biết nơi mà mỗi script nên chạy.

Trong ví dụ ở trên, port là 3000 và được định vị trong máy tính của bạn. Vì vậy, nếu bạn gõ:

vào browser của mình, và bạn đang chạy app Node, server sẽ biết cách chạy script cụ thể. Trong trường hợp này, ngay khi nhập URL, bạn sẽ nhập message vào console và có thể sử dụng các routes bất kì. Nếu bản thân nhà hàng là toàn bộ ứng dụng của bạn thì hiện tại nó đã bắt đầu kinh doanh ở địa chỉ 3000.