Koa.js - Hướng dẫn nhanh

Khung ứng dụng web cung cấp cho bạn một API đơn giản để tạo trang web, ứng dụng web và phụ trợ. Bạn không cần phải lo lắng về các giao thức, quy trình cấp thấp, v.v.

Koa là gì?

Koa cung cấp một giao diện tối thiểu để xây dựng các ứng dụng. Nó là một khuôn khổ rất nhỏ (600 LoC) cung cấp các công cụ cần thiết để xây dựng ứng dụng và khá linh hoạt. Có rất nhiều mô-đun có sẵn trên npm cho Koa, có thể được cắm trực tiếp vào nó. Koa có thể được coi là cốt lõi của express.js mà không cần đến tất cả các chuông và còi.

Tại sao Koa?

Koa có một dấu ấn nhỏ (600 LoC) và là một lớp trừu tượng rất mỏng trên nút để tạo các ứng dụng phía máy chủ. Nó hoàn toàn có thể cắm được và có một cộng đồng lớn. Điều này cũng cho phép chúng tôi dễ dàng mở rộng Koa và sử dụng nó theo nhu cầu của chúng tôi. Nó được xây dựng bằng công nghệ tiên tiến (ES6) mang lại cho nó một lợi thế so với các khuôn khổ cũ hơn như express.

Pug

Pug (trước đây được gọi là Jade) là một ngôn ngữ ngắn gọn để viết các mẫu HTML.

  • Tạo HTML
  • Hỗ trợ mã động
  • Hỗ trợ khả năng tái sử dụng (DRY)

Nó là một trong những ngôn ngữ tạo khuôn mẫu phổ biến nhất được sử dụng với Koa.

MongoDB và Mongoose

MongoDB là một cơ sở dữ liệu tài liệu mã nguồn mở được thiết kế để dễ phát triển và mở rộng. Chúng tôi sẽ sử dụng cơ sở dữ liệu này để lưu trữ dữ liệu.

Mongoose là một API máy khách cho node.js, giúp dễ dàng truy cập cơ sở dữ liệu từ ứng dụng Koa của chúng tôi.

Để bắt đầu phát triển bằng Koa framework, bạn cần cài đặt Node và npm (trình quản lý gói nút). Nếu bạn chưa có những thứ này, hãy chuyển đến Thiết lập nút để cài đặt nút trên hệ thống cục bộ của bạn. Xác nhận rằng nút và npm đã được cài đặt bằng cách chạy các lệnh sau trong thiết bị đầu cuối của bạn.

$ node --version
$ npm --version

Bạn sẽ nhận được một đầu ra tương tự như -

v5.0.0
3.5.2

Hãy đảm bảo phiên bản nút của bạn trên 6.5.0. Bây giờ chúng ta đã thiết lập Node và npm, chúng ta hãy hiểu npm là gì và cách sử dụng nó.

Trình quản lý gói nút (npm)

npm là trình quản lý gói cho nút. Npm Registry là tập hợp công khai các gói mã nguồn mở cho Node.js, ứng dụng web front-end, ứng dụng di động, rô bốt, bộ định tuyến và vô số nhu cầu khác của cộng đồng JavaScript. npm cho phép chúng tôi truy cập tất cả các gói này và cài đặt chúng cục bộ. Bạn có thể duyệt qua danh sách các gói có sẵn trên npm tại npmJS .

Làm thế nào để sử dụng npm?

Có hai cách để cài đặt một gói sử dụng npm - trên toàn cầu và cục bộ.

Globally- Phương pháp này thường được sử dụng để cài đặt các công cụ phát triển và các gói dựa trên CLI. Để cài đặt một gói trên toàn cầu, hãy sử dụng lệnh sau.

$ npm install -g <package-name>

Locally- Phương pháp này thường được sử dụng để cài đặt các khung và thư viện. Một gói được cài đặt cục bộ chỉ có thể được sử dụng trong thư mục mà nó được cài đặt. Để cài đặt một gói cục bộ, hãy sử dụng lệnh tương tự như trên mà không có dấu -g cờ.

$ npm install <package-name>

Bất cứ khi nào chúng tôi tạo một dự án bằng npm, chúng tôi cần cung cấp một tệp package.json, tệp này có tất cả các chi tiết về dự án của chúng tôi. npm giúp chúng tôi dễ dàng thiết lập tệp này. Hãy để chúng tôi thiết lập dự án phát triển của chúng tôi.

Step 1 - Kích hoạt terminal / cmd của bạn, tạo một thư mục mới có tên hello-world và cd vào đó -

Step 2 - Bây giờ để tạo tệp package.json bằng npm, hãy sử dụng như sau.

npm init

Nó sẽ hỏi bạn những thông tin sau -

Chỉ cần tiếp tục nhấn enter và nhập tên của bạn vào trường "tên tác giả".

Step 3- Bây giờ chúng ta đã thiết lập tệp package.json, chúng ta sẽ cài đặt Koa. Để cài đặt Koa và thêm nó vào tệp package.json của chúng tôi, hãy sử dụng lệnh sau.

$ npm install --save koa

Để xác nhận Koa được cài đặt chính xác, hãy chạy lệnh sau.

$ ls node_modules #(dir node_modules for windows)

Tip - Sự --save cờ có thể được thay thế bằng -Scờ. Cờ này đảm bảo rằng Koa được thêm vào dưới dạng phụ thuộc vào tệp package.json của chúng tôi. Điều này có một lợi thế, lần sau khi chúng ta cần cài đặt tất cả các tệp phụ thuộc của dự án của mình, chúng ta chỉ cần chạy lệnh npm install và nó sẽ tìm các tệp phụ thuộc trong tệp này và cài đặt chúng cho chúng ta.

Đây là tất cả những gì chúng ta cần để bắt đầu phát triển bằng Koa framework. Để làm cho quá trình phát triển của chúng tôi dễ dàng hơn nhiều, chúng tôi sẽ cài đặt một công cụ từ npm, gật đầu. Công cụ này làm được gì, nó khởi động lại máy chủ của chúng tôi ngay sau khi chúng tôi thực hiện thay đổi trong bất kỳ tệp nào của mình, nếu không, chúng tôi cần khởi động lại máy chủ theo cách thủ công sau mỗi lần sửa đổi tệp. Để cài đặt gật đầu, hãy sử dụng lệnh sau.

$ npm install -g nodemon

Bây giờ tất cả chúng ta đã sẵn sàng để đi sâu vào Koa!

Khi chúng tôi đã thiết lập sự phát triển, đã đến lúc bắt đầu phát triển ứng dụng đầu tiên của chúng tôi bằng Koa. Tạo một tệp mới có tênapp.js và nhập nội dung sau vào đó.

var koa = require('koa');
var app = new koa();

app.use(function* (){
   this.body = 'Hello world!';
});

app.listen(3000, function(){
   console.log('Server running on https://localhost:3000')
});

Lưu tệp, chuyển đến thiết bị đầu cuối của bạn và nhập.

$ nodemon app.js

Điều này sẽ khởi động máy chủ. Để kiểm tra ứng dụng này, hãy mở trình duyệt của bạn và truy cậphttps://localhost:3000 và bạn sẽ nhận được thông báo sau.

Ứng dụng này hoạt động như thế nào?

Dòng đầu tiên nhập Koa trong tệp của chúng tôi. Chúng tôi có quyền truy cập vào API của nó thông qua biến Koa. Chúng tôi sử dụng nó để tạo một ứng dụng và gán nó cho ứng dụng var.

app.use(function)- Chức năng này là một phần mềm trung gian, được gọi bất cứ khi nào máy chủ của chúng tôi nhận được yêu cầu. Chúng ta sẽ tìm hiểu thêm về phần mềm trung gian trong các chương tiếp theo. Hàm gọi lại là một trình tạo, chúng ta sẽ xem trong chương tiếp theo. Ngữ cảnh của trình tạo này được gọi là ngữ cảnh trong Koa. Ngữ cảnh này được sử dụng để truy cập và sửa đổi các đối tượng yêu cầu và phản hồi. Chúng tôi đang thiết lập phần thân của phản hồi này làHello world!.

app.listen(port, function)- Chức năng này liên kết và lắng nghe các kết nối trên cổng được chỉ định. Cổng là tham số bắt buộc duy nhất ở đây. Chức năng gọi lại được thực thi, nếu ứng dụng chạy thành công.

Một trong những tính năng mới thú vị nhất của JavaScript ES6 là một loại chức năng mới, được gọi là trình tạo. Trước trình tạo, toàn bộ tập lệnh thường được sử dụng để thực thi theo thứ tự từ trên xuống dưới, không có cách dễ dàng để dừng thực thi mã và tiếp tục lại với cùng một ngăn xếp sau đó. Trình tạo là các chức năng có thể được thoát và sau đó nhập lại. Bối cảnh của chúng (ràng buộc biến) sẽ được lưu qua các lần truy cập lại.

Trình tạo cho phép chúng tôi dừng thực thi mã ở giữa. Do đó, chúng ta hãy xem xét một máy phát điện đơn giản.

var generator_func = function* (){
   yield 1;
   yield 2;
};

var itr = generator_func();
console.log(itr.next());
console.log(itr.next());
console.log(itr.next());

Khi chạy đoạn mã trên, sau đây sẽ là kết quả.

{ value: 1, done: false }
{ value: 2, done: false }
{ value: undefined, done: true }

Hãy xem bên trong đoạn mã trên. Đầu tiên chúng tôi tạo một trình tạo có têngenerator_func(). Chúng tôi đã tạo một phiên bản của hàm trông kỳ lạ này và gán nó choitr. Sau đó, chúng tôi bắt đầu gọinext() trên biến itr này.

Việc gọi next () sẽ khởi động trình tạo và nó chạy cho đến khi đạt được lợi nhuận. Sau đó, nó trả về đối tượng có giá trị và thực hiện, trong đó giá trị có giá trị biểu thức. Biểu thức này có thể là bất cứ thứ gì. Tại thời điểm này, nó tạm dừng thực thi. Một lần nữa khi chúng ta gọi hàm này (tiếp theo), trình tạo tiếp tục thực thi từ điểm năng suất cuối cùng với trạng thái hàm giống nhau tại thời điểm tạm dừng, cho đến điểm năng suất tiếp theo. Điều này được thực hiện cho đến khi không còn điểm lợi nhuận trong mã.

Máy phát điện ở Koa

Vậy tại sao chúng ta lại thảo luận về máy phát điện trong hướng dẫn này. Như bạn có thể nhớ từ chương trình hello world, chúng tôi đã sử dụngfunction* ()ký hiệu để chuyển một lệnh gọi lại đến app.use (). Koa là một đối tượng, chứa một loạt các chức năng của trình tạo phần mềm trung gian, tất cả đều được tạo và thực thi theo cách giống như ngăn xếp theo mỗi yêu cầu. Koa cũng thực hiện hạ nguồn, sau đó là ngược dòng kiểm soát.

Hãy xem ví dụ sau để hiểu điều này một cách tốt hơn.

var koa = require('koa');
var app = koa();
 
app.use(function* (next) {
   //do something before yielding to next generator function 
   
   //in line which will be 1st event in downstream
   console.log("1");
   yield next;
 
   //do something when the execution returns upstream, 
   //this will be last event in upstream
   console.log("2");
});
app.use(function* (next) {
   // This shall be 2nd event downstream
   console.log("3");
   yield next;
 
   // This would be 2nd event upstream
   console.log("4");
});
app.use(function* () { 
   // Here it would be last function downstream
   console.log("5");
   
   // Set response body
   this.body = "Hello Generators";

   // First event of upstream (from the last to first)
   console.log("6");
});

app.listen(3000);

Khi chạy đoạn mã trên và điều hướng đến https://localhost:3000/ chúng tôi nhận được kết quả sau trên bảng điều khiển của chúng tôi.

1
3
5
6
4
2

Đây thực chất là cách Koa sử dụng máy phát điện. Nó cho phép chúng tôi tạo phần mềm trung gian nhỏ gọn bằng cách sử dụng thuộc tính này và viết mã cho cả chức năng thượng nguồn và hạ lưu, do đó giúp chúng tôi tiết kiệm khỏi các cuộc gọi lại.

Các khuôn khổ web cung cấp các tài nguyên như trang HTML, tập lệnh, hình ảnh, v.v. theo các tuyến khác nhau. Koa không hỗ trợ các tuyến trong mô-đun cốt lõi. Chúng ta cần sử dụng mô-đun Koa-router để dễ dàng tạo các tuyến đường trong Koa. Cài đặt mô-đun này bằng lệnh sau.

npm install --save koa-router

Bây giờ chúng ta đã cài đặt Koa-router, hãy xem một ví dụ đơn giản về lộ trình GET.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();              //Instantiate the router
_.get('/hello', getMessage);   // Define routes

function *getMessage() {
   this.body = "Hello world!";
};

app.use(_.routes());           //Use the routes defined using the router
app.listen(3000);

Nếu chúng tôi chạy ứng dụng của mình và truy cập localhost: 3000 / hello, máy chủ sẽ nhận được yêu cầu theo tuyến "/ hello". Ứng dụng Koa của chúng tôi thực thi chức năng gọi lại được đính kèm với tuyến đường này và gửi "Hello World!" như phản hồi.

Chúng tôi cũng có thể có nhiều phương pháp khác nhau trên cùng một tuyến đường. Ví dụ,

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router(); //Instantiate the router

_.get('/hello', getMessage);
_.post('/hello', postMessage);

function *getMessage() {
	this.body = "Hello world!";
};
function *postMessage() {
   this.body = "You just called the post method at '/hello'!\n";
};
app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

Để kiểm tra yêu cầu này, hãy mở thiết bị đầu cuối của bạn và sử dụng cURL để thực hiện yêu cầu sau

curl -X POST "https://localhost:3000/hello"

Một phương pháp đặc biệt, all, được cung cấp bởi express để xử lý tất cả các loại phương thức http tại một tuyến đường cụ thể bằng cách sử dụng cùng một chức năng. Để sử dụng phương pháp này, hãy thử như sau:

_.all('/test', allMessage);

function *allMessage(){
   this.body = "All HTTP calls regardless of the verb will get this response";
};

Bây giờ chúng ta có thể xác định các tuyến đường; chúng tĩnh hoặc cố định. Để sử dụng các tuyến đường động, chúng ta cần cung cấp các loại tuyến đường khác nhau. Sử dụng các tuyến đường động cho phép chúng tôi truyền các tham số và xử lý dựa trên chúng. Sau đây là một ví dụ về một tuyến đường động.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

_.get('/:id', sendID);

function *sendID() {
   this.body = 'The id you specified is ' + this.params.id;
}

app.use(_.routes());
app.listen(3000);

Để kiểm tra điều này, hãy truy cập https://localhost:3000/123. Bạn sẽ nhận được phản hồi sau.

Bạn có thể thay thế '123' trong URL bằng bất kỳ thứ gì khác và nó sẽ được phản ánh trong phản hồi. Sau đây là một ví dụ phức tạp của điều trên.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

_.get('/things/:name/:id', sendIdAndName);

function *sendIdAndName(){
   this.body = 'id: ' + this.params.id + ' and name: ' + this.params.name;
};

app.use(_.routes());

app.listen(3000);

Để kiểm tra điều này, hãy truy cập https://localhost:3000/things/tutorialspoint/12345.

Bạn có thể dùng this.paramsđối tượng để truy cập tất cả các tham số bạn chuyển vào URL. Lưu ý rằng hai đường dẫn trên có các đường dẫn khác nhau. Chúng sẽ không bao giờ chồng lên nhau. Ngoài ra, nếu bạn muốn thực thi mã khi nhận được '/ things', thì bạn cần phải xác định nó một cách riêng biệt.

Các tuyến đường phù hợp với mẫu

Bạn cũng có thể sử dụng regex để hạn chế đối sánh tham số URL. Giả sử bạn cần id là số có năm chữ số. Bạn có thể sử dụng định nghĩa tuyến đường sau đây.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

_.get('/things/:id([0-9]{5})', sendID);

function *sendID(){
   this.body = 'id: ' + this.params.id;
}

app.use(_.routes());
app.listen(3000);

Lưu ý rằng điều này sẽ onlykhớp với các yêu cầu có id dài 5 chữ số. Bạn có thể sử dụng các regex phức tạp hơn để khớp / xác thực các tuyến đường của mình. Nếu không có tuyến đường nào của bạn phù hợp với yêu cầu, bạn sẽ nhận được thông báo Không tìm thấy dưới dạng phản hồi.

Ví dụ: nếu chúng tôi xác định các tuyến đường tương tự như trên, khi yêu cầu với một URL hợp lệ, chúng tôi nhận được -

Phương thức HTTP được cung cấp trong yêu cầu và chỉ định hoạt động mà khách hàng đã yêu cầu. Bảng sau đây tóm tắt các phương thức HTTP thường được sử dụng.

Sr.No. Phương pháp & Mô tả
1

GET

Phương thức GET yêu cầu biểu diễn tài nguyên được chỉ định. Các yêu cầu sử dụng GET chỉ nên truy xuất dữ liệu và không có tác dụng nào khác.

2

POST

Phương thức POST yêu cầu máy chủ chấp nhận dữ liệu trong yêu cầu như một đối tượng / thực thể mới của tài nguyên được xác định bởi URI.

3

PUT

Phương thức PUT yêu cầu máy chủ chấp nhận dữ liệu trong yêu cầu như một sửa đổi đối với đối tượng hiện có được xác định bởi URI. Nếu nó không tồn tại, thì phương thức PUT sẽ tạo một.

4

DELETE

Phương thức DELETE yêu cầu máy chủ xóa tài nguyên được chỉ định.

Đây là những phương thức HTTP phổ biến nhất. Để tìm hiểu thêm về chúng, hãy truy cậphttps://www.tutorialspoint.com/http/http_methods.htm.

Đối tượng Koa Request là một đối tượng trừu tượng nằm trên đối tượng yêu cầu vani của nút, cung cấp chức năng bổ sung hữu ích cho việc phát triển máy chủ HTTP hàng ngày. Đối tượng yêu cầu Koa được nhúng trong đối tượng ngữ cảnh,this. Hãy đăng xuất đối tượng yêu cầu bất cứ khi nào chúng ta nhận được yêu cầu.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

_.get('/hello', getMessage);

function *getMessage(){
   console.log(this.request);
   this.body = 'Your request has been logged.';
}
app.use(_.routes());
app.listen(3000);

Khi bạn chạy mã này và điều hướng đến https://localhost:3000/hello, thì bạn sẽ nhận được phản hồi sau.

Trên bảng điều khiển của bạn, bạn sẽ đăng xuất đối tượng yêu cầu.

{ 
   method: 'GET',
   url: '/hello/',
   header: 
   { 
      host: 'localhost:3000',
      connection: 'keep-alive',
      'upgrade-insecure-requests': '1',
      'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) 
         AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36',
      accept: 'text/html,application/xhtml+xml,
         application/xml;q = 0.9,image/webp,*/*;q = 0.8',
      dnt: '1',
      'accept-encoding': 'gzip, deflate, sdch',
      'accept-language': 'en-US,en;q = 0.8' 
   }
}

Chúng tôi có quyền truy cập vào nhiều thuộc tính hữu ích của yêu cầu bằng cách sử dụng đối tượng này. Hãy để chúng tôi xem xét một số ví dụ.

request.header

Cung cấp tất cả các tiêu đề yêu cầu.

request.method

Cung cấp phương thức yêu cầu (GET, POST, v.v.)

request.href

Cung cấp URL yêu cầu đầy đủ.

request.path

Cung cấp đường dẫn của yêu cầu. Không có chuỗi truy vấn và url cơ sở.

request.query

Cung cấp chuỗi truy vấn đã phân tích cú pháp. Ví dụ: nếu chúng tôi ghi lại điều này theo yêu cầu chẳng hạn nhưhttps://localhost:3000/hello/?name=Ayush&age=20&country=India, sau đó chúng ta sẽ nhận được đối tượng sau.

{
   name: 'Ayush',
   age: '20',
   country: 'India'
}

request.ac Concept (loại)

Hàm này trả về true hoặc false dựa trên việc các tài nguyên được yêu cầu có chấp nhận kiểu yêu cầu đã cho hay không.

Bạn có thể đọc thêm về đối tượng yêu cầu trong tài liệu tại Yêu cầu .

Đối tượng Koa Response là một đối tượng trừu tượng nằm trên đối tượng phản hồi vani của nút, cung cấp chức năng bổ sung hữu ích cho việc phát triển máy chủ HTTP hàng ngày. Đối tượng phản hồi Koa được nhúng trong đối tượng ngữ cảnh,this. Hãy đăng xuất đối tượng phản hồi bất cứ khi nào chúng ta nhận được yêu cầu.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

_.get('/hello', getMessage);

function *getMessage(){
   this.body = 'Your request has been logged.';
   console.log(this.response);
}

app.use(_.routes());
app.listen(3000);

Khi bạn chạy mã này và điều hướng đến https://localhost:3000/hello thì bạn sẽ nhận được phản hồi sau.

Trên bảng điều khiển của bạn, bạn sẽ đăng xuất đối tượng yêu cầu.

{ 
   status: 200,
   message: 'OK',
   header: 
   {
      'content-type': 'text/plain; charset=utf-8',
      'content-length': '12' 
   },
   body: 'Your request has been logged.' 
}

Trạng thái và thông báo do Koa tự động đặt nhưng chúng tôi có thể sửa đổi. Nếu chúng tôi không đặt nội dung phản hồi, mã trạng thái được đặt thành 404. Khi chúng tôi đặt nội dung phản hồi, trạng thái được đặt thành 200 theo mặc định. Chúng tôi có thể ghi đè hành vi này một cách rõ ràng.

Chúng tôi có quyền truy cập vào nhiều thuộc tính hữu ích của phản hồi bằng cách sử dụng đối tượng này. Hãy để chúng tôi xem xét một số ví dụ -

response.header

Cung cấp tất cả các tiêu đề phản hồi.

response.status

Cung cấp trạng thái phản hồi (200, 404, 500, v.v.). Thuộc tính này cũng được sử dụng để đặt trạng thái phản hồi.

response.message

Cung cấp thông báo phản hồi. Thuộc tính này cũng được sử dụng để đặt các thông báo tùy chỉnh với phản hồi. Nó được liên kết với response.status.

response.body

Nhận hoặc đặt nội dung phản hồi. Thông thường, chúng tôi truy cập nó bằng cách sử dụng đối tượng ngữ cảnh. Đây chỉ là một cách khác để truy cập nó. Phần thân có thể thuộc loại: Chuỗi, Bộ đệm, Dòng, Đối tượng hoặc Null.

response.type

Nhận hoặc đặt loại nội dung của phản hồi hiện tại.

response.get (trường)

Hàm này được sử dụng để lấy giá trị của tiêu đề có trường giá trị không phân biệt chữ hoa chữ thường.

response.set (trường, giá trị)

Hàm này được sử dụng để đặt tiêu đề trên phản hồi bằng cách sử dụng cặp giá trị và trường.

response.remove (trường)

Hàm này được sử dụng để bỏ đặt tiêu đề trên phản hồi bằng cách sử dụng tên trường.

Bạn có thể đọc thêm về đối tượng phản hồi trong tài liệu tại Phản hồi .

Chuyển hướng là rất quan trọng khi tạo trang web. Nếu một URL không đúng định dạng được yêu cầu hoặc có một số lỗi trên máy chủ của bạn, bạn nên chuyển hướng chúng đến các trang lỗi tương ứng. Chuyển hướng cũng có thể được sử dụng để ngăn mọi người ra khỏi các khu vực hạn chế trên trang web của bạn.

Hãy để chúng tôi tạo một trang lỗi và chuyển hướng đến trang đó bất cứ khi nào ai đó yêu cầu một URL không đúng định dạng.

var koa = require('koa');
var router = require('koa-router');
var app = koa();
var _ = router();

_.get('/not_found', printErrorMessage);
_.get('/hello', printHelloMessage);

app.use(_.routes());
app.use(handle404Errors);

function *printErrorMessage() {
   this.status = 404;
   this.body = "Sorry we do not have this resource.";
}
function *printHelloMessage() {
   this.status = 200;
   this.body = "Hey there!";
}
function *handle404Errors(next) {
   if (404 != this.status) return;
   this.redirect('/not_found');
}
app.listen(3000);

Khi chúng tôi chạy mã này và điều hướng đến bất kỳ tuyến đường nào khác ngoài / hello, chúng tôi sẽ được chuyển hướng đến / not_found. Chúng tôi đã đặt phần mềm trung gian ở cuối (lệnh gọi hàm app.use đến phần mềm trung gian này). Điều này đảm bảo cuối cùng chúng tôi tiếp cận được phần mềm trung gian và gửi phản hồi tương ứng. Sau đây là kết quả chúng ta thấy khi chạy đoạn mã trên.

Khi chúng tôi điều hướng đến https://localhost:3000/hello, chúng tôi nhận được -

Nếu chúng tôi điều hướng đến bất kỳ tuyến đường nào khác, chúng tôi sẽ -

Xử lý lỗi đóng một phần quan trọng trong việc xây dựng ứng dụng web. Koa cũng sử dụng phần mềm trung gian cho mục đích này.

Trong Koa, bạn thêm một phần mềm trung gian try { yield next }là một trong những phần mềm trung gian đầu tiên. Nếu chúng tôi gặp bất kỳ lỗi nào ở phía dưới, chúng tôi quay lại mệnh đề bắt được liên kết và xử lý lỗi tại đây. Ví dụ -

var koa = require('koa');
var app = koa();

//Error handling middleware
app.use(function *(next) {
   try {
      yield next;
   } catch (err) {
      this.status = err.status || 500;
      this.body = err.message;
      this.app.emit('error', err, this);
   }
});

//Create an error in the next middleware
//Set the error message and status code and throw it using context object

app.use(function *(next) {
   //This will set status and message
   this.throw('Error Message', 500);
});

app.listen(3000);

Chúng tôi đã cố tình tạo ra một lỗi trong đoạn mã trên và đang xử lý lỗi trong khối bắt phần mềm trung gian đầu tiên của chúng tôi. Điều này sau đó được gửi đến bảng điều khiển của chúng tôi cũng như được gửi dưới dạng phản hồi cho khách hàng của chúng tôi. Sau đây là thông báo lỗi chúng tôi nhận được khi chúng tôi kích hoạt lỗi này.

InternalServerError: Error Message
   at Object.module.exports.throw 
      (/home/ayushgp/learning/koa.js/node_modules/koa/lib/context.js:91:23)
   at Object.<anonymous> (/home/ayushgp/learning/koa.js/error.js:18:13)
   at next (native)
   at onFulfilled (/home/ayushgp/learning/koa.js/node_modules/co/index.js:65:19)
   at /home/ayushgp/learning/koa.js/node_modules/co/index.js:54:5
   at Object.co (/home/ayushgp/learning/koa.js/node_modules/co/index.js:50:10)
   at Object.toPromise (/home/ayushgp/learning/koa.js/node_modules/co/index.js:118:63)
   at next (/home/ayushgp/learning/koa.js/node_modules/co/index.js:99:29)
   at onFulfilled (/home/ayushgp/learning/koa.js/node_modules/co/index.js:69:7)
   at /home/ayushgp/learning/koa.js/node_modules/co/index.js:54:5

Ngay bây giờ bất kỳ yêu cầu nào được gửi đến máy chủ sẽ dẫn đến lỗi này.

Các chức năng phần mềm trung gian là các chức năng có quyền truy cập vào context objectvà chức năng phần mềm trung gian tiếp theo trong chu trình phản hồi yêu cầu của ứng dụng. Các chức năng này được sử dụng để sửa đổi các đối tượng yêu cầu và phản hồi cho các tác vụ như phân tích cú pháp nội dung yêu cầu, thêm tiêu đề phản hồi, v.v. Koa tiến thêm một bước nữa bằng cách tạo ra'downstream', sau đó chuyển điều khiển trở lại 'upstream'. Hiệu ứng này được gọi làcascading.

Sau đây là một ví dụ đơn giản về chức năng phần mềm trung gian đang hoạt động.

var koa = require('koa');
var app = koa();
var _ = router();

//Simple request time logger
app.use(function* (next) {
   console.log("A new request received at " + Date.now());
   
   //This function call is very important. It tells that more processing is 
   //required for the current request and is in the next middleware function/route handler.
   yield next;
});

app.listen(3000);

Phần mềm trung gian ở trên được gọi cho mọi yêu cầu trên máy chủ. Vì vậy, sau mỗi yêu cầu, chúng tôi sẽ nhận được thông báo sau trong bảng điều khiển.

A new request received at 1467267512545

Để giới hạn nó trong một tuyến đường cụ thể (và tất cả các tuyến con của nó), chúng ta chỉ cần tạo các tuyến đường như chúng ta đã làm để định tuyến. Trên thực tế, những phần mềm trung gian của nó chỉ xử lý yêu cầu của chúng tôi.

Ví dụ,

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

//Simple request time logger
_.get('/request/*', function* (next) {
   console.log("A new request received at " + Date.now());
   yield next;
});

app.use(_.routes());
app.listen(3000);

Bây giờ bất cứ khi nào bạn yêu cầu bất kỳ quy trình con nào của '/ request', chỉ khi đó nó sẽ ghi lại thời gian.

Thứ tự cuộc gọi phần mềm trung gian

Một trong những điều quan trọng nhất về phần mềm trung gian trong Koa là thứ tự mà chúng được viết / đưa vào tệp của bạn, là thứ tự mà chúng được thực thi ở phía dưới. Ngay sau khi chúng tôi nhấn vào một tuyên bố lợi nhuận trong một phần mềm trung gian, nó sẽ chuyển sang phần mềm trung gian tiếp theo trong hàng, cho đến khi chúng tôi đến phần cuối cùng. Sau đó, một lần nữa chúng tôi bắt đầu di chuyển trở lại và tiếp tục các chức năng từ các câu lệnh lợi nhuận.

Ví dụ: trong đoạn mã sau, chức năng đầu tiên thực hiện đầu tiên cho đến khi có lợi nhuận, sau đó là phần mềm trung gian thứ hai cho đến khi có lợi nhuận, sau đó là chức năng thứ ba. Vì chúng tôi không còn phần mềm trung gian ở đây, chúng tôi bắt đầu di chuyển trở lại, thực thi theo thứ tự ngược lại, tức là thứ ba, thứ hai, thứ nhất. Ví dụ này tóm tắt cách sử dụng phần mềm trung gian theo cách Koa.

var koa = require('koa');
var app = koa();

//Order of middlewares
app.use(first);
app.use(second);
app.use(third);

function *first(next) {
   console.log("I'll be logged first. ");
   
   //Now we yield to the next middleware
   yield next;
   
   //We'll come back here at the end after all other middlewares have ended
   console.log("I'll be logged last. ");
};

function *second(next) {
   console.log("I'll be logged second. ");
   yield next;
   console.log("I'll be logged fifth. ");
};

function *third(next) {
   console.log("I'll be logged third. ");
   yield next;
   console.log("I'll be logged fourth. ");
};

app.listen(3000);

Khi chúng tôi truy cập '/' sau khi chạy mã này, trên bảng điều khiển của chúng tôi, chúng tôi sẽ nhận được -

I'll be logged first. 
I'll be logged second. 
I'll be logged third. 
I'll be logged fourth. 
I'll be logged fifth. 
I'll be logged last.

Sơ đồ sau đây tóm tắt những gì đang thực sự xảy ra trong ví dụ trên.

Bây giờ chúng ta đã biết cách tạo phần mềm trung gian của riêng mình, chúng ta hãy thảo luận về một số phần mềm trung gian được cộng đồng tạo ra phổ biến nhất.

Phần mềm trung gian của bên thứ ba

Danh sách các phần mềm trung gian của bên thứ ba cho express có sẵn tại đây. Sau đây là một số phần mềm trung gian được sử dụng phổ biến nhất:

  • koa-bodyparser
  • koa-router
  • koa-static
  • koa-compress

Chúng ta sẽ thảo luận về nhiều phần mềm trung gian trong các chương tiếp theo.

Pug là một động cơ tạo khuôn mẫu. Các công cụ tạo khuôn mẫu được sử dụng để loại bỏ sự lộn xộn của mã máy chủ của chúng tôi với HTML, nối các chuỗi một cách lung tung với các mẫu HTML hiện có. Pug là một động cơ tạo khuôn mẫu rất mạnh mẽ, có nhiều tính năng nhưfilters, includes, inheritance, interpolation, vv Có rất nhiều cơ sở để giải quyết vấn đề này.

Để sử dụng Pug với Koa, chúng ta cần cài đặt nó bằng lệnh sau.

$ npm install --save pug koa-pug

Sau khi cài đặt pug, hãy đặt nó làm công cụ tạo khuôn mẫu cho ứng dụng của bạn. Thêm mã sau vào tệp app.js của bạn.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app //Equivalent to app.use(pug)
});

var _ = router(); //Instantiate the router

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

Bây giờ, tạo một thư mục mới được gọi là các khung nhìn. Trong thư mục, tạo một tệp có tên first_view.pug và nhập dữ liệu sau vào đó.

doctype html
html
   head
      title = "Hello Pug"
   body
      p.greetings#people Hello Views!

Để chạy trang này, hãy thêm tuyến đường sau vào ứng dụng của bạn.

_.get('/hello', getMessage); // Define routes

function *getMessage(){
   this.render('first_view');
};

Bạn sẽ nhận được đầu ra là -

Những gì Pug làm là, nó chuyển đổi đánh dấu trông rất đơn giản này thành html. Chúng tôi không cần theo dõi việc đóng các thẻ của mình, không cần sử dụng các từ khóa class và id, thay vào đó là sử dụng '.' và '#' để xác định chúng. Đoạn mã trên trước tiên được chuyển đổi thành

<!DOCTYPE html>
<html>
   <head>
      <title>Hello Pug</title>
   </head>
    
   <body>
      <p class = "greetings" id = "people">Hello Views!</p>
   </body>
</html>

Pug có khả năng làm được nhiều việc hơn là đơn giản hóa việc đánh dấu HTML. Hãy cùng khám phá một số đặc điểm này của Pug.

Thẻ đơn giản

Các thẻ được lồng vào nhau theo thụt lề của chúng. Giống như trong ví dụ trên,<title> được thụt vào trong <head>thẻ, vì vậy nó đã ở bên trong nó. Tuy nhiên,<body> thẻ nằm trên cùng một thụt lề, do đó nó là anh em của <head> nhãn.

Chúng tôi không cần phải đóng thẻ. Ngay khi Pug gặp thẻ tiếp theo ở cùng cấp độ thụt đầu dòng hoặc bên ngoài, nó sẽ đóng thẻ cho chúng ta.

Có ba phương pháp để đưa văn bản vào bên trong thẻ:

  • Không gian riêng biệt -
h1 Welcome to Pug
  • Văn bản dạng ống -
div
   | To insert multiline text, 
   | You can use the pipe operator.
  • Khối văn bản -
div.
   But that gets tedious if you have a lot of text. 
   You can use "." at the end of tag to denote block of text. 
   To put tags inside this block, simply enter tag in a new line and 
   indent it accordingly.

Bình luận

Pug sử dụng cú pháp tương tự như JavaScript (//) để tạo nhận xét. Những bình luận này được chuyển đổi thành bình luận html (<! - comment ->). Ví dụ,

//This is a Pug comment

Nhận xét này được chuyển đổi thành -

<!--This is a Pug comment-->

Thuộc tính

Để xác định thuộc tính, chúng tôi sử dụng danh sách các thuộc tính được phân tách bằng dấu phẩy, trong ngoặc đơn. Thuộc tính lớp và ID có các đại diện đặc biệt. Dòng mã sau bao gồm việc xác định các thuộc tính, lớp và id cho một thẻ html nhất định.

div.container.column.main#division(width = "100",height = "100")

Dòng mã này, được chuyển đổi thành -

<div class = "container column main" id = "division" width = "100" height = "100"></div>

Chuyển giá trị cho mẫu

Khi chúng tôi hiển thị một mẫu Pug, chúng tôi thực sự có thể chuyển cho nó một giá trị từ trình xử lý tuyến đường của chúng tôi, sau đó chúng tôi có thể sử dụng trong mẫu của mình. Tạo một trình xử lý tuyến đường mới với mã sau.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app // equals to pug.use(app) and app.use(pug.middleware)
});

var _ = router(); //Instantiate the router

_.get('//dynamic_view', dynamicMessage); // Define routes

function *dynamicMessage(){
   this.render('dynamic', {
      name: "TutorialsPoint", 
      url:"https://www.tutorialspoint.com"
   });
};

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

Sau đó, tạo một tệp dạng xem mới trong thư mục dạng xem, có tên là dynamic.pug, bằng cách sử dụng mã sau.

html
   head
      title = name
   body
      h1 = name
      a(href = url) URL

Mở localhost:3000/dynamictrong trình duyệt của bạn và sau đây sẽ là đầu ra. -

Chúng ta cũng có thể sử dụng các biến được truyền này trong văn bản. Để chèn các biến đã chuyển vào giữa văn bản của thẻ, chúng tôi sử dụng cú pháp # {variableName}. Ví dụ, trong ví dụ trên, nếu chúng ta muốn chèn Lời chào từ TutorialsPoint, thì chúng ta phải sử dụng đoạn mã sau.

html
   head
      title = name
   body
      h1 Greetings from #{name}
      a(href = url) URL

Phương pháp sử dụng giá trị này được gọi là nội suy.

Điều kiện

Chúng ta cũng có thể sử dụng các câu lệnh điều kiện và các cấu trúc lặp. Hãy xem xét ví dụ thực tế này, nếu một người dùng đã đăng nhập, chúng tôi muốn hiển thị "Xin chào, Người dùng" và nếu không, chúng tôi muốn hiển thị cho họ liên kết "Đăng nhập / Đăng ký". Để đạt được điều này, chúng ta có thể xác định một mẫu đơn giản như:

html
   head
      title Simple template
   body
      if(user)
         h1 Hi, #{user.name}
      else
         a(href = "/sign_up") Sign Up

Khi chúng tôi kết xuất điều này bằng cách sử dụng các tuyến đường của chúng tôi và nếu chúng tôi truyền một đối tượng như -

this.render('/dynamic',{user: 
   {name: "Ayush", age: "20"}
});

Nó sẽ đưa ra một thông báo hiển thị Xin chào, Ayush. Tuy nhiên, nếu chúng tôi không chuyển bất kỳ đối tượng nào hoặc chuyển một đối tượng không có khóa người dùng, thì chúng tôi sẽ nhận được liên kết Đăng ký.

Bao gồm và các thành phần

Pug cung cấp một cách rất trực quan để tạo các thành phần cho một trang web. Ví dụ: nếu bạn thấy một trang web tin tức, tiêu đề có biểu trưng và danh mục luôn cố định. Thay vì sao chép nó vào mọi chế độ xem, chúng ta có thể sử dụng bao gồm. Ví dụ sau cho thấy cách chúng ta có thể sử dụng bao gồm:

Tạo ba chế độ xem với mã sau:

header.pug

div.header.
   I'm the header for this website.

content.pug

html
   head
      title Simple template
   body
      include ./header.pug
      h3 I'm the main content
      include ./footer.pug

footer.pug

div.footer.
   I'm the footer for this website.

Tạo một tuyến đường cho việc này như sau.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app //Equivalent to app.use(pug)
});

var _ = router(); //Instantiate the router

_.get('/components', getComponents);

function *getComponents(){
   this.render('content.pug');
}

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

Đi đến localhost:3000/components, bạn sẽ nhận được kết quả sau.

include cũng có thể được sử dụng để bao gồm plaintext, CSS và JavaScript.

Còn rất nhiều tính năng khác của Pug. Tuy nhiên, những điều đó nằm ngoài phạm vi của hướng dẫn này. Bạn có thể khám phá thêm về Pug tại Pug .

Biểu mẫu là một phần không thể thiếu của web. Hầu hết mọi trang web chúng tôi truy cập đều cung cấp cho chúng tôi các biểu mẫu gửi hoặc lấy một số thông tin cho chúng tôi. Để bắt đầu với các biểu mẫu, trước tiên chúng ta sẽ cài đặt koa-body. Để cài đặt cái này, hãy đi tới thiết bị đầu cuối của bạn và sử dụng -

$ npm install --save koa-body

Thay thế nội dung tệp app.js của bạn bằng mã sau.

var koa = require('koa');
var router = require('koa-router');
var bodyParser = require('koa-body');
var app = koa();

//Set up Pug
var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app //Equivalent to app.use(pug)
});

//Set up body parsing middleware
app.use(bodyParser({
   formidable:{uploadDir: './uploads'},
   multipart: true,
   urlencoded: true
}));

_.get('/', renderForm);
_.post('/', handleForm);

function * renderForm(){
   this.render('form');
}
function *handleForm(){
   console.log(this.request.body);
   console.log(this.req.body);
   this.body = this.request.body; //This is where the parsed request is stored
}

app.use(_.routes()); 
app.listen(3000);

Những điều mới mà chúng tôi đang làm ở đây là nhập phân tích cú pháp cơ thể và multer. Chúng tôi đang sử dụng trình phân tích cú pháp nội dung để phân tích cú pháp các yêu cầu tiêu đề json và x-www-form-urlencoded, trong khi chúng tôi sử dụng multer để phân tích cú pháp đa phần / biểu mẫu-dữ liệu.

Hãy để chúng tôi tạo một biểu mẫu html để kiểm tra điều này! Tạo một dạng xem mới có tên form.pug với mã sau.

html
   head
      title Form Tester
   body
      form(action = "/", method = "POST")
         div
            label(for = "say") Say: 
            input(name = "say" value = "Hi")
         br
         div
            label(for = "to") To: 
            input(name = "to" value = "Koa form")
         br
         button(type = "submit") Send my greetings

Chạy máy chủ của bạn bằng -

nodemon index.js

Bây giờ, hãy truy cập localhost: 3000 / và điền vào biểu mẫu bạn muốn và gửi nó. Bạn sẽ nhận được phản hồi là -

Hãy xem bảng điều khiển của bạn, nó sẽ hiển thị cho bạn phần nội dung yêu cầu của bạn dưới dạng một đối tượng JavaScript. Ví dụ -

Các this.request.bodyđối tượng chứa nội dung yêu cầu đã được phân tích cú pháp của bạn. Để sử dụng các trường từ đối tượng đó, chỉ cần sử dụng chúng như các đối tượng JS bình thường.

Đây chỉ là một cách để gửi yêu cầu. Có nhiều cách khác, nhưng những cách đó không liên quan để đề cập ở đây, vì ứng dụng Koa của chúng tôi sẽ xử lý tất cả các yêu cầu đó theo cùng một cách. Để tìm hiểu thêm về những cách khác nhau để tạo ra một yêu cầu, có một cái nhìn tại này trang.

Ứng dụng web cần cung cấp chức năng cho phép tải tệp lên. Hãy để chúng tôi xem cách chúng tôi có thể nhận tệp từ máy khách và lưu trữ chúng trên máy chủ của chúng tôi.

Chúng tôi đã sử dụng phần mềm trung gian koa-body để phân tích cú pháp các yêu cầu. Phần mềm trung gian này cũng được sử dụng để xử lý tải lên tệp. Hãy để chúng tôi tạo một biểu mẫu cho phép chúng tôi tải lên các tệp và sau đó lưu các tệp này bằng Koa. Đầu tiên, hãy tạo một mẫu có tênfile_upload.pug với các nội dung sau.

html
   head
      title File uploads
   body
      form(action = "/upload" method = "POST" enctype = "multipart/form-data")
         div
            input(type = "text" name = "name" placeholder = "Name")
         
         div
            input(type = "file" name = "image")
         
         div
            input(type = "submit")

Lưu ý rằng bạn cần cung cấp cùng loại mã hóa như trên trong biểu mẫu của mình. Bây giờ hãy để chúng tôi xử lý dữ liệu này trên máy chủ của chúng tôi.

var koa = require('koa');
var router = require('koa-router');
var bodyParser = require('koa-body');
var app = koa();

//Set up Pug
var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app 
});

//Set up body parsing middleware
app.use(bodyParser({
   formidable:{uploadDir: './uploads'},    //This is where the files would come
   multipart: true,
   urlencoded: true
}));

var _ = router(); //Instantiate the router

_.get('/files', renderForm);
_.post('/upload', handleForm);

function * renderForm(){
   this.render('file_upload');
}

function *handleForm(){
   console.log("Files: ", this.request.body.files);
   console.log("Fields: ", this.request.body.fields);
   this.body = "Received your data!"; //This is where the parsed request is stored
}

app.use(_.routes()); 
app.listen(3000);

Khi bạn chạy điều này, bạn sẽ nhận được biểu mẫu sau.

Khi bạn gửi cái này, bảng điều khiển của bạn sẽ tạo ra kết quả sau.

Các tệp đã được tải lên được lưu trữ trong đường dẫn ở đầu ra ở trên. Bạn có thể truy cập các tệp trong yêu cầu bằng cách sử dụngthis.request.body.files và các trường trong yêu cầu đó bởi this.request.body.fields.

Tệp tĩnh là tệp mà khách hàng tải xuống khi chúng ở trên máy chủ. Tạo một thư mục mới,public. Theo mặc định, Express không cho phép bạn cung cấp các tệp tĩnh.

Chúng tôi cần một phần mềm trung gian để phục vụ mục đích này. Tiếp tục và cài đặtkoa-serve -

$ npm install --save koa-static

Bây giờ chúng ta cần usephần mềm trung gian này. Trước đó, hãy tạo một thư mục gọi là public. Chúng tôi sẽ lưu trữ tất cả các tệp tĩnh của chúng tôi ở đây. Điều này cho phép chúng tôi giữ an toàn cho mã máy chủ của mình vì không có gì bên trên thư mục chung này có thể truy cập được đối với khách hàng. Sau khi bạn đã tạo một thư mục công cộng, hãy tạo một tệp có tênhello.txttrong đó với bất kỳ nội dung nào bạn thích. Bây giờ hãy thêm phần sau vào app.js của bạn.

var serve = require('koa-static');
var koa = require('koa');
var app = koa();

app.use(serve('./public'));

app.listen(3000);

Note- Koa tra cứu các tệp liên quan đến thư mục tĩnh, vì vậy tên của thư mục tĩnh không phải là một phần của URL. Tuyến gốc hiện được đặt thành công khai của bạn, vì vậy tất cả các tệp tĩnh bạn tải sẽ được coi là công khai là gốc. Để kiểm tra xem điều này có hoạt động tốt hay không, hãy chạy ứng dụng của bạn và truy cậphttps://localhost:3000/hello.txt

Bạn sẽ nhận được kết quả sau. Lưu ý rằng đây không phải là tài liệu HTML hoặc dạng xem Pug, mà nó là một tệp txt đơn giản.

Nhiều Dirs tĩnh

Chúng tôi cũng có thể đặt nhiều thư mục tài sản tĩnh bằng cách sử dụng:

var serve = require('koa-static');
var koa = require('koa');
var app = koa();

app.use(serve('./public'));
app.use(serve('./images'));

app.listen(3000);

Bây giờ khi chúng tôi yêu cầu một tệp, Koa sẽ tìm kiếm các thư mục này và gửi cho chúng tôi tệp phù hợp.

Cookie là các tệp / dữ liệu nhỏ, đơn giản được gửi đến máy khách với yêu cầu của máy chủ và được lưu trữ ở phía máy khách. Mỗi khi người dùng tải lại trang web, cookie này sẽ được gửi kèm theo yêu cầu. Điều này giúp theo dõi các hành động của người dùng. Có rất nhiều cách sử dụng HTTP Cookies.

  • Quản lý phiên
  • Cá nhân hóa (Hệ thống khuyến nghị)
  • Theo dõi người dùng

Để sử dụng cookie với Koa, chúng tôi có các chức năng: ctx.cookies.set()ctx.cookies.get(). Để đặt một cookie mới, hãy xác định một tuyến đường mới trong ứng dụng Koa của chúng tôi.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

_.get('/', setACookie);

function *setACookie() {
   this.cookies.set('foo', 'bar', {httpOnly: false});
}

var _ = router();

app.use(_.routes());
app.listen(3000);

Để kiểm tra xem cookie đã được thiết lập hay chưa, chỉ cần truy cập trình duyệt của bạn, kích hoạt bảng điều khiển và nhập -

console.log(document.cookie);

Điều này sẽ tạo ra kết quả sau (bạn có thể đặt nhiều cookie hơn có thể do các tiện ích mở rộng trong trình duyệt của bạn).

"foo = bar"

Đây là một ví dụ về điều trên.

Trình duyệt cũng gửi lại cookie mỗi khi nó truy vấn máy chủ. Để xem cookie trên máy chủ của bạn, trên bảng điều khiển máy chủ trong một tuyến, hãy thêm mã sau vào tuyến đó.

console.log('Cookies: foo = ', this.cookies.get('foo'));

Lần tới khi bạn gửi một yêu cầu đến tuyến đường này, bạn sẽ nhận được kết quả sau.

Cookies: foo = bar

Thêm cookie với thời gian hết hạn

Bạn có thể thêm các cookie hết hạn. Để thêm một cookie hết hạn, chỉ cần chuyển một đối tượng có thuộc tính 'expires' được đặt vào thời điểm bạn muốn nó hết hạn. Ví dụ,

var koa = require('koa');
var router = require('koa-router');
var app = koa();

_.get('/', setACookie);

function *setACookie(){
   //Expires after 360000 ms from the time it is set.
	this.cookies.set('name', 'value', { 
      httpOnly: false, expires: 360000 + Date.now() });
}

var _ = router();

app.use(_.routes());
app.listen(3000);

Xóa cookie hiện có

Để hủy đặt cookie, chỉ cần đặt cookie thành một chuỗi trống. Ví dụ: nếu bạn cần xóa một cookie có tênfoo, sử dụng mã sau.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

_.get('/', setACookie);

function *setACookie(){
   //Expires after 360000 ms from the time it is set.
   this.cookies.set('name', '');
}

var _ = router();

app.use(_.routes());
app.listen(3000);

Điều này sẽ hủy đặt cookie đã nói. Lưu ý rằng bạn nên đểHttpOnly tùy chọn đúng khi không sử dụng cookie trong mã phía máy khách.

HTTP là không trạng thái, do đó để liên kết một yêu cầu với bất kỳ yêu cầu nào khác, bạn cần có cách lưu trữ dữ liệu người dùng giữa các yêu cầu HTTP. Cookie và tham số URL đều là những cách phù hợp để vận chuyển dữ liệu giữa máy khách và máy chủ. Tuy nhiên, cả hai đều có thể đọc được ở phía máy khách. Phiên giải quyết chính xác vấn đề này. Bạn gán cho khách hàng một ID và nó thực hiện tất cả các yêu cầu khác bằng cách sử dụng ID đó. Thông tin liên kết với máy khách được lưu trữ trên máy chủ được liên kết với ID này.

Chúng tôi sẽ cần koa-session, do đó hãy cài đặt nó bằng cách sử dụng -

npm install --save koa-session

Chúng tôi sẽ đặt koa-sessionphần mềm trung gian tại chỗ. Trong ví dụ này, chúng tôi sẽ sử dụng RAM để lưu trữ các phiên. Không bao giờ sử dụng điều này trong môi trường sản xuất. Phần mềm trung gian phiên xử lý mọi thứ, tức là tạo phiên, thiết lập cookie phiên và tạo đối tượng phiên trong đối tượng ngữ cảnh.

Bất cứ khi nào chúng tôi thực hiện lại yêu cầu từ cùng một khách hàng, chúng tôi sẽ lưu trữ thông tin phiên của họ với chúng tôi (do máy chủ đó chưa được khởi động lại). Chúng ta có thể thêm nhiều thuộc tính hơn vào đối tượng phiên này. Trong ví dụ sau, chúng tôi sẽ tạo bộ đếm lượt xem cho một máy khách.

var session = require('koa-session');
var koa = require('koa');
var app = koa();

app.keys = ['Shh, its a secret!'];
app.use(session(app));  // Include the session middleware

app.use(function *(){
   var n = this.session.views || 0;
   this.session.views = ++n;
   
   if(n === 1)
      this.body = 'Welcome here for the first time!';
   else
      this.body = "You've visited this page " + n + " times!";
})

app.listen(3000);

Đoạn mã trên có chức năng gì, khi người dùng truy cập trang web, nó sẽ tạo một phiên mới cho người dùng và chỉ định một cookie. Lần tới khi người dùng truy cập, cookie sẽ được kiểm tra và biến phiên page_view được cập nhật tương ứng.

Bây giờ nếu bạn chạy ứng dụng và truy cập localhost:3000, bạn sẽ nhận được phản hồi sau.

Nếu bạn truy cập lại trang, số lượt truy cập trang sẽ tăng lên. Trong trường hợp này, trang đã được làm mới 12 lần.

Xác thực là một quá trình trong đó thông tin xác thực được cung cấp được so sánh với thông tin trong hồ sơ trong cơ sở dữ liệu thông tin của người dùng được ủy quyền trên hệ điều hành cục bộ hoặc trong máy chủ xác thực. Nếu thông tin xác thực khớp, quá trình hoàn tất và người dùng được cấp quyền truy cập.

Chúng tôi sẽ tạo ra một hệ thống xác thực rất cơ bản sẽ sử dụng Basic HTTP Authentication. Đây là cách đơn giản nhất có thể để thực thi kiểm soát truy cập vì nó không yêu cầu cookie, phiên hoặc bất kỳ thứ gì khác. Để sử dụng điều này, máy khách phải gửi tiêu đề Ủy quyền cùng với mọi yêu cầu mà nó đưa ra. Tên người dùng và mật khẩu không được mã hóa, nhưng được nối trong một chuỗi như sau.

username:password

Chuỗi này được mã hóa bằng Base64 và từ Basic được đặt trước giá trị này. Ví dụ: nếu tên người dùng của bạn là Ayush và mật khẩu là Ấn Độ, thì chuỗi"Ayush:India" sẽ được gửi dưới dạng mã hóa trong tiêu đề ủy quyền.

Authorization: Basic QXl1c2g6SW5kaWE=

Để triển khai điều này trong ứng dụng koa của bạn, bạn sẽ cần phần mềm trung gian koa-basic-auth. Cài đặt nó bằng -

$ npm install --save koa-basic-auth

Bây giờ, hãy mở tệp app.js của bạn và nhập mã sau vào đó.

//This is what the authentication would be checked against
var credentials = { name: 'Ayush', pass: 'India' }

var koa = require('koa');
var auth = require('koa-basic-auth');
var _ = require('koa-router')();

var app = koa();

//Error handling middleware
app.use(function *(next){
   try {
      yield next;
   } catch (err) {
      if (401 == err.status) {
         this.status = 401;
         this.set('WWW-Authenticate', 'Basic');
         this.body = 'You have no access here';
      } else {
         throw err;
      }
   }
});

// Set up authentication here as first middleware. 
// This returns an error if user is not authenticated.
_.get('/protected', auth(credentials), function *(){
   this.body = 'You have access to the protected area.';
   yield next;
});

// No authentication middleware present here.
_.get('/unprotected', function*(next){
   this.body = "Anyone can access this area";
   yield next;
});

app.use(_.routes());
app.listen(3000);

Chúng tôi đã tạo phần mềm trung gian xử lý lỗi để xử lý tất cả các lỗi liên quan đến xác thực. Sau đó, chúng tôi đã tạo 2 tuyến đường -

  • /protected- Tuyến đường này chỉ có thể được truy cập nếu người dùng gửi tiêu đề xác thực chính xác. Đối với tất cả những người khác, nó sẽ báo lỗi.

  • /unprotected - Tuyến đường này có thể được truy cập bởi bất kỳ ai, có hoặc không có xác thực.

Bây giờ nếu bạn gửi một yêu cầu đến / bảo vệ mà không có tiêu đề xác thực hoặc với thông tin đăng nhập sai, bạn sẽ nhận được lỗi. Ví dụ,

$ curl https://localhost:3000/protected

Bạn sẽ nhận được phản hồi là -

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic
Content-Type: text/plain; charset=utf-8
Content-Length: 28
Date: Sat, 17 Sep 2016 19:05:56 GMT
Connection: keep-alive

Please authenticate yourself

Tuy nhiên, với thông tin đăng nhập phù hợp, bạn sẽ nhận được phản hồi như mong đợi. Ví dụ,

$ curl -H "Authorization: basic QXl1c2g6SW5kaWE=" https://localhost:3000/protected -i

Bạn sẽ nhận được phản hồi là -

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 38
Date: Sat, 17 Sep 2016 19:07:33 GMT
Connection: keep-alive

You have access to the protected area.

Mọi người vẫn có thể truy cập vào tuyến đường / không được bảo vệ.

Nén là một cách đơn giản, hiệu quả để tiết kiệm băng thông và tăng tốc trang web của bạn. Nó chỉ tương thích với các trình duyệt hiện đại và nên được sử dụng thận trọng nếu người dùng của bạn cũng sử dụng các trình duyệt cũ.

Khi gửi phản hồi từ máy chủ, nếu sử dụng tính năng nén, nó có thể cải thiện đáng kể thời gian tải. Chúng tôi sẽ sử dụng một phần mềm trung gian có tên làkoa-compress để xử lý việc nén các tệp cũng như đặt các tiêu đề thích hợp.

Tiếp tục và cài đặt phần mềm trung gian bằng cách sử dụng -

$ npm install --save koa-compress

Bây giờ trong tệp app.js của bạn, hãy thêm mã sau:

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app //Equivalent to app.use(pug)
});

app.use(compress({
   filter: function (content_type) {
      return /text/i.test(content_type)
   },
   threshold: 2048,
   flush: require('zlib').Z_SYNC_FLUSH
}));

var _ = router(); //Instantiate the router

_.get('/', getRoot);

function *getRoot(next){
   this.render('index');
}

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

Điều này đặt phần mềm trung gian nén của chúng tôi vào đúng vị trí. Tùy chọn bộ lọc là một chức năng kiểm tra loại nội dung phản hồi để quyết định xem có nén hay không. Tùy chọn ngưỡng là kích thước phản hồi tối thiểu tính bằng byte để nén. Điều này đảm bảo chúng tôi không nén từng phản hồi nhỏ.

Sau đây là một phản hồi mà không cần nén.

Sau đây là phản ứng tương tự với nén.

Nếu bạn nhìn vào tab kích thước ở dưới cùng, bạn rất có thể thấy sự khác biệt giữa hai loại. Có hơn 150% cải thiện, khi chúng tôi nén các tệp.

Bộ nhớ đệm là thuật ngữ để lưu trữ các phản hồi có thể sử dụng lại để thực hiện các yêu cầu tiếp theo nhanh hơn. Mọi trình duyệt đều có triển khai bộ đệm HTTP. Tất cả những gì chúng ta phải làm là đảm bảo rằng mỗi phản hồi của máy chủ cung cấp các chỉ thị tiêu đề HTTP chính xác để hướng dẫn trình duyệt về thời gian và bao lâu phản hồi có thể được trình duyệt lưu vào bộ nhớ cache.

Sau đây là một số lợi ích của việc đưa vào bộ nhớ đệm trong các ứng dụng web của bạn -

  • Chi phí mạng của bạn giảm xuống. Nếu nội dung của bạn được lưu vào bộ nhớ đệm, bạn sẽ cần gửi ít nội dung hơn cho mọi yêu cầu tiếp theo.

  • Tốc độ và hiệu suất của trang web của bạn tăng lên.

  • Nội dung của bạn có thể được cung cấp ngay cả khi khách hàng của bạn ngoại tuyến.

Chúng tôi sẽ sử dụng phần mềm trung gian koa-static-cache để triển khai bộ nhớ đệm trong ứng dụng của mình. Cài đặt các phần mềm trung gian này bằng cách sử dụng -

$ npm install --save koa-static-cache

Truy cập tệp app.js của bạn và thêm mã sau vào tệp đó.

var koa = require('koa');
var app = koa();

var path = require('path');
var staticCache = require('koa-static-cache');

app.use(staticCache(path.join(__dirname, 'public'), {
   maxAge: 365 * 24 * 60 * 60  //Add these files to caches for a year
}))

app.listen(3000);

Các koa-static-cachephần mềm trung gian được sử dụng để lưu vào bộ đệm các phản hồi của máy chủ ở phía máy khách. Cáccache-controltiêu đề được đặt theo các tùy chọn chúng tôi cung cấp trong khi khởi tạo đối tượng bộ đệm. Chúng tôi đã đặt thời gian hết hạn của phản hồi được lưu trong bộ nhớ cache này là 1 năm. Sau đây là những so sánh về yêu cầu mà chúng tôi đã gửi trước và sau khi tệp được lưu vào bộ nhớ đệm.

Trước khi tệp này được lưu vào bộ nhớ cache, mã trạng thái trả về là 200, điều này là OK. Các tiêu đề phản hồi có nhiều thông tin liên quan đến nội dung được lưu vào bộ nhớ đệm và cũng đã cung cấpETag cho nội dung.

Lần tiếp theo yêu cầu được gửi, nó sẽ được gửi cùng với thẻ ETt. Vì nội dung của chúng tôi không thay đổi trên máy chủ, ETag tương ứng của nó cũng được giữ nguyên và khách hàng được thông báo rằng bản sao mà nó có cục bộ được cập nhật với những gì máy chủ sẽ cung cấp và nên sử dụng bản sao cục bộ thay vì yêu cầu lần nữa.

Note- Để làm mất hiệu lực của bất kỳ tệp đã lưu trong bộ nhớ cache nào, bạn chỉ cần thay đổi tên tệp của nó và cập nhật tham chiếu của nó. Điều này sẽ đảm bảo rằng bạn có một tệp mới để gửi cho máy khách và máy khách không thể tải lại nó từ bộ nhớ cache.

Chúng tôi đang nhận được các yêu cầu, nhưng không lưu trữ chúng ở bất kỳ đâu. Chúng tôi cần một Cơ sở dữ liệu để lưu trữ dữ liệu. Chúng tôi sẽ sử dụng cơ sở dữ liệu NoSQL nổi tiếng có tênMongoDB. Để cài đặt và đọc về Mongo, hãy truy cập liên kết này.

Để sử dụng Mongo với Koa, chúng ta cần có API ứng dụng khách cho nút. Có nhiều lựa chọn cho chúng tôi, tuy nhiên đối với hướng dẫn này, chúng tôi sẽ bám vào mongoose . Mongoose được sử dụng chodocument modelingtrong Node cho MongoDB. Lập mô hình tài liệu có nghĩa là, chúng tôi sẽ tạoModel (giống như một class trong lập trình hướng tài liệu), và sau đó chúng tôi sẽ sản xuất documents sử dụng Mô hình này (giống như chúng tôi tạo documents of a classtrong OOP). Tất cả quá trình xử lý của chúng tôi sẽ được thực hiện trên các "tài liệu" này, sau đó cuối cùng, chúng tôi sẽ ghi các tài liệu này vào cơ sở dữ liệu của mình.

Thiết lập Mongoose

Bây giờ chúng ta đã cài đặt Mongo, chúng ta hãy cài đặt mongoose, giống như cách chúng ta đã cài đặt các gói nút khác của mình.

$ npm install --save mongoose

Trước khi bắt đầu sử dụng mongoose, chúng ta phải tạo cơ sở dữ liệu bằng cách sử dụng Mongo shell. Để tạo cơ sở dữ liệu mới, hãy mở thiết bị đầu cuối của bạn và nhập "mongo". Một trình bao Mongo sẽ bắt đầu, hãy nhập như sau.

use my_db

Một cơ sở dữ liệu mới sẽ được tạo cho bạn. Bất cứ khi nào bạn mở Mongo shell, nó sẽ mặc định là "test" db và bạn sẽ phải thay đổi cơ sở dữ liệu của mình bằng cách sử dụng lệnh tương tự như trên.

Để sử dụng mongoose, chúng tôi sẽ yêu cầu nó trong tệp app.js của chúng tôi và sau đó kết nối với dịch vụ mongod đang chạy trên mongodb: // localhost

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

app.use(_.routes());
app.listen(3000);

Bây giờ ứng dụng của chúng tôi được kết nối với cơ sở dữ liệu của chúng tôi, hãy tạo một Mô hình mới. Mô hình này sẽ hoạt động như một tập hợp trong cơ sở dữ liệu của chúng tôi. Để tạo một Mô hình mới, hãy sử dụng mã sau, trước khi xác định bất kỳ tuyến nào.

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

app.use(_.routes());
app.listen(3000);

Đoạn mã trên xác định lược đồ cho một người và được sử dụng để tạo Mô hình mongoose Person.

Lưu tài liệu

Bây giờ chúng ta sẽ tạo một biểu mẫu html mới, sẽ lấy thông tin chi tiết của một người và lưu nó vào cơ sở dữ liệu của chúng ta. Để tạo biểu mẫu, hãy tạo một tệp dạng xem mới có tên là person.pug trong thư mục dạng xem với nội dung sau.

html
   head
      title Person
   body
      form(action = "/person", method = "POST")
         div
            label(for = "name") Name: 
            input(name = "name")
         br
         div
            label(for = "age") Age: 
            input(name = "age")
         br
         div
            label(for = "nationality") Nationality: 
            input(name = "nationality")
         br
         button(type = "submit") Create new person

Đồng thời thêm một tuyến nhận mới trong index.js để hiển thị tài liệu này.

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

_.get('/person', getPerson);

function *getPerson(next){
   this.render('person');
   yield next;
}

app.use(_.routes());
app.listen(3000);

Vào localhost: 3000 / người để kiểm tra xem biểu mẫu của chúng tôi có hiển thị đúng không. Lưu ý rằng đây chỉ là giao diện người dùng, nó chưa hoạt động. Đây là cách biểu mẫu của chúng tôi trông.

Bây giờ chúng ta sẽ xác định một trình xử lý tuyến đường tại '/ person' sẽ xử lý yêu cầu này.

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

_.post('/person', createPerson);

function *createPerson(next){
   var self = this;
   var personInfo = self.request.body; //Get the parsed information
   
   if(!personInfo.name || !personInfo.age || !personInfo.nationality){
      self.render(
         'show_message', {message: "Sorry, you provided wrong info", type: "error"});
   } else {
      var newPerson = new Person({
         name: personInfo.name,
         age: personInfo.age,
         nationality: personInfo.nationality
      });
      yield newPerson.save(function(err, res) {
         if(err)
            self.render('show_message', 
               {message: "Database error", type: "error"});
         else
            self.render('show_message', 
               {message: "New person added", type: "success", person: personInfo});
      });
   }
}

app.use(_.routes());
app.listen(3000);

Trong đoạn mã trên, nếu chúng tôi nhận được bất kỳ trường trống nào hoặc không nhận được bất kỳ trường nào, chúng tôi sẽ gửi phản hồi lỗi. Tuy nhiên, nếu chúng tôi nhận được một tài liệu được định dạng tốt, thì chúng tôi tạo một tài liệu Người mới từ mô hình Người và lưu nó vào DB của chúng tôi bằng cách sử dụngnewPerson.save()chức năng. Điều này được định nghĩa trong mongoose và chấp nhận một cuộc gọi lại làm đối số. Lệnh gọi lại này có hai đối số,errorresponse. Điều này sẽ hiển thị chế độ xem show_message, vì vậy chúng tôi cũng cần tạo nó.

Để hiển thị phản hồi từ tuyến đường này, chúng tôi cũng sẽ cần tạo show_messagelượt xem. Tạo chế độ xem mới với mã sau.

html
   head
      title Person
   body
      if(type = "error")
         h3(style = "color:red") #{message}
      else
         h3 New person, name: 
            #{person.name}, age: 
            #{person.age} and nationality: 
            #{person.nationality} added!

Sau đây là phản hồi mà chúng tôi nhận được khi gửi biểu mẫu thành công (show_message.pug).

Bây giờ chúng tôi có một giao diện để tạo người!

Lấy tài liệu

Mongoose cung cấp rất nhiều chức năng để lấy tài liệu, chúng tôi sẽ tập trung vào ba trong số đó. Tất cả các hàm này cũng nhận một cuộc gọi lại làm tham số cuối cùng và cũng giống như hàm lưu, các đối số của chúng là lỗi và phản hồi.

Ba chức năng là -

Model.find (điều kiện, gọi lại)

Hàm này tìm tất cả các tài liệu khớp với các trường trong đối tượng điều kiện. Các toán tử tương tự được sử dụng trong Mongo cũng hoạt động trong mongoose. Ví dụ, điều này sẽ lấy tất cả các tài liệu từ bộ sưu tập của những người.

Person.find(function(err, response){
   console.log(response);
});

Thao tác này sẽ tìm nạp tất cả các tài liệu có tên trường là "Ayush" và tuổi là 20.

Person.find({name: "Ayush", age: 20}, 
   function(err, response){
      console.log(response);
   });

Chúng tôi cũng có thể cung cấp phép chiếu mà chúng tôi cần, tức là, các trường chúng tôi cần. Ví dụ, nếu chúng ta chỉ muốnnames của những người có nationality"tiếng Ấn Độ" , chúng tôi sử dụng -

Person.find({nationality: "Indian"}, 
   "name", function(err, response) {
      console.log(response);
   });

Model.findOne (điều kiện, gọi lại)

Hàm này luôn tìm nạp một tài liệu duy nhất, phù hợp nhất. Nó có các đối số chính xác giống như Model.find ().

Model.findById (id, callback)

Chức năng này có trong _id(được định nghĩa bởi mongo) làm đối số đầu tiên, một chuỗi chiếu tùy chọn và một lệnh gọi lại để xử lý phản hồi. Ví dụ,

Person.findById("507f1f77bcf86cd799439011", 
   function(err, response){
      console.log(response);
   });

Hãy tạo một tuyến đường để xem tất cả hồ sơ của mọi người.

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

_.get('/people', getPeople);
function *getPeople(next){
   var self = this;
   
   yield Person.find(function(err, response){
      self.body = response;
   });
}
app.use(_.routes());
app.listen(3000);

Cập nhật tài liệu

Mongoose cung cấp ba chức năng để cập nhật tài liệu.

Model.update (tình trạng, cập nhật, gọi lại)

Hàm này nhận một điều kiện và cập nhật đối tượng làm đầu vào và áp dụng các thay đổi cho tất cả các tài liệu phù hợp với các điều kiện trong bộ sưu tập. Ví dụ, đoạn mã sau sẽ cập nhật tất cả tài liệu Cá nhân để có quốc tịch "Mỹ".

Person.update({age: 25},
   {nationality: "American"}, 
   function(err, response){
      console.log(response);
   });

Model.findOneAndUpdate (tình trạng, cập nhật, gọi lại)

Nó làm chính xác những gì được nói. Tìm một tài liệu dựa trên truy vấn và cập nhật tài liệu đó theo đối số thứ hai. Nó cũng lấy một cuộc gọi lại làm đối số cuối cùng. Ví dụ,

Person.findOneAndUpdate({name: "Ayush"}, 
   {age: 40}, 
   function(err, response){
      console.log(response);
   });

Model.findByIdAndUpdate (id, cập nhật, gọi lại)

Hàm này cập nhật một tài liệu duy nhất được xác định bằng id của nó. Ví dụ,

Person.findByIdAndUpdate("507f1f77bcf86cd799439011", 
   {name: "James"}, 
   function(err, response){
      console.log(response);
   });

Hãy tạo một lộ trình để cập nhật mọi người. Đây sẽ là một tuyến PUT với id là một tham số và các chi tiết trong tải trọng.

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();
var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

_.put('/people/:id', updatePerson);

function *updatePerson() {
   var self = this;
   yield Person.findByIdAndUpdate(self.params.id, 
      {$set: {self.request.body}}, function(err, response){
      
      if(err) {
         self.body = {
            message: "Error in updating person with id " + self.params.id};
      } else {
         self.body = response;
      }
   });
}

app.use(_.routes());
app.listen(3000);

Để kiểm tra tuyến đường này, hãy nhập thông tin sau vào thiết bị đầu cuối của bạn (thay id bằng id từ những người đã tạo của bạn).

curl -X PUT --data "name = James&age = 20&nationality = American" https://localhost:3000/people/507f1f77bcf86cd799439011

Thao tác này sẽ cập nhật tài liệu được liên kết với id được cung cấp trong lộ trình với các chi tiết ở trên.

Xóa tài liệu

Chúng tôi đã bảo hiểm Create, Read và Update, bây giờ chúng ta sẽ xem cách mongoose có thể được sử dụng để Xóa tài liệu. Có ba chức năng ở đây, giống hệt như cập nhật.

Model.remove (điều kiện, [gọi lại])

Hàm này nhận một đối tượng điều kiện làm đầu vào và loại bỏ tất cả các tài liệu phù hợp với các điều kiện. Ví dụ: nếu chúng tôi cần xóa tất cả những người ở độ tuổi 20,

Person.remove({age:20});

Model.findOneAndRemove (điều kiện, [gọi lại])

Chức năng này loại bỏ một single, tài liệu có liên quan nhất theo đối tượng điều kiện. Ví dụ,

Person.findOneAndRemove({name: "Ayush"});

Model.findByIdAndRemove (id, [gọi lại])

Hàm này loại bỏ một tài liệu duy nhất được xác định bởi id của nó. Ví dụ,

Person.findByIdAndRemove("507f1f77bcf86cd799439011");

Bây giờ, hãy tạo một lộ trình để xóa mọi người khỏi cơ sở dữ liệu của chúng ta.

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

_.delete('/people/:id', deletePerson);
function *deletePerson(next){
   var self = this;
   yield Person.findByIdAndRemove(self.params.id, function(err, response){
      if(err) {
         self.body = {message: "Error in deleting record id " + self.params.id};
      } else {
         self.body = {message: "Person with id " + self.params.id + " removed."};
      }
   });
}

app.use(_.routes());
app.listen(3000);

Để kiểm tra điều này, hãy sử dụng lệnh curl sau:

curl -X DELETE https://localhost:3000/people/507f1f77bcf86cd799439011

Thao tác này sẽ xóa người có id đã cho tạo ra thông báo sau. -

{message: "Person with id 507f1f77bcf86cd799439011 removed."}

Phần này tóm tắt cách chúng ta có thể tạo các ứng dụng CRUD đơn giản bằng MongoDB, mongoose và Koa. Để khám phá thêm mongoose, hãy đọc tài liệu API.

Để tạo ứng dụng di động, ứng dụng trang đơn, sử dụng lệnh gọi AJAX và cung cấp dữ liệu cho khách hàng, bạn sẽ cần một API. Một kiểu kiến ​​trúc phổ biến về cách cấu trúc và đặt tên cho các API này và các điểm cuối được gọi làREST(Representational Transfer State). HTTP 1.1 được thiết kế để lưu ý các nguyên tắc REST. REST được giới thiệu bởiRoy Fielding vào năm 2000 trong Luận án Fielding giấy của mình.

Các phương thức và URI RESTful cung cấp cho chúng tôi hầu hết mọi thông tin cần thiết để xử lý một yêu cầu. Bảng sau đây tóm tắt cách sử dụng các động từ khác nhau và cách đặt tên các URI. Chúng tôi sẽ tạo một API phim về cuối, vì vậy hãy thảo luận về cách cấu trúc của nó.

phương pháp URI Chi tiết Chức năng
ĐƯỢC /phim An toàn, có thể truy cập được Nhận danh sách tất cả các bộ phim và thông tin chi tiết của chúng
ĐƯỢC / phim / 1234 An toàn, có thể truy cập được Nhận thông tin chi tiết của Movie id 1234
BÀI ĐĂNG /phim N / A Tạo một bộ phim mới với các chi tiết được cung cấp. Phản hồi chứa URI cho tài nguyên mới được tạo này.
ĐẶT / phim / 1234 Idempotent Sửa đổi id phim 1234 (tạo một id nếu nó chưa tồn tại). Phản hồi chứa URI cho tài nguyên mới được tạo này.
XÓA BỎ / phim / 1234 Idempotent Id phim 1234 nên bị xóa, nếu nó tồn tại. Phản hồi phải chứa trạng thái của yêu cầu.
XÓA hoặc ĐẶT /phim không hợp lệ Nên không hợp lệ. DELETE và PUT phải chỉ định tài nguyên nào chúng đang làm việc.

Bây giờ chúng ta hãy tạo API này trong Koa. Chúng tôi sẽ sử dụng JSON làm định dạng dữ liệu truyền tải vì nó dễ làm việc với JavaScript và có vô số lợi ích khác. Thay thế tệp index.js của bạn bằng tệp sau:

INDEX.JS

var koa = require('koa');
var router = require('koa-router');
var bodyParser = require('koa-body');

var app = koa();

//Set up body parsing middleware
app.use(bodyParser({
   formidable:{uploadDir: './uploads'},
   multipart: true,
   urlencoded: true
}));

//Require the Router we defined in movies.js
var movies = require('./movies.js');

//Use the Router on the sub route /movies
app.use(movies.routes());

app.listen(3000);

Bây giờ chúng ta đã thiết lập xong ứng dụng của mình, hãy tập trung vào việc tạo API. Đầu tiên hãy thiết lập tệp phim.js. Chúng tôi không sử dụng cơ sở dữ liệu để lưu trữ phim mà đang lưu trữ chúng trong bộ nhớ, vì vậy mỗi khi máy chủ khởi động lại, các phim do chúng tôi thêm vào sẽ biến mất. Điều này có thể dễ dàng được bắt chước bằng cách sử dụng cơ sở dữ liệu hoặc tệp (sử dụng mô-đun fs nút).

Nhập koa-router, tạo một Router và xuất nó bằng module.exports.

var Router = require('koa-router');
var router = Router({
  prefix: '/movies'
});  //Prefixed all routes with /movies

var movies = [
   {id: 101, name: "Fight Club", year: 1999, rating: 8.1},
   {id: 102, name: "Inception", year: 2010, rating: 8.7},
   {id: 103, name: "The Dark Knight", year: 2008, rating: 9},
   {id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];

//Routes will go here

module.exports = router;

Nhận các tuyến đường

Xác định lộ trình GET để tải tất cả các bộ phim.

router.get('/', sendMovies);
function *sendMovies(next){
   this.body = movies;
   yield next;
}

Đó là nó. Để kiểm tra xem điều này có hoạt động tốt hay không, hãy chạy ứng dụng của bạn, sau đó mở thiết bị đầu cuối của bạn và nhập -

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET localhost:3000/movies

Bạn sẽ nhận được phản hồi sau -

[{"id":101,"name":"Fight 
Club","year":1999,"rating":8.1},{"id":102,"name":"Inception","year":2010,"rating":8.7},
{"id":103,"name":"The Dark Knight","year":2008,"rating":9},{"id":104,"name":"12 Angry 
Men","year":1957,"rating":8.9}]

Chúng tôi có một lộ trình để lấy tất cả các bộ phim. Bây giờ chúng ta hãy tạo một tuyến đường để lấy một bộ phim cụ thể theo id của nó.

router.get('/:id([0-9]{3,})', sendMovieWithId);

function *sendMovieWithId(next){
   var ctx = this;
   var currMovie = movies.filter(function(movie){
      if(movie.id == ctx.params.id){
         return true;
      }
   });
   if(currMovie.length == 1){
      this.body = currMovie[0];
   } else {
      this.response.status = 404;//Set status to 404 as movie was not found
      this.body = {message: "Not Found"};
   }
   yield next;
}

Điều này sẽ giúp chúng tôi nhận được các bộ phim theo id mà chúng tôi cung cấp. Để kiểm tra điều này, hãy sử dụng lệnh sau trong thiết bị đầu cuối của bạn.

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET localhost:3000/movies/101

Bạn sẽ nhận được phản hồi là -

{"id":101,"name":"Fight Club","year":1999,"rating":8.1}

Nếu bạn truy cập một tuyến đường không hợp lệ, nó sẽ tạo ra lỗi không thể GET, trong khi nếu bạn truy cập một tuyến đường hợp lệ có id không tồn tại, nó sẽ tạo ra lỗi 404.

Chúng tôi đã hoàn thành với các tuyến đường GET. Bây giờ, chúng ta hãy chuyển sang tuyến đường POST.

ĐĂNG lộ trình

Sử dụng tuyến sau để xử lý dữ liệu ĐÃ ĐĂNG.

router.post('/', addNewMovie);

function *addNewMovie(next){
   //Check if all fields are provided and are valid:
   if(!this.request.body.name || 
      !this.request.body.year.toString().match(/^[0-9]{4}$/g) || 
      !this.request.body.rating.toString().match(/^[0-9]\.[0-9]$/g)){
      
      this.response.status = 400;
      this.body = {message: "Bad Request"};
   } else {
      var newId = movies[movies.length-1].id+1;
      
      movies.push({
         id: newId,
         name: this.request.body.name,
         year: this.request.body.year,
         rating: this.request.body.rating
      });
      this.body = {message: "New movie created.", location: "/movies/" + newId};
   }
   yield next;
}

Thao tác này sẽ tạo một bộ phim mới và lưu trữ nó trong biến phim. Để kiểm tra lộ trình này, hãy nhập thông tin sau vào thiết bị đầu cuối của bạn:

curl -X POST --data "name = Toy%20story&year = 1995&rating = 8.5" 
https://localhost:3000/movies

Bạn sẽ nhận được phản hồi sau -

{"message":"New movie created.","location":"/movies/105"}

Để kiểm tra xem điều này đã được thêm vào đối tượng phim chưa, hãy chạy lại yêu cầu nhận / phim / 105. Bạn sẽ nhận được phản hồi sau -

{"id":105,"name":"Toy story","year":"1995","rating":"8.5"}

Hãy chuyển sang tạo các tuyến PUT và DELETE.

Tuyến đường PUT

Tuyến PUT gần giống như tuyến POST. Chúng tôi sẽ chỉ định id cho đối tượng sẽ được cập nhật / tạo. Tạo tuyến đường theo cách sau:

router.put('/:id', updateMovieWithId);

function *updateMovieWithId(next){
   //Check if all fields are provided and are valid:
   if(!this.request.body.name || 
      !this.request.body.year.toString().match(/^[0-9]{4}$/g) || 
      !this.request.body.rating.toString().match(/^[0-9]\.[0-9]$/g) ||
      !this.params.id.toString().match(/^[0-9]{3,}$/g)){
      
      this.response.status = 400;
      this.body = {message: "Bad Request"};
   } else {
      //Gets us the index of movie with given id.
      var updateIndex = movies.map(function(movie){
         return movie.id;
      }).indexOf(parseInt(this.params.id));
      
      if(updateIndex === -1){
         //Movie not found, create new movies.push({
            id: this.params.id,
            name: this.request.body.name,
            year: this.request.body.year,
            rating: this.request.body.rating
         });
         this.body = {message: "New movie created.", location: "/movies/" + this.params.id};    
      } else {
         //Update existing movie
         movies[updateIndex] = {
            id: this.params.id,
            name: this.request.body.name,
            year: this.request.body.year,
            rating: this.request.body.rating
         };
         this.body = {message: "Movie id " + this.params.id + " updated.", location: "/movies/" + this.params.id};
      }
   }
}

Tuyến đường này sẽ thực hiện chức năng mà chúng tôi đã chỉ định trong bảng trên. Nó sẽ cập nhật đối tượng với các chi tiết mới nếu nó tồn tại. Nếu nó không tồn tại, nó sẽ tạo một đối tượng mới. Để kiểm tra tuyến đường này, hãy sử dụng lệnh curl sau đây. Điều này sẽ cập nhật một bộ phim hiện có. Để tạo Phim mới, chỉ cần thay đổi id thành id không tồn tại.

curl -X PUT --data "name = Toy%20story&year = 1995&rating = 8.5" 
https://localhost:3000/movies/101

Phản ứng

{"message":"Movie id 101 updated.","location":"/movies/101"}

XÓA tuyến đường

Sử dụng mã sau để tạo một lộ trình xóa.

router.delete('/:id', deleteMovieWithId);

function *deleteMovieWithId(next){
   var removeIndex = movies.map(function(movie){
      return movie.id;
   }).indexOf(this.params.id); //Gets us the index of movie with given id.
   
   if(removeIndex === -1){
      this.body = {message: "Not found"};
   } else {
      movies.splice(removeIndex, 1);
      this.body = {message: "Movie id " + this.params.id + " removed."};
   }
}

Kiểm tra tuyến đường giống như cách chúng tôi đã làm cho những tuyến đường khác. Khi xóa thành công (ví dụ: id 105), bạn sẽ nhận được -

{message: "Movie id 105 removed."}

Cuối cùng, tệp phim.js của chúng tôi trông giống như:

var Router = require('koa-router');
var router = Router({
   prefix: '/movies'
});  //Prefixed all routes with /movies
var movies = [
   {id: 101, name: "Fight Club", year: 1999, rating: 8.1},
   {id: 102, name: "Inception", year: 2010, rating: 8.7},
   {id: 103, name: "The Dark Knight", year: 2008, rating: 9},
   {id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];

//Routes will go here
router.get('/', sendMovies);
router.get('/:id([0-9]{3,})', sendMovieWithId);
router.post('/', addNewMovie);
router.put('/:id', updateMovieWithId);
router.delete('/:id', deleteMovieWithId);

function *deleteMovieWithId(next){
   var removeIndex = movies.map(function(movie){
      return movie.id;
   }).indexOf(this.params.id); //Gets us the index of movie with given id.
   
   if(removeIndex === -1){
      this.body = {message: "Not found"};
   } else {
      movies.splice(removeIndex, 1);
      this.body = {message: "Movie id " + this.params.id + " removed."};
   }
}

function *updateMovieWithId(next) {
   //Check if all fields are provided and are valid:
   if(!this.request.body.name ||
      !this.request.body.year.toString().match(/^[0-9]{4}$/g) ||
      !this.request.body.rating.toString().match(/^[0-9]\.[0-9]$/g) ||
      !this.params.id.toString().match(/^[0-9]{3,}$/g)){
      
      this.response.status = 400;
      this.body = {message: "Bad Request"};
   } else {
      //Gets us the index of movie with given id.
      var updateIndex = movies.map(function(movie){
         return movie.id;
      }).indexOf(parseInt(this.params.id));
      
      if(updateIndex === -1){
         //Movie not found, create new
         movies.push({
            id: this.params.id,
            name: this.request.body.name,
            year: this.request.body.year,
            rating: this.request.body.rating
         });
         this.body = {message: "New movie created.", location: "/movies/" + this.params.id};
      } else {
         //Update existing movie
            movies[updateIndex] = {
            id: this.params.id,
            name: this.request.body.name,
            year: this.request.body.year,
            rating: this.request.body.rating
         };
         this.body = {message: "Movie id " + this.params.id + " updated.", 
            location: "/movies/" + this.params.id};
      }
   }
}

function *addNewMovie(next){
   //Check if all fields are provided and are valid:
   if(!this.request.body.name ||
      !this.request.body.year.toString().match(/^[0-9]{4}$/g) ||
      !this.request.body.rating.toString().match(/^[0-9]\.[0-9]$/g)){
      
      this.response.status = 400;
      this.body = {message: "Bad Request"};
   } else {
      var newId = movies[movies.length-1].id+1;
      
      movies.push({
         id: newId,
         name: this.request.body.name,
         year: this.request.body.year,
         rating: this.request.body.rating
      });
      this.body = {message: "New movie created.", location: "/movies/" + newId};
   }
   yield next;
}
function *sendMovies(next){
   this.body = movies;
   yield next;
}
function *sendMovieWithId(next){
   var ctx = this
   
   var currMovie = movies.filter(function(movie){
      if(movie.id == ctx.params.id){
         return true;
      }
   });
   if(currMovie.length == 1){
      this.body = currMovie[0];
   } else {
      this.response.status = 404;//Set status to 404 as movie was not found
      this.body = {message: "Not Found"};
   }
   yield next;
}
module.exports = router;

Điều này hoàn thành API REST của chúng tôi. Giờ đây, bạn có thể tạo các ứng dụng phức tạp hơn nhiều bằng cách sử dụng phong cách kiến ​​trúc đơn giản này và Koa.

Ghi nhật ký khá hữu ích khi tạo các ứng dụng web vì chúng cho chúng tôi biết chính xác mọi thứ đã sai ở đâu. Chúng tôi cũng nhận được bối cảnh cho những điều đã xảy ra và có thể đưa ra các giải pháp khả thi cho vấn đề tương tự.

Để kích hoạt đăng nhập Koa, chúng tôi cần phần mềm trung gian, koa-logger. Cài đặt nó bằng lệnh sau.

$ npm install --save-dev koa-logger

Bây giờ trong ứng dụng của bạn, hãy thêm mã sau để kích hoạt ghi nhật ký.

var logger = require('koa-logger')
var koa = require('koa')

var app = koa()
app.use(logger())

app.use(function*(){
   this.body = "Hello Logger";
})

app.listen(3000)

Chạy máy chủ này và truy cập bất kỳ tuyến đường nào trên máy chủ. Bạn sẽ thấy các bản ghi như -

Bây giờ nếu bạn gặp lỗi trên một tuyến đường hoặc yêu cầu cụ thể, các nhật ký này sẽ giúp bạn tìm ra lỗi trong mỗi chúng.

Giàn giáo cho phép chúng tôi dễ dàng tạo ra một skeleton for a web application. Chúng tôi đã tạo thủ công thư mục công cộng của mình, thêm phần mềm trung gian, tạo các tệp đường dẫn riêng, v.v. Một công cụ giàn giáo thiết lập tất cả những thứ này cho chúng tôi để chúng tôi có thể trực tiếp bắt đầu xây dựng ứng dụng của mình.

Bộ giàn giáo chúng tôi sẽ sử dụng có tên là Yeoman. Nó là một công cụ giàn giáo được xây dựng cho Node.js nhưng cũng có bộ tạo cho một số khung công tác khác (chẳng hạn như flask, đường ray, django, v.v.). Để cài đặt yeoman, hãy nhập lệnh sau vào thiết bị đầu cuối của bạn.

$ npm install -g yeoman

Yeoman sử dụng máy phát điện để tạo ra các ứng dụng. Để kiểm tra các máy phát điện có sẵn trên npm để sử dụng với yeoman, hãy truy cập tại đây . Đối với mục đích của hướng dẫn này, chúng tôi sẽ sử dụng 'máy phát điện-koa'. Để cài đặt trình tạo này, hãy nhập lệnh sau vào thiết bị đầu cuối của bạn.

$ npm install -g generator-koa

Để sử dụng trình tạo này, hãy nhập -

yo koa

Sau đó, nó sẽ tạo cấu trúc thư mục và sẽ tạo các tệp sau cho bạn. Nó cũng sẽ cài đặt các mô-đun npm và các thành phần bower cần thiết cho bạn.

create package.json
create test/routeSpec.js
create views/layout.html
create views/list.html
create public/styles/main.css
create public/scripts/.gitkeep
create controllers/messages.js
create app.js
create .editorconfig
create .jshintrc

I'm all done. Running npm install & bower install for you to install 
the required dependencies. 
If this fails, try running the command yourself.

Máy phát điện này tạo ra một cấu trúc rất đơn giản cho chúng ta.

.
├── controllers
│   └── messages.js
├── public
|   ├── scripts
|   └── styles
|       └── main.css    
├── test
|   └── routeSpec.js
├── views
|   ├── layout.html
|   └── list.html
├── .editorconfig
├── .jshintrc
├── app.js
└── package.json

Khám phá nhiều máy phát điện có sẵn cho Koa và chọn loại phù hợp với bạn. Các bước làm việc với tất cả các máy phát điện đều giống nhau. Bạn sẽ cần cài đặt một trình tạo, chạy nó bằng yeoman, nó sẽ hỏi bạn một số câu hỏi và sau đó tạo khung cho ứng dụng của bạn dựa trên câu trả lời của bạn.

Sau đây là danh sách các tài nguyên chúng tôi đã sử dụng trong khi phát triển hướng dẫn này:

  • Koajs.com

  • Koajs - Ví dụ Danh sách các ví dụ do cộng đồng tạo

  • Danh sách các phần mềm trung gian chính thức và bên thứ 3 .

  • API CRUD sử dụng koa.js - Đoạn phim ngắn hướng dẫn cách tạo API CRUD trong Koa.js

  • Koa.js Quickstart screencast

  • Giới thiệu về Koa.js và máy phát điện