Koa.js - คู่มือฉบับย่อ

เฟรมเวิร์กแอปพลิเคชันบนเว็บช่วยให้คุณมี API ง่ายๆในการสร้างเว็บไซต์เว็บแอปและแบ็กเอนด์ คุณไม่จำเป็นต้องกังวลเกี่ยวกับโปรโตคอลระดับต่ำกระบวนการ ฯลฯ

Koa คืออะไร?

Koa มีอินเทอร์เฟซขั้นต่ำในการสร้างแอพ เป็นเฟรมเวิร์กที่เล็กมาก (600 LoC) ซึ่งมีเครื่องมือที่จำเป็นในการสร้างแอพและค่อนข้างยืดหยุ่น มีโมดูลมากมายบน npm สำหรับ Koa ซึ่งสามารถเสียบเข้ากับมันได้โดยตรง Koa ถือได้ว่าเป็นแกนหลักของ express.js โดยไม่มีเสียงระฆังและเสียงนกหวีด

ทำไมต้อง Koa?

Koa มีขนาดเล็ก (600 LoC) และเป็นชั้นนามธรรมที่บางมากเหนือโหนดเพื่อสร้างแอปฝั่งเซิร์ฟเวอร์ สามารถเสียบได้อย่างสมบูรณ์และมีชุมชนขนาดใหญ่ นอกจากนี้ยังช่วยให้เราสามารถขยาย Koa ได้อย่างง่ายดายและใช้งานได้ตามความต้องการของเรา สร้างขึ้นโดยใช้เทคโนโลยี Bleeding Edge (ES6) ซึ่งให้ความได้เปรียบเหนือเฟรมเวิร์กรุ่นเก่าเช่น express

ปั๊ก

Pug (ก่อนหน้านี้รู้จักกันในชื่อ Jade) เป็นภาษาสั้น ๆ สำหรับการเขียนเทมเพลต HTML

  • สร้าง HTML
  • รองรับรหัสแบบไดนามิก
  • รองรับการใช้ซ้ำ (DRY)

เป็นภาษาแม่แบบที่นิยมใช้กับ Koa

MongoDB และพังพอน

MongoDB เป็นฐานข้อมูลเอกสารแบบโอเพนซอร์สที่ออกแบบมาเพื่อความสะดวกในการพัฒนาและปรับขนาด เราจะใช้ฐานข้อมูลนี้เพื่อจัดเก็บข้อมูล

Mongoose เป็นไคลเอนต์ API สำหรับ node.js ซึ่งทำให้ง่ายต่อการเข้าถึงฐานข้อมูลของเราจากแอปพลิเคชัน Koa ของเรา

ในการเริ่มต้นการพัฒนาโดยใช้ Koa framework คุณต้องติดตั้ง Node และ npm (node ​​package manager) หากคุณยังไม่มีให้ตรงไปที่การตั้งค่าโหนดเพื่อติดตั้งโหนดในระบบภายในของคุณ ตรวจสอบว่าโหนดและ npm ได้รับการติดตั้งโดยรันคำสั่งต่อไปนี้ในเทอร์มินัลของคุณ

$ node --version
$ npm --version

คุณควรได้รับผลลัพธ์ที่คล้ายกับ -

v5.0.0
3.5.2

โปรดตรวจสอบให้แน่ใจว่าเวอร์ชันโหนดของคุณสูงกว่า 6.5.0 ตอนนี้เราได้ตั้งค่า Node และ npm แล้วให้เราเข้าใจว่า npm คืออะไรและจะใช้อย่างไร

Node Package Manager (npm)

npm เป็นตัวจัดการแพ็คเกจสำหรับโหนด npm Registry เป็นชุดสาธารณะของแพ็กเกจรหัสโอเพนซอร์สสำหรับ Node.js เว็บแอปฟรอนต์เอนด์แอปบนอุปกรณ์เคลื่อนที่โรบ็อตเราเตอร์และความต้องการอื่น ๆ อีกมากมายของชุมชน JavaScript npm ช่วยให้เราเข้าถึงแพ็คเกจเหล่านี้ทั้งหมดและติดตั้งในเครื่อง คุณสามารถเรียกดูผ่านรายการของแพคเกจที่มีอยู่บน NPM ที่npmJS

วิธีใช้ npm

มีสองวิธีในการติดตั้งแพ็คเกจโดยใช้ npm - ทั่วโลกและในเครื่อง

Globally- วิธีนี้มักใช้เพื่อติดตั้งเครื่องมือพัฒนาและแพ็คเกจที่ใช้ CLI ในการติดตั้งแพ็คเกจทั่วโลกให้ใช้คำสั่งต่อไปนี้

$ npm install -g <package-name>

Locally- วิธีนี้มักใช้ในการติดตั้งเฟรมเวิร์กและไลบรารี แพคเกจที่ติดตั้งภายในสามารถใช้ได้เฉพาะภายในไดเร็กทอรีที่ติดตั้ง ในการติดตั้งแพ็กเกจภายในเครื่องให้ใช้คำสั่งเดียวกันกับด้านบนโดยไม่มี -g ธง.

$ npm install <package-name>

เมื่อใดก็ตามที่เราสร้างโปรเจ็กต์โดยใช้ npm เราจำเป็นต้องจัดเตรียมไฟล์ package.json ซึ่งมีรายละเอียดทั้งหมดเกี่ยวกับโปรเจ็กต์ของเรา npm ทำให้เราตั้งค่าไฟล์นี้ได้ง่าย ให้เราตั้งค่าโครงการพัฒนาของเรา

Step 1 - เปิดเครื่องเทอร์มินัล / cmd ของคุณสร้างโฟลเดอร์ใหม่ชื่อ hello-world และ cd ลงในนั้น -

Step 2 - ตอนนี้ในการสร้างไฟล์ package.json โดยใช้ npm ให้ใช้สิ่งต่อไปนี้

npm init

จะขอข้อมูลต่อไปนี้จากคุณ -

เพียงกด Enter และป้อนชื่อของคุณในฟิลด์ "ชื่อผู้แต่ง"

Step 3- ตอนนี้เราได้ตั้งค่าไฟล์ package.json แล้วเราจะติดตั้ง Koa ในการติดตั้ง Koa และเพิ่มในไฟล์ package.json ของเราให้ใช้คำสั่งต่อไปนี้

$ npm install --save koa

เพื่อยืนยันว่า Koa ติดตั้งอย่างถูกต้องให้รันคำสั่งต่อไปนี้

$ ls node_modules #(dir node_modules for windows)

Tip - --save ธงสามารถถูกแทนที่ด้วย -Sธง. แฟล็กนี้ช่วยให้มั่นใจได้ว่า Koa ถูกเพิ่มเป็นการอ้างอิงกับไฟล์ package.json ของเรา สิ่งนี้มีข้อได้เปรียบในครั้งต่อไปที่เราต้องติดตั้งการอ้างอิงทั้งหมดของโครงการของเราเราเพียงแค่เรียกใช้คำสั่ง npm install และจะพบการอ้างอิงในไฟล์นี้และติดตั้งให้เรา

นี่คือทั้งหมดที่เราต้องเริ่มพัฒนาโดยใช้กรอบ Koa เพื่อให้กระบวนการพัฒนาของเราง่ายขึ้นมากเราจะติดตั้งเครื่องมือจาก npm, nodemon เครื่องมือนี้ทำหน้าที่อะไรคือรีสตาร์ทเซิร์ฟเวอร์ของเราทันทีที่เราทำการเปลี่ยนแปลงในไฟล์ใด ๆ ของเรามิฉะนั้นเราต้องรีสตาร์ทเซิร์ฟเวอร์ด้วยตนเองหลังจากแก้ไขไฟล์แต่ละครั้ง ในการติดตั้ง nodemon ให้ใช้คำสั่งต่อไปนี้

$ npm install -g nodemon

ตอนนี้เราทุกคนพร้อมที่จะดำดิ่งสู่ Koa แล้ว!

เมื่อเราตั้งค่าการพัฒนาเรียบร้อยแล้วก็ถึงเวลาเริ่มพัฒนาแอพแรกของเราโดยใช้ Koa สร้างไฟล์ใหม่ชื่อapp.js แล้วพิมพ์ข้อความต่อไปนี้

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')
});

บันทึกไฟล์ไปที่เทอร์มินัลของคุณแล้วพิมพ์

$ nodemon app.js

สิ่งนี้จะเริ่มต้นเซิร์ฟเวอร์ ในการทดสอบแอปนี้ให้เปิดเบราว์เซอร์ของคุณแล้วไปที่https://localhost:3000 และคุณควรได้รับข้อความต่อไปนี้

แอพนี้ทำงานอย่างไร

บรรทัดแรกนำเข้า Koa ในไฟล์ของเรา เราสามารถเข้าถึง API ผ่านตัวแปร Koa เราใช้เพื่อสร้างแอปพลิเคชันและกำหนดให้กับแอป var

app.use(function)- ฟังก์ชั่นนี้เป็นมิดเดิลแวร์ซึ่งจะถูกเรียกเมื่อใดก็ตามที่เซิร์ฟเวอร์ของเราได้รับคำขอ เราจะเรียนรู้เพิ่มเติมเกี่ยวกับมิดเดิลแวร์ในบทต่อ ๆ ไป ฟังก์ชันเรียกกลับเป็นตัวสร้างซึ่งเราจะเห็นในบทถัดไป บริบทของเครื่องกำเนิดไฟฟ้านี้เรียกว่าบริบทใน Koa บริบทนี้ใช้เพื่อเข้าถึงและแก้ไขอ็อบเจ็กต์การร้องขอและการตอบกลับ เรากำลังกำหนดเนื้อหาของการตอบสนองนี้ให้เป็นHello world!.

app.listen(port, function)- ฟังก์ชั่นนี้ผูกและรับฟังการเชื่อมต่อบนพอร์ตที่ระบุ พอร์ตเป็นพารามิเตอร์ที่จำเป็นเท่านั้นที่นี่ ฟังก์ชันเรียกกลับจะทำงานหากแอปทำงานสำเร็จ

หนึ่งในคุณสมบัติใหม่ที่น่าตื่นเต้นที่สุดของ JavaScript ES6 คือฟังก์ชันใหม่ที่เรียกว่าเครื่องกำเนิดไฟฟ้า ก่อนตัวกำเนิดสคริปต์ทั้งหมดจะถูกใช้เพื่อดำเนินการตามลำดับจากบนลงล่างโดยไม่มีวิธีง่ายๆในการหยุดการเรียกใช้โค้ดและเริ่มต้นใหม่ด้วยสแต็กเดียวกันในภายหลัง เครื่องกำเนิดไฟฟ้าเป็นฟังก์ชันที่สามารถออกและป้อนใหม่ได้ในภายหลัง บริบทของพวกเขา (การเชื่อมโยงตัวแปร) จะถูกบันทึกข้ามทางเข้าใหม่

เครื่องกำเนิดไฟฟ้าช่วยให้เราสามารถหยุดการเรียกใช้โค้ดได้ ดังนั้นเรามาดูเครื่องกำเนิดไฟฟ้าอย่างง่าย

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

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

เมื่อรันโค้ดด้านบนผลลัพธ์ต่อไปนี้จะเป็น

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

มาดูข้างในโค้ดด้านบน ก่อนอื่นเราสร้างเครื่องกำเนิดไฟฟ้าที่เรียกว่าgenerator_func(). เราได้สร้างอินสแตนซ์ของฟังก์ชันที่ดูแปลก ๆ นี้และกำหนดให้itr. จากนั้นเราก็เริ่มโทรnext() บนตัวแปร itr นี้

การเรียก next () จะเริ่มต้นเครื่องกำเนิดไฟฟ้าและทำงานจนกว่าจะได้ผลตอบแทน จากนั้นส่งคืนวัตถุด้วยค่าและเสร็จสิ้นโดยที่ค่ามีค่านิพจน์ สำนวนนี้สามารถเป็นอะไรก็ได้ ณ จุดนี้จะหยุดการดำเนินการชั่วคราว อีกครั้งเมื่อเราเรียกใช้ฟังก์ชันนี้ (ถัดไป) เครื่องกำเนิดไฟฟ้าจะดำเนินการต่อจากจุดผลตอบแทนสุดท้ายโดยที่สถานะของฟังก์ชันจะเหมือนเดิมในเวลาที่หยุดชั่วคราวจนถึงจุดผลตอบแทนถัดไป สิ่งนี้ทำได้จนกว่าจะไม่มีคะแนนผลตอบแทนอีกต่อไปในรหัส

เครื่องปั่นไฟใน Koa

เหตุใดเราจึงพูดถึงเครื่องกำเนิดไฟฟ้าในบทช่วยสอนนี้ อย่างที่คุณจำได้จากโปรแกรม hello world เราใช้ไฟล์function* ()สัญกรณ์เพื่อส่งการโทรกลับไปยัง app.use () Koa เป็นอ็อบเจ็กต์ที่มีอาร์เรย์ของฟังก์ชันตัวสร้างมิดเดิลแวร์ซึ่งทั้งหมดนี้ประกอบและดำเนินการในลักษณะสแต็กตามคำขอแต่ละรายการ Koa ยังดำเนินการล่องตามด้วยการควบคุมขั้นตอนต้นน้ำ

ลองดูตัวอย่างต่อไปนี้เพื่อทำความเข้าใจในทางที่ดีขึ้น

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);

เมื่อเรียกใช้โค้ดด้านบนและไปที่ https://localhost:3000/ เราได้รับผลลัพธ์ต่อไปนี้บนคอนโซลของเรา

1
3
5
6
4
2

นี่คือวิธีที่ Koa ใช้เครื่องกำเนิดไฟฟ้า ช่วยให้เราสร้างมิดเดิลแวร์ขนาดกะทัดรัดโดยใช้คุณสมบัตินี้และเขียนโค้ดสำหรับฟังก์ชันทั้งอัพสตรีมและดาวน์สตรีมซึ่งช่วยให้เราประหยัดจากการโทรกลับ

เว็บเฟรมเวิร์กจัดเตรียมทรัพยากรเช่นเพจ HTML สคริปต์รูปภาพ ฯลฯ ในเส้นทางต่างๆ Koa ไม่รองรับเส้นทางในโมดูลหลัก เราจำเป็นต้องใช้โมดูล Koa-router เพื่อสร้างเส้นทางใน Koa ได้อย่างง่ายดาย ติดตั้งโมดูลนี้โดยใช้คำสั่งต่อไปนี้

npm install --save koa-router

ตอนนี้เราได้ติดตั้ง Koa-router แล้วมาดูตัวอย่างเส้นทาง 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);

หากเราเรียกใช้แอปพลิเคชันของเราและไปที่ localhost: 3000 / hello เซิร์ฟเวอร์จะได้รับคำขอที่ route "/ hello" แอป Koa ของเราเรียกใช้ฟังก์ชันเรียกกลับที่แนบมากับเส้นทางนี้และส่ง "Hello World!" เป็นการตอบสนอง

นอกจากนี้เรายังสามารถมีหลายวิธีที่แตกต่างกันในเส้นทางเดียวกัน ตัวอย่างเช่น,

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);

ในการทดสอบคำขอนี้ให้เปิดเทอร์มินัลของคุณและใช้ cURL เพื่อดำเนินการตามคำขอต่อไปนี้

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

วิธีพิเศษ allจัดเตรียมโดย express เพื่อจัดการเมธอด http ทุกประเภทในเส้นทางเฉพาะโดยใช้ฟังก์ชันเดียวกัน หากต้องการใช้วิธีนี้ให้ลองทำดังต่อไปนี้ -

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

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

เราสามารถกำหนดเส้นทางได้แล้ว เป็นแบบคงที่หรือคงที่ ในการใช้เส้นทางแบบไดนามิกเราจำเป็นต้องระบุเส้นทางประเภทต่างๆ การใช้เส้นทางแบบไดนามิกช่วยให้เราสามารถส่งผ่านพารามิเตอร์และประมวลผลตามพวกเขาได้ ต่อไปนี้เป็นตัวอย่างของเส้นทางแบบไดนามิก

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);

เพื่อทดสอบสิ่งนี้ไปที่ https://localhost:3000/123. คุณจะได้รับคำตอบดังต่อไปนี้

คุณสามารถแทนที่ "123" ใน URL ด้วยสิ่งอื่นและจะแสดงในการตอบกลับ ต่อไปนี้เป็นตัวอย่างที่ซับซ้อนข้างต้น

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);

เพื่อทดสอบสิ่งนี้ไปที่ https://localhost:3000/things/tutorialspoint/12345.

คุณสามารถใช้ไฟล์ this.paramsเพื่อเข้าถึงพารามิเตอร์ทั้งหมดที่คุณส่งผ่านใน URL โปรดทราบว่าสองรายการข้างต้นมีเส้นทางที่แตกต่างกัน พวกเขาจะไม่ทับซ้อนกัน นอกจากนี้หากคุณต้องการรันโค้ดเมื่อคุณได้รับ '/ things' คุณต้องกำหนดแยกต่างหาก

รูปแบบที่ตรงกันเส้นทาง

คุณยังสามารถใช้ regex เพื่อ จำกัด การจับคู่พารามิเตอร์ URL สมมติว่าคุณต้องให้รหัสเป็นตัวเลขยาวห้าหลัก คุณสามารถใช้นิยามเส้นทางต่อไปนี้

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);

โปรดทราบว่าสิ่งนี้จะ onlyตรงกับคำขอที่มีรหัสยาว 5 หลัก คุณสามารถใช้ regexes ที่ซับซ้อนมากขึ้นเพื่อจับคู่ / ตรวจสอบเส้นทางของคุณ หากเส้นทางของคุณไม่ตรงกับคำขอคุณจะได้รับข้อความ "ไม่พบ" เป็นการตอบกลับ

ตัวอย่างเช่นหากเรากำหนดเส้นทางเดียวกันกับด้านบนเมื่อขอด้วย URL ที่ถูกต้องเราจะได้รับ -

วิธี HTTP ถูกจัดเตรียมไว้ในคำร้องขอและระบุการดำเนินการที่ไคลเอ็นต์ร้องขอ ตารางต่อไปนี้สรุปวิธีการ HTTP ที่ใช้กันทั่วไป

ซีเนียร์ วิธีการและคำอธิบาย
1

GET

เมธอด GET ร้องขอการเป็นตัวแทนของทรัพยากรที่ระบุ คำขอโดยใช้ GET ควรดึงข้อมูลเท่านั้นและไม่ควรมีผลกระทบอื่น ๆ

2

POST

เมธอด POST ร้องขอให้เซิร์ฟเวอร์ยอมรับข้อมูลที่อยู่ในคำร้องขอเป็นอ็อบเจ็กต์ / เอนทิตีใหม่ของทรัพยากรที่ระบุโดย URI

3

PUT

เมธอด PUT ร้องขอให้เซิร์ฟเวอร์ยอมรับข้อมูลที่อยู่ในคำร้องขอเป็นการแก้ไขอ็อบเจ็กต์ที่มีอยู่ที่ระบุโดย URI หากไม่มีอยู่วิธีการ PUT ควรสร้างขึ้นมาใหม่

4

DELETE

เมธอด DELETE ร้องขอให้เซิร์ฟเวอร์ลบทรัพยากรที่ระบุ

นี่คือวิธีการ HTTP ที่พบบ่อยที่สุด หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับพวกเขาตรงไปที่https://www.tutorialspoint.com/http/http_methods.htm.

ออบเจ็กต์ Koa Request เป็นสิ่งที่เป็นนามธรรมที่อยู่ด้านบนของอ็อบเจ็กต์คำขอวานิลลาของโหนดซึ่งมีฟังก์ชันเพิ่มเติมที่เป็นประโยชน์สำหรับการพัฒนาเซิร์ฟเวอร์ HTTP ในชีวิตประจำวัน อ็อบเจ็กต์คำขอ Koa ถูกฝังอยู่ในอ็อบเจ็กต์บริบทthis. มาออกจากระบบวัตถุคำขอเมื่อใดก็ตามที่เราได้รับคำขอ

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);

เมื่อคุณเรียกใช้รหัสนี้และไปที่ https://localhost:3000/helloจากนั้นคุณจะได้รับคำตอบดังต่อไปนี้

บนคอนโซลของคุณคุณจะได้รับวัตถุคำขอออกจากระบบ

{ 
   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' 
   }
}

เราสามารถเข้าถึงคุณสมบัติที่มีประโยชน์มากมายของคำขอโดยใช้วัตถุนี้ ให้เราดูตัวอย่างบางส่วน

request.header

จัดเตรียมส่วนหัวของคำขอทั้งหมด

ขอวิธี

ให้วิธีการร้องขอ (GET, POST ฯลฯ )

request.href

ระบุ URL คำขอแบบเต็ม

request.path

จัดเตรียมเส้นทางของคำขอ ไม่มีสตริงการสืบค้นและ URL พื้นฐาน

request.query

ให้สตริงแบบสอบถามที่แยกวิเคราะห์ ตัวอย่างเช่นหากเราบันทึกสิ่งนี้ตามคำขอเช่นhttps://localhost:3000/hello/?name=Ayush&age=20&country=Indiaจากนั้นเราจะได้รับวัตถุต่อไปนี้

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

request.accepts (ประเภท)

ฟังก์ชันนี้ส่งคืนจริงหรือเท็จโดยขึ้นอยู่กับว่ารีซอร์สที่ร้องขอยอมรับชนิดคำร้องขอที่กำหนด

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับวัตถุคำขอในเอกสารที่ขอ

ออบเจ็กต์ Koa Response เป็นสิ่งที่เป็นนามธรรมที่อยู่ด้านบนของวัตถุตอบสนองวานิลลาของโหนดซึ่งมีฟังก์ชันเพิ่มเติมที่เป็นประโยชน์สำหรับการพัฒนาเซิร์ฟเวอร์ HTTP ในชีวิตประจำวัน วัตถุตอบสนอง Koa ถูกฝังอยู่ในวัตถุบริบทthis. มาออกจากระบบวัตถุตอบกลับทุกครั้งที่เราได้รับคำขอ

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);

เมื่อคุณเรียกใช้รหัสนี้และไปที่ https://localhost:3000/hello จากนั้นคุณจะได้รับคำตอบดังต่อไปนี้

บนคอนโซลของคุณคุณจะได้รับวัตถุคำขอออกจากระบบ

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

สถานะและข้อความถูกกำหนดโดย Koa โดยอัตโนมัติ แต่เราสามารถแก้ไขได้ หากเราไม่ได้ตั้งค่าเนื้อหาการตอบกลับรหัสสถานะจะตั้งเป็น 404 เมื่อเราตั้งค่าเนื้อหาการตอบกลับแล้วสถานะจะตั้งเป็น 200 โดยค่าเริ่มต้น เราสามารถลบล้างพฤติกรรมนี้ได้อย่างชัดเจน

เราสามารถเข้าถึงคุณสมบัติที่มีประโยชน์มากมายของการตอบสนองโดยใช้วัตถุนี้ ให้เราดูตัวอย่างบางส่วน -

response.header

จัดเตรียมส่วนหัวการตอบกลับทั้งหมด

response.status

แสดงสถานะการตอบกลับ (200, 404, 500 ฯลฯ ) คุณสมบัตินี้ยังใช้เพื่อตั้งค่าสถานะการตอบกลับ

response.message

แสดงข้อความตอบกลับ คุณสมบัตินี้ยังใช้เพื่อตั้งค่าข้อความที่กำหนดเองพร้อมการตอบกลับ มีความเกี่ยวข้องกับ response.status

response.body

รับหรือตั้งค่าเนื้อหาตอบสนอง โดยปกติเราเข้าถึงโดยใช้วัตถุบริบท นี่เป็นเพียงอีกวิธีหนึ่งในการเข้าถึง เนื้อความอาจเป็นประเภท: String, Buffer, Stream, Object หรือ Null

response.type

รับหรือตั้งค่าประเภทเนื้อหาของการตอบกลับปัจจุบัน

response.get (ฟิลด์)

ฟังก์ชันนี้ใช้เพื่อรับค่าของส่วนหัวที่มีฟิลด์ค่าที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่

response.set (ฟิลด์ค่า)

ฟังก์ชันนี้ใช้เพื่อตั้งค่าส่วนหัวของการตอบสนองโดยใช้ฟิลด์และคู่ค่า

response.remove (ฟิลด์)

ฟังก์ชันนี้ใช้เพื่อยกเลิกการตั้งค่าส่วนหัวของการตอบกลับโดยใช้ชื่อฟิลด์

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับวัตถุการตอบสนองในเอกสารที่ตอบสนอง

การเปลี่ยนเส้นทางมีความสำคัญมากเมื่อสร้างเว็บไซต์ หากมีการร้องขอ URL ที่ผิดรูปแบบหรือมีข้อผิดพลาดบางอย่างบนเซิร์ฟเวอร์ของคุณคุณควรเปลี่ยนเส้นทางไปยังหน้าแสดงข้อผิดพลาดที่เกี่ยวข้อง นอกจากนี้ยังสามารถใช้การเปลี่ยนเส้นทางเพื่อป้องกันไม่ให้บุคคลอื่นออกจากพื้นที่ที่ จำกัด ในเว็บไซต์ของคุณ

ให้เราสร้างหน้าแสดงข้อผิดพลาดและเปลี่ยนเส้นทางไปยังหน้านั้นเมื่อใดก็ตามที่มีผู้ร้องขอ URL ที่ผิดรูปแบบ

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);

เมื่อเราเรียกใช้รหัสนี้และไปยังเส้นทางอื่นที่ไม่ใช่ / สวัสดีเราจะถูกเปลี่ยนเส้นทางไปที่ / not_found เราได้วางมิดเดิลแวร์ไว้ที่ส่วนท้าย (app.use function call to this middleware) เพื่อให้แน่ใจว่าเราไปถึงมิดเดิลแวร์ในที่สุดและส่งการตอบกลับที่เกี่ยวข้อง ต่อไปนี้เป็นผลลัพธ์ที่เราเห็นเมื่อเราเรียกใช้โค้ดด้านบน

เมื่อเราไปที่ https://localhost:3000/helloเราได้รับ -

หากเรานำทางไปยังเส้นทางอื่นเราจะได้รับ -

การจัดการข้อผิดพลาดมีส่วนสำคัญในการสร้างเว็บแอปพลิเคชัน Koa ใช้มิดเดิลแวร์เพื่อการนี้เช่นกัน

ใน Koa คุณเพิ่มมิดเดิลแวร์ที่ทำ try { yield next }เป็นหนึ่งในมิดเดิลแวร์แรก หากเราพบข้อผิดพลาดที่ปลายน้ำเราจะกลับไปที่คำสั่ง catch ที่เกี่ยวข้องและจัดการข้อผิดพลาดที่นี่ ตัวอย่างเช่น -

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);

เราได้สร้างข้อผิดพลาดโดยเจตนาในโค้ดด้านบนและกำลังจัดการข้อผิดพลาดในการดักจับมิดเดิลแวร์แรกของเรา จากนั้นจะถูกส่งไปยังคอนโซลของเราและส่งเป็นการตอบกลับไปยังไคลเอนต์ของเรา ต่อไปนี้เป็นข้อความแสดงข้อผิดพลาดที่เราได้รับเมื่อเรียกข้อผิดพลาดนี้

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

ตอนนี้คำขอใด ๆ ที่ส่งไปยังเซิร์ฟเวอร์จะทำให้เกิดข้อผิดพลาดนี้

ฟังก์ชันมิดเดิลแวร์คือฟังก์ชันที่สามารถเข้าถึงไฟล์ context objectและฟังก์ชันมิดเดิลแวร์ถัดไปในวงจรการตอบสนองคำขอของแอปพลิเคชัน ฟังก์ชันเหล่านี้ใช้เพื่อแก้ไขอ็อบเจ็กต์การร้องขอและการตอบสนองสำหรับงานเช่นการแยกวิเคราะห์เนื้อหาของคำร้องขอการเพิ่มส่วนหัวการตอบสนองเป็นต้น Koa ก้าวไปอีกขั้นด้วยการให้'downstream'จากนั้นจึงเลื่อนการควบคุมกลับ 'upstream'. ผลกระทบนี้เรียกว่าcascading.

ต่อไปนี้เป็นตัวอย่างง่ายๆของฟังก์ชันมิดเดิลแวร์ที่กำลังทำงานอยู่

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);

มิดเดิลแวร์ข้างต้นเรียกว่าสำหรับทุกคำขอบนเซิร์ฟเวอร์ ดังนั้นหลังจากการร้องขอทุกครั้งเราจะได้รับข้อความต่อไปนี้ในคอนโซล

A new request received at 1467267512545

หากต้องการ จำกัด เส้นทางเฉพาะ (และรูทย่อยทั้งหมด) เราเพียงแค่ต้องสร้างเส้นทางเช่นเดียวกับที่เราทำสำหรับการกำหนดเส้นทาง อันที่จริงมันเป็นมิดเดิลแวร์เหล่านี้เท่านั้นที่จัดการคำขอของเรา

ตัวอย่างเช่น,

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);

ตอนนี้เมื่อใดก็ตามที่คุณร้องขอรูทย่อยของ '/ request' ระบบจะบันทึกเวลาเท่านั้น

ลำดับการโทรของมิดเดิลแวร์

สิ่งที่สำคัญที่สุดอย่างหนึ่งเกี่ยวกับมิดเดิลแวร์ใน Koa คือลำดับที่เขียน / รวมไว้ในไฟล์ของคุณคือลำดับที่จะดำเนินการต่อท้ายสตรีม ทันทีที่เรากดคำสั่งอัตราผลตอบแทนในมิดเดิลแวร์มันจะเปลี่ยนเป็นมิดเดิลแวร์ถัดไปในบรรทัดจนกว่าเราจะไปถึงอันสุดท้าย จากนั้นอีกครั้งเราจะเริ่มการสำรองข้อมูลและเรียกคืนฟังก์ชันจากคำสั่งผลตอบแทน

ตัวอย่างเช่นในข้อมูลโค้ดต่อไปนี้ฟังก์ชันแรกจะดำเนินการก่อนจนกว่าจะได้ผลจากนั้นมิดเดิลแวร์ที่สองจนกว่าจะให้ผลตามด้วยฟังก์ชันที่สาม เนื่องจากเราไม่มีมิดเดิลแวร์อีกต่อไปแล้วเราจึงเริ่มทำการสำรองข้อมูลโดยดำเนินการในลำดับย้อนกลับคือสามวินาทีแรก ตัวอย่างนี้สรุปวิธีการใช้มิดเดิลแวร์ด้วยวิธี 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);

เมื่อเราไปที่ '/' หลังจากเรียกใช้รหัสนี้บนคอนโซลของเราเราจะได้รับ -

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.

แผนภาพต่อไปนี้สรุปสิ่งที่เกิดขึ้นจริงในตัวอย่างข้างต้น

ตอนนี้เรารู้วิธีสร้างมิดเดิลแวร์ของเราเองแล้วให้เราพูดคุยเกี่ยวกับมิดเดิลแวร์ที่สร้างโดยชุมชนที่ใช้บ่อยที่สุด

ตัวกลางของบุคคลที่สาม

รายชื่อตัวกลางของบุคคลที่สามสำหรับ Express มีอยู่ที่นี่ ต่อไปนี้เป็นมิดเดิลแวร์ที่ใช้บ่อยที่สุด -

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

เราจะพูดถึงมิดเดิลแวร์หลายตัวในบทต่อ ๆ ไป

ปั๊กเป็นเครื่องยนต์เทมเพลต Templating engine ใช้เพื่อลบความยุ่งเหยิงของโค้ดเซิร์ฟเวอร์ของเราด้วย HTML โดยเชื่อมสตริงเข้ากับเทมเพลต HTML ที่มีอยู่ Pug เป็นเครื่องมือสร้างเทมเพลตที่ทรงพลังมากซึ่งมีคุณสมบัติหลากหลายเช่นfilters, includes, inheritance, interpolationฯลฯ มีพื้นมากมายที่จะครอบคลุมนี้

ในการใช้ Pug กับ Koa เราจำเป็นต้องติดตั้งโดยใช้คำสั่งต่อไปนี้

$ npm install --save pug koa-pug

เมื่อติดตั้งปั๊กแล้วให้ตั้งเป็นเครื่องมือสร้างเทมเพลตสำหรับแอปของคุณ เพิ่มรหัสต่อไปนี้ในไฟล์ app.js ของคุณ

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);

ตอนนี้สร้างไดเร็กทอรีใหม่ที่เรียกว่า views ภายในไดเร็กทอรีสร้างไฟล์ชื่อ first_view.pug และป้อนข้อมูลต่อไปนี้ในไดเร็กทอรี

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

หากต้องการเรียกใช้หน้านี้ให้เพิ่มเส้นทางต่อไปนี้ในแอปของคุณ

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

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

คุณจะได้รับผลลัพธ์เป็น -

สิ่งที่ปั๊กทำคือมันแปลงมาร์กอัปที่ดูเรียบง่ายนี้เป็น html เราไม่จำเป็นต้องติดตามการปิดแท็กของเราไม่จำเป็นต้องใช้คีย์เวิร์ด class และ id แทนที่จะใช้ "." และ '#' เพื่อกำหนด รหัสข้างต้นจะถูกแปลงเป็นไฟล์

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

Pug สามารถทำอะไรได้มากกว่าการทำให้มาร์กอัป HTML ง่ายขึ้น ลองสำรวจคุณสมบัติเหล่านี้ของ Pug

แท็กง่ายๆ

แท็กจะซ้อนกันตามการเยื้อง เช่นในตัวอย่างข้างต้น<title> อยู่เยื้องภายใน <head>แท็กก็เลยอยู่ข้างใน อย่างไรก็ตาม<body> แท็กอยู่ในการเยื้องเดียวกันดังนั้นจึงเป็นพี่น้องของ <head> แท็ก

เราไม่จำเป็นต้องปิดแท็ก ทันทีที่ Pug พบแท็กถัดไปในระดับการเยื้องเดียวกันหรือระดับนอกมันจะปิดแท็กให้เรา

มีสามวิธีในการใส่ข้อความภายในแท็ก -

  • แยกพื้นที่ -
h1 Welcome to Pug
  • ข้อความไปป์ -
div
   | To insert multiline text, 
   | You can use the pipe operator.
  • บล็อกข้อความ -
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.

ความคิดเห็น

Pug ใช้ไวยากรณ์เดียวกันกับ JavaScript (//) ในการสร้างข้อคิดเห็น ความคิดเห็นเหล่านี้จะถูกแปลงเป็นความคิดเห็น html (<! - comment ->) ตัวอย่างเช่น,

//This is a Pug comment

ความคิดเห็นนี้ถูกแปลงเป็น -

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

คุณลักษณะ

ในการกำหนดแอตทริบิวต์เราใช้รายการแอตทริบิวต์ที่คั่นด้วยเครื่องหมายจุลภาคในวงเล็บ แอตทริบิวต์คลาสและ ID มีการแสดงพิเศษ บรรทัดโค้ดต่อไปนี้ครอบคลุมการกำหนดแอตทริบิวต์คลาสและ id สำหรับแท็ก html ที่กำหนด

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

โค้ดบรรทัดนี้ถูกแปลงเป็น -

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

ส่งผ่านค่าไปยังเทมเพลต

เมื่อเราสร้างเทมเพลต Pug เราสามารถส่งผ่านค่าจากตัวจัดการเส้นทางของเราซึ่งเราสามารถใช้ในเทมเพลตของเราได้ สร้างตัวจัดการเส้นทางใหม่โดยใช้รหัสต่อไปนี้

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);

จากนั้นสร้างไฟล์มุมมองใหม่ในไดเร็กทอรี views ชื่อ dynamic.pug โดยใช้โค้ดต่อไปนี้

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

เปิด localhost:3000/dynamicในเบราว์เซอร์ของคุณและสิ่งต่อไปนี้ควรเป็นผลลัพธ์ -

เรายังสามารถใช้ตัวแปรที่ส่งผ่านเหล่านี้ภายในข้อความ ในการแทรกตัวแปรที่ส่งผ่านระหว่างข้อความของแท็กเราใช้ไวยากรณ์ # {variableName} ตัวอย่างเช่นในตัวอย่างข้างต้นหากเราต้องการแทรกคำทักทายจาก TutorialsPoint เราจะต้องใช้รหัสต่อไปนี้

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

วิธีการใช้ค่านี้เรียกว่าการแก้ไข

เงื่อนไข

เราสามารถใช้ประโยคเงื่อนไขและโครงสร้างแบบวนซ้ำได้เช่นกัน ลองพิจารณาตัวอย่างที่ใช้ได้จริงนี้หากผู้ใช้เข้าสู่ระบบเราต้องการแสดง "สวัสดีผู้ใช้" และหากไม่เป็นเช่นนั้นเราจะแสดงลิงก์ "เข้าสู่ระบบ / สมัครใช้งาน" ให้เขาดู เพื่อให้บรรลุเป้าหมายนี้เราสามารถกำหนดเทมเพลตง่ายๆเช่น -

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

เมื่อเราสร้างสิ่งนี้โดยใช้เส้นทางของเราและถ้าเราส่งวัตถุเช่น -

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

มันจะแสดงข้อความว่าสวัสดี Ayush อย่างไรก็ตามหากเราไม่ส่งผ่านวัตถุใด ๆ หรือส่งต่อโดยไม่มีรหัสผู้ใช้เราจะได้รับลิงค์ลงทะเบียน

รวมและส่วนประกอบ

Pug เป็นวิธีที่ใช้งานง่ายมากในการสร้างส่วนประกอบสำหรับหน้าเว็บ ตัวอย่างเช่นหากคุณเห็นเว็บไซต์ข่าวส่วนหัวที่มีโลโก้และหมวดหมู่จะได้รับการแก้ไขเสมอ แทนที่จะคัดลอกไปยังทุกมุมมองเราสามารถใช้การรวม ตัวอย่างต่อไปนี้แสดงให้เห็นว่าเราสามารถใช้ include -

สร้างมุมมองสามแบบด้วยรหัสต่อไปนี้ -

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.

สร้างเส้นทางสำหรับสิ่งนี้ดังนี้

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);

ไปที่ localhost:3000/componentsคุณควรได้รับผลลัพธ์ต่อไปนี้

include ยังสามารถใช้เพื่อรวมข้อความธรรมดา CSS และ JavaScript

คุณสมบัติอื่น ๆ ของปั๊กยังมีอีกมากมาย อย่างไรก็ตามสิ่งเหล่านี้ไม่อยู่ในขอบเขตของบทช่วยสอนนี้ นอกจากนี้คุณยังสามารถสำรวจปั๊กที่ปั๊ก

แบบฟอร์มเป็นส่วนหนึ่งของเว็บ เกือบทุกเว็บไซต์ที่เราเยี่ยมชมเสนอแบบฟอร์มที่ส่งหรือดึงข้อมูลบางอย่างให้เรา ในการเริ่มต้นใช้งานแบบฟอร์มเราจะติดตั้ง koa-body ก่อน ในการติดตั้งสิ่งนี้ไปที่เทอร์มินัลของคุณและใช้ -

$ npm install --save koa-body

แทนที่เนื้อหาไฟล์ app.js ของคุณด้วยรหัสต่อไปนี้

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);

สิ่งใหม่ที่เรากำลังทำอยู่ที่นี่คือการนำเข้าตัวแยกวิเคราะห์เนื้อหาและตัวกรอง เรากำลังใช้ตัวแยกวิเคราะห์เนื้อหาสำหรับการแยกวิเคราะห์คำขอส่วนหัว json และ x-www-form-urlencoded ในขณะที่เราใช้ multer สำหรับการแยกวิเคราะห์ข้อมูลหลายส่วน / แบบฟอร์ม

ให้เราสร้างแบบฟอร์ม html เพื่อทดสอบสิ่งนี้! สร้างมุมมองใหม่ชื่อ form.pug ด้วยรหัสต่อไปนี้

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

เรียกใช้เซิร์ฟเวอร์ของคุณโดยใช้ -

nodemon index.js

ไปที่ localhost: 3000 / แล้วกรอกแบบฟอร์มตามที่คุณต้องการแล้วส่ง คุณจะได้รับคำตอบเป็น -

ดูที่คอนโซลของคุณซึ่งจะแสดงเนื้อหาของคำขอของคุณเป็นวัตถุ JavaScript ตัวอย่างเช่น -

this.request.bodyวัตถุมีเนื้อหาคำขอที่แยกวิเคราะห์ของคุณ หากต้องการใช้ฟิลด์จากออบเจ็กต์นั้นให้ใช้เป็นออบเจ็กต์ JS ปกติ

นี่เป็นเพียงวิธีหนึ่งในการส่งคำขอ มีวิธีอื่น ๆ อีกมากมาย แต่วิธีเหล่านี้ไม่เกี่ยวข้องที่จะกล่าวถึงในที่นี้เนื่องจากแอป Koa ของเราจะจัดการคำขอเหล่านั้นทั้งหมดในลักษณะเดียวกัน เพื่ออ่านข้อมูลเพิ่มเติมเกี่ยวกับวิธีการที่แตกต่างกันจะทำให้คำขอมีลักษณะที่นี้หน้า

เว็บแอปพลิเคชันจำเป็นต้องมีฟังก์ชันเพื่อให้สามารถอัปโหลดไฟล์ได้ ให้เราดูว่าเราสามารถรับไฟล์จากไคลเอนต์และจัดเก็บไว้บนเซิร์ฟเวอร์ของเราได้อย่างไร

เราได้ใช้มิดเดิลแวร์ koa-body สำหรับการแยกวิเคราะห์คำขอแล้ว มิดเดิลแวร์นี้ยังใช้สำหรับจัดการการอัปโหลดไฟล์ ให้เราสร้างแบบฟอร์มที่อนุญาตให้เราอัปโหลดไฟล์จากนั้นบันทึกไฟล์เหล่านี้โดยใช้ Koa ก่อนอื่นให้สร้างเทมเพลตชื่อfile_upload.pug มีเนื้อหาดังต่อไปนี้

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")

โปรดทราบว่าคุณต้องระบุประเภทการเข้ารหัสเดียวกันกับด้านบนในแบบฟอร์มของคุณ ตอนนี้ให้เราจัดการข้อมูลนี้บนเซิร์ฟเวอร์ของเรา

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);

เมื่อคุณเรียกใช้สิ่งนี้คุณจะได้รับแบบฟอร์มต่อไปนี้

เมื่อคุณส่งสิ่งนี้คอนโซลของคุณจะสร้างผลลัพธ์ต่อไปนี้

ไฟล์ที่อัพโหลดจะถูกเก็บไว้ในพา ธ ในเอาต์พุตด้านบน คุณสามารถเข้าถึงไฟล์ในคำขอโดยใช้this.request.body.files และฟิลด์ในคำขอนั้นโดย this.request.body.fields.

ไฟล์คงเป็นไฟล์ที่ไคลเอ็นต์ดาวน์โหลดตามที่มาจากเซิร์ฟเวอร์ สร้างไดเร็กทอรีใหม่public. Express โดยค่าเริ่มต้นไม่อนุญาตให้คุณแสดงไฟล์แบบคงที่

เราต้องการมิดเดิลแวร์เพื่อตอบสนองวัตถุประสงค์นี้ ไปข้างหน้าและติดตั้งkoa-serve -

$ npm install --save koa-static

ตอนนี้เราจำเป็นต้อง useมิดเดิลแวร์นี้ ก่อนหน้านั้นให้สร้างไดเรกทอรีที่เรียกว่าสาธารณะ เราจะจัดเก็บไฟล์คงที่ทั้งหมดของเราที่นี่ สิ่งนี้ช่วยให้เราสามารถรักษารหัสเซิร์ฟเวอร์ของเราให้ปลอดภัยเนื่องจากไม่มีสิ่งใดอยู่เหนือโฟลเดอร์สาธารณะนี้ที่ลูกค้าสามารถเข้าถึงได้ หลังจากสร้างไดเร็กทอรีสาธารณะแล้วให้สร้างไฟล์ชื่อhello.txtด้วยเนื้อหาที่คุณชอบ ตอนนี้เพิ่มสิ่งต่อไปนี้ใน app ของคุณ js.

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

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

app.listen(3000);

Note- Koa ค้นหาไฟล์ที่สัมพันธ์กับไดเร็กทอรีแบบคงที่ดังนั้นชื่อของไดเร็กทอรีแบบคงที่ไม่ได้เป็นส่วนหนึ่งของ URL ขณะนี้รูทรูทถูกตั้งค่าเป็น dir สาธารณะของคุณดังนั้นไฟล์สแตติกทั้งหมดที่คุณโหลดจะถูกพิจารณาว่าพับลิกเป็นรูท หากต้องการทดสอบว่าใช้งานได้ดีให้เรียกใช้แอปของคุณและไปที่https://localhost:3000/hello.txt

คุณควรได้รับผลลัพธ์ต่อไปนี้ โปรดทราบว่านี่ไม่ใช่เอกสาร HTML หรือมุมมอง Pug แต่เป็นไฟล์ txt ธรรมดา

Dirs คงหลาย

นอกจากนี้เรายังสามารถตั้งค่าไดเรกทอรีสินทรัพย์คงที่หลายรายการโดยใช้ -

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

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

app.listen(3000);

ตอนนี้เมื่อเราขอไฟล์ Koa จะค้นหาไดเร็กทอรีเหล่านี้และส่งไฟล์ที่ตรงกันมาให้เรา

คุกกี้เป็นไฟล์ / ข้อมูลขนาดเล็กที่เรียบง่ายซึ่งถูกส่งไปยังไคลเอนต์ด้วยคำขอของเซิร์ฟเวอร์และจัดเก็บไว้ที่ฝั่งไคลเอ็นต์ ทุกครั้งที่ผู้ใช้โหลดเว็บไซต์กลับมาคุกกี้นี้จะถูกส่งไปพร้อมกับคำขอ ซึ่งจะช่วยติดตามการดำเนินการของผู้ใช้ มีการใช้งานคุกกี้ HTTP มากมาย

  • การจัดการเซสชัน
  • Personalization (ระบบคำแนะนำ)
  • การติดตามผู้ใช้

ในการใช้คุกกี้กับ Koa เรามีฟังก์ชั่น: ctx.cookies.set() และ ctx.cookies.get(). หากต้องการตั้งค่าคุกกี้ใหม่ให้กำหนดเส้นทางใหม่ในแอป Koa ของเรา

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);

หากต้องการตรวจสอบว่าคุกกี้ถูกตั้งค่าไว้หรือไม่เพียงไปที่เบราว์เซอร์ของคุณเปิดคอนโซลแล้วป้อน -

console.log(document.cookie);

สิ่งนี้จะสร้างผลลัพธ์ต่อไปนี้ (คุณอาจมีการตั้งค่าคุกกี้มากขึ้นอาจเป็นเพราะส่วนขยายในเบราว์เซอร์ของคุณ)

"foo = bar"

นี่คือตัวอย่างข้างต้น

เบราว์เซอร์ยังส่งคุกกี้กลับทุกครั้งที่ค้นหาเซิร์ฟเวอร์ หากต้องการดูคุกกี้บนเซิร์ฟเวอร์ของคุณบนคอนโซลเซิร์ฟเวอร์ในเส้นทางให้เพิ่มรหัสต่อไปนี้ในเส้นทางนั้น

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

ครั้งต่อไปที่คุณส่งคำขอไปยังเส้นทางนี้คุณจะได้รับผลลัพธ์ดังต่อไปนี้

Cookies: foo = bar

การเพิ่มคุกกี้ด้วยเวลาหมดอายุ

คุณสามารถเพิ่มคุกกี้ที่หมดอายุได้ หากต้องการเพิ่มคุกกี้ที่หมดอายุเพียงแค่ส่งวัตถุที่มีคุณสมบัติ "หมดอายุ" ที่ตั้งค่าเป็นเวลาที่คุณต้องการให้มันหมดอายุ ตัวอย่างเช่น,

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);

การลบคุกกี้ที่มีอยู่

หากต้องการยกเลิกการตั้งค่าคุกกี้เพียงแค่ตั้งค่าคุกกี้เป็นสตริงว่าง ตัวอย่างเช่นหากคุณต้องการล้างคุกกี้ที่ชื่อfooใช้รหัสต่อไปนี้

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);

การดำเนินการนี้จะยกเลิกการตั้งค่าคุกกี้ดังกล่าว โปรดทราบว่าคุณควรออกจากไฟล์HttpOnly ตัวเลือกให้เป็นจริงเมื่อไม่ใช้คุกกี้ในรหัสฝั่งไคลเอ็นต์

HTTP ไม่มีสถานะดังนั้นในการเชื่อมโยงคำขอกับคำขออื่น ๆ คุณต้องมีวิธีจัดเก็บข้อมูลผู้ใช้ระหว่างคำขอ HTTP คุกกี้และพารามิเตอร์ URL เป็นวิธีที่เหมาะสมในการขนส่งข้อมูลระหว่างไคลเอนต์และเซิร์ฟเวอร์ อย่างไรก็ตามทั้งคู่สามารถอ่านได้จากฝั่งไคลเอ็นต์ เซสชันแก้ปัญหานี้ได้อย่างตรงจุด คุณกำหนดรหัสลูกค้าและส่งคำขอเพิ่มเติมทั้งหมดโดยใช้ ID นั้น ข้อมูลที่เกี่ยวข้องกับไคลเอนต์จะถูกเก็บไว้บนเซิร์ฟเวอร์ที่เชื่อมโยงกับ ID นี้

เราจะต้องใช้ koa-session จึงติดตั้งโดยใช้ -

npm install --save koa-session

เราจะใส่ไฟล์ koa-sessionมิดเดิลแวร์ในสถานที่ ในตัวอย่างนี้เราจะใช้ RAM เพื่อจัดเก็บเซสชัน ห้ามใช้สิ่งนี้ในสภาพแวดล้อมการผลิต มิดเดิลแวร์ของเซสชันจะจัดการทุกอย่างเช่นการสร้างเซสชันการตั้งค่าคุกกี้เซสชันและการสร้างวัตถุเซสชันในวัตถุบริบท

เมื่อใดก็ตามที่เราทำการร้องขอจากไคลเอนต์เดิมอีกครั้งเราจะมีข้อมูลเซสชันของพวกเขาเก็บไว้กับเรา (เนื่องจากเซิร์ฟเวอร์นั้นไม่ได้รีสตาร์ท) เราสามารถเพิ่มคุณสมบัติเพิ่มเติมให้กับวัตถุเซสชันนี้ได้ ในตัวอย่างต่อไปนี้เราจะสร้างตัวนับมุมมองสำหรับลูกค้า

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);

สิ่งที่โค้ดข้างต้นทำคือเมื่อผู้ใช้เยี่ยมชมไซต์จะสร้างเซสชันใหม่สำหรับผู้ใช้และกำหนดคุกกี้ ครั้งต่อไปที่ผู้ใช้เยี่ยมชมคุกกี้จะถูกตรวจสอบและตัวแปรเซสชัน page_view จะได้รับการอัปเดตตามนั้น

ตอนนี้ถ้าคุณเรียกใช้แอพและไปที่ localhost:3000, คุณจะได้รับคำตอบดังต่อไปนี้

หากคุณกลับมาที่หน้านี้ตัวนับหน้าจะเพิ่มขึ้น ในกรณีนี้เพจถูกรีเฟรช 12 ครั้ง

การพิสูจน์ตัวตนเป็นกระบวนการที่ข้อมูลประจำตัวที่ให้มาเปรียบเทียบกับข้อมูลประจำตัวที่อยู่ในฐานข้อมูลของข้อมูลผู้ใช้ที่ได้รับอนุญาตบนระบบปฏิบัติการภายในหรือภายในเซิร์ฟเวอร์การพิสูจน์ตัวตน หากข้อมูลรับรองตรงกันกระบวนการจะเสร็จสมบูรณ์และผู้ใช้จะได้รับสิทธิ์ในการเข้าถึง

เราจะสร้างระบบตรวจสอบสิทธิ์ขั้นพื้นฐานที่จะใช้ Basic HTTP Authentication. นี่เป็นวิธีที่ง่ายที่สุดในการบังคับใช้การควบคุมการเข้าถึงเนื่องจากไม่ต้องใช้คุกกี้เซสชันหรือสิ่งอื่นใด ในการใช้งานลูกค้าจะต้องส่งส่วนหัวการอนุญาตพร้อมกับทุกคำขอ ชื่อผู้ใช้และรหัสผ่านไม่ได้เข้ารหัส แต่จะเชื่อมต่อกันเป็นสตริงเดียวดังต่อไปนี้

username:password

สตริงนี้เข้ารหัสด้วย Base64 และคำว่า Basic จะอยู่หน้าค่านี้ ตัวอย่างเช่นหากชื่อผู้ใช้ของคุณคือ Ayush และรหัสผ่านอินเดียให้ใช้สตริง"Ayush:India" จะถูกส่งแบบเข้ารหัสในส่วนหัวการอนุญาต

Authorization: Basic QXl1c2g6SW5kaWE=

ในการใช้สิ่งนี้ในแอป koa ของคุณคุณจะต้องมีมิดเดิลแวร์ koa-basic-auth ติดตั้งโดยใช้ -

$ npm install --save koa-basic-auth

ตอนนี้เปิดไฟล์ app.js ของคุณแล้วป้อนรหัสต่อไปนี้

//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);

เราได้สร้างข้อผิดพลาดในการจัดการมิดเดิลแวร์เพื่อจัดการข้อผิดพลาดที่เกี่ยวข้องกับการตรวจสอบสิทธิ์ทั้งหมด จากนั้นเราได้สร้าง 2 เส้นทาง -

  • /protected- สามารถเข้าถึงเส้นทางนี้ได้ก็ต่อเมื่อผู้ใช้ส่งส่วนหัวการตรวจสอบสิทธิ์ที่ถูกต้อง สำหรับคนอื่น ๆ ทั้งหมดจะให้ข้อผิดพลาด

  • /unprotected - ทุกคนสามารถเข้าถึงเส้นทางนี้โดยมีหรือไม่มีการตรวจสอบสิทธิ์

ตอนนี้หากคุณส่งคำขอไปยัง / ป้องกันโดยไม่มีส่วนหัวการตรวจสอบสิทธิ์หรือข้อมูลรับรองไม่ถูกต้องคุณจะได้รับข้อผิดพลาด ตัวอย่างเช่น,

$ curl https://localhost:3000/protected

คุณจะได้รับคำตอบเป็น -

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

อย่างไรก็ตามด้วยข้อมูลรับรองที่ถูกต้องคุณจะได้รับคำตอบที่คาดหวัง ตัวอย่างเช่น,

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

คุณจะได้รับคำตอบเป็น -

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.

ทุกคนยังสามารถเข้าถึงเส้นทาง / ที่ไม่มีการป้องกันได้

การบีบอัดเป็นวิธีที่ง่ายและมีประสิทธิภาพในการประหยัดแบนด์วิดท์และเพิ่มความเร็วไซต์ของคุณ มันเข้ากันได้กับเบราว์เซอร์สมัยใหม่เท่านั้นและควรใช้ด้วยความระมัดระวังหากผู้ใช้ของคุณใช้เบราว์เซอร์แบบเดิมด้วย

เมื่อส่งการตอบกลับจากเซิร์ฟเวอร์หากใช้การบีบอัดจะสามารถปรับปรุงเวลาในการโหลดได้อย่างมาก เราจะใช้มิดเดิลแวร์ที่เรียกว่าkoa-compress เพื่อดูแลการบีบอัดไฟล์รวมถึงการตั้งค่าส่วนหัวที่เหมาะสม

ไปข้างหน้าและติดตั้งมิดเดิลแวร์โดยใช้ -

$ npm install --save koa-compress

ตอนนี้ในไฟล์ app.js ของคุณให้เพิ่มรหัสต่อไปนี้ -

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);

สิ่งนี้ทำให้มิดเดิลแวร์การบีบอัดของเราเข้าที่ ตัวเลือกตัวกรองคือฟังก์ชันที่ตรวจสอบชนิดเนื้อหาการตอบกลับเพื่อตัดสินใจว่าจะบีบอัดหรือไม่ อ็อพชัน threshold คือขนาดการตอบสนองต่ำสุดในหน่วยไบต์ที่จะบีบอัด สิ่งนี้ทำให้มั่นใจได้ว่าเราจะไม่บีบอัดทุกการตอบสนองเพียงเล็กน้อย

ต่อไปนี้เป็นการตอบสนองโดยไม่ต้องบีบอัด

ต่อไปนี้คือการตอบสนองที่คล้ายกันกับการบีบอัด

หากคุณดูแท็บขนาดที่ด้านล่างคุณจะเห็นความแตกต่างระหว่างทั้งสองได้เป็นอย่างดี มีการปรับปรุงมากกว่า 150% เมื่อเราบีบอัดไฟล์

การแคชเป็นคำศัพท์สำหรับการจัดเก็บการตอบกลับที่ใช้ซ้ำได้เพื่อให้การร้องขอในภายหลังเร็วขึ้น ทุกเบราว์เซอร์มาพร้อมกับการใช้งานแคช HTTP สิ่งที่เราต้องทำคือตรวจสอบให้แน่ใจว่าการตอบสนองของเซิร์ฟเวอร์แต่ละรายการมีคำสั่งส่วนหัว HTTP ที่ถูกต้องเพื่อสั่งให้เบราว์เซอร์ทราบว่าเบราว์เซอร์สามารถแคชการตอบกลับเมื่อใดและนานเท่าใด

ต่อไปนี้เป็นประโยชน์บางประการของการรวมแคชในเว็บแอปของคุณ -

  • ต้นทุนเครือข่ายของคุณลดลง หากเนื้อหาของคุณถูกแคชคุณจะต้องส่งน้อยลงสำหรับทุกคำขอที่ตามมา

  • ความเร็วและประสิทธิภาพของเว็บไซต์ของคุณเพิ่มขึ้น

  • เนื้อหาของคุณสามารถใช้งานได้แม้ว่าลูกค้าของคุณจะออฟไลน์ก็ตาม

เราจะใช้มิดเดิลแวร์ koa-static-cache เพื่อใช้แคชในแอปของเรา ติดตั้งมิดเดิลแวร์เหล่านี้โดยใช้ -

$ npm install --save koa-static-cache

ไปที่ไฟล์ app.js ของคุณแล้วเพิ่มรหัสต่อไปนี้

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);

koa-static-cacheมิดเดิลแวร์ใช้เพื่อแคชการตอบสนองของเซิร์ฟเวอร์ในฝั่งไคลเอ็นต์ cache-controlส่วนหัวถูกตั้งค่าตามตัวเลือกที่เรามีให้ในขณะที่เริ่มต้นวัตถุแคช เราได้กำหนดเวลาหมดอายุของการตอบกลับที่แคชไว้เป็น 1 ปี ต่อไปนี้เป็นการเปรียบเทียบคำขอที่เราส่งไปก่อนและหลังไฟล์ถูกแคช

ก่อนที่ไฟล์นี้จะถูกแคชรหัสสถานะที่ส่งคืนคือ 200 ซึ่งก็ใช้ได้ ส่วนหัวของการตอบกลับมีข้อมูลหลายอย่างเกี่ยวกับเนื้อหาที่จะแคชและยังให้ไฟล์ETag สำหรับเนื้อหา

ในครั้งต่อไปที่ส่งคำขอจะถูกส่งไปพร้อมกับ ETtag เนื่องจากเนื้อหาของเราไม่ได้เปลี่ยนแปลงบนเซิร์ฟเวอร์ ETag ที่เกี่ยวข้องจึงยังคงเหมือนเดิมและลูกค้าได้รับแจ้งว่าสำเนาที่มีอยู่ในเครื่องนั้นเป็นข้อมูลล่าสุดกับสิ่งที่เซิร์ฟเวอร์จะให้และควรใช้ในเครื่องแทนการร้องขอ อีกครั้ง.

Note- สำหรับการทำให้ไฟล์แคชไม่ถูกต้องคุณเพียงแค่เปลี่ยนชื่อไฟล์และอัปเดตข้อมูลอ้างอิง เพื่อให้แน่ใจว่าคุณมีไฟล์ใหม่ที่จะส่งไปยังไคลเอนต์และไคลเอนต์ไม่สามารถโหลดกลับจากแคชได้

เราได้รับคำขอ แต่ไม่ได้จัดเก็บไว้ที่ใด เราจำเป็นต้องมีฐานข้อมูลเพื่อจัดเก็บข้อมูล เราจะใช้ฐานข้อมูล NoSQL ที่มีชื่อเสียงชื่อMongoDB. หากต้องการติดตั้งและอ่านเกี่ยวกับ Mongo ให้ไปที่ลิงค์นี้

ในการใช้ Mongo กับ Koa เราจำเป็นต้องมีไคลเอนต์ API สำหรับโหนด มีหลายตัวเลือกสำหรับเรามี แต่สำหรับการกวดวิชานี้เราจะยึดติดอยู่กับพังพอน พังพอนใช้สำหรับdocument modelingในโหนดสำหรับ MongoDB การสร้างแบบจำลองเอกสารหมายความว่าเราจะสร้างไฟล์Model (เหมือนก class ในการเขียนโปรแกรมเชิงเอกสาร) จากนั้นเราจะผลิต documents โดยใช้ Model นี้ (เหมือนที่เราสร้าง documents of a classใน OOP) การประมวลผลทั้งหมดของเราจะดำเนินการใน "เอกสาร" เหล่านี้จากนั้นสุดท้ายเราจะเขียนเอกสารเหล่านี้ในฐานข้อมูลของเรา

การตั้งค่าพังพอน

ตอนนี้เราติดตั้ง Mongo แล้วให้เราติดตั้งพังพอนแบบเดียวกับที่เราติดตั้งแพ็คเกจโหนดอื่น ๆ

$ npm install --save mongoose

ก่อนที่เราจะเริ่มใช้พังพอนเราต้องสร้างฐานข้อมูลโดยใช้เปลือก Mongo ในการสร้างฐานข้อมูลใหม่ให้เปิดเทอร์มินัลของคุณแล้วป้อน "mongo" เปลือก Mongo จะเริ่มขึ้นให้ป้อนสิ่งต่อไปนี้

use my_db

ฐานข้อมูลใหม่จะถูกสร้างขึ้นสำหรับคุณ เมื่อใดก็ตามที่คุณเปิด Mongo shell ค่าเริ่มต้นจะเป็น "test" db และคุณจะต้องเปลี่ยนเป็นฐานข้อมูลของคุณโดยใช้คำสั่งเดียวกับด้านบน

ในการใช้พังพอนเราจะต้องใช้มันในไฟล์ app.js ของเราจากนั้นเชื่อมต่อกับบริการ mongod ที่ทำงานบน 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);

ตอนนี้แอพของเราเชื่อมต่อกับฐานข้อมูลของเราแล้วเรามาสร้าง Model ใหม่กันเถอะ โมเดลนี้จะทำหน้าที่รวบรวมในฐานข้อมูลของเรา ในการสร้างโมเดลใหม่ให้ใช้รหัสต่อไปนี้ก่อนกำหนดเส้นทางใด ๆ

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);

รหัสด้านบนกำหนดสคีมาสำหรับบุคคลและใช้ในการสร้างแบบจำลองพังพอน Person.

การบันทึกเอกสาร

ตอนนี้เราจะสร้างแบบฟอร์ม html ใหม่ซึ่งจะได้รับรายละเอียดของบุคคลและบันทึกลงในฐานข้อมูลของเรา ในการสร้างฟอร์มให้สร้างไฟล์มุมมองใหม่ที่เรียกว่า person.pug ในไดเร็กทอรี views ที่มีเนื้อหาต่อไปนี้

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

เพิ่มเส้นทางรับใหม่ใน index.js เพื่อแสดงเอกสารนี้

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);

ไปที่ localhost: 3000 / คนเพื่อตรวจสอบว่าแบบฟอร์มของเราแสดงถูกต้องหรือไม่ โปรดทราบว่านี่เป็นเพียง UI เท่านั้นยังใช้งานไม่ได้ นี่คือลักษณะของฟอร์มของเรา

ตอนนี้เราจะกำหนดตัวจัดการเส้นทางการโพสต์ที่ "/ person" ซึ่งจะจัดการคำขอนี้

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);

ในโค้ดด้านบนหากเราได้รับฟิลด์ว่างหรือไม่ได้รับฟิลด์ใด ๆ เราจะส่งการตอบสนองข้อผิดพลาด อย่างไรก็ตามหากเราได้รับเอกสารที่มีรูปแบบสมบูรณ์เราจะสร้างเอกสาร newPerson จากแบบจำลองบุคคลและบันทึกลงในฐานข้อมูลของเราโดยใช้newPerson.save()ฟังก์ชัน สิ่งนี้ถูกกำหนดเป็นพังพอนและยอมรับการเรียกกลับเป็นอาร์กิวเมนต์ การเรียกกลับนี้มีสองอาร์กิวเมนต์error และ response. สิ่งนี้จะแสดงมุมมอง show_message ดังนั้นเราจำเป็นต้องสร้างสิ่งนั้นด้วย

เพื่อแสดงการตอบสนองจากเส้นทางนี้เราจะต้องสร้างไฟล์ show_messageดู. สร้างมุมมองใหม่ด้วยรหัสต่อไปนี้

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!

ต่อไปนี้เป็นคำตอบที่เราได้รับเมื่อส่งแบบฟอร์มสำเร็จ (show_message.pug)

ตอนนี้เรามีอินเทอร์เฟซสำหรับสร้างบุคคลแล้ว!

การดึงเอกสาร

พังพอนมีฟังก์ชั่นมากมายในการดึงเอกสารเราจะมุ่งเน้นไปที่สามสิ่งเหล่านี้ ฟังก์ชันทั้งหมดเหล่านี้ใช้การเรียกกลับเป็นพารามิเตอร์สุดท้ายเช่นเดียวกับฟังก์ชันบันทึกอาร์กิวเมนต์คือข้อผิดพลาดและการตอบสนอง

สามฟังก์ชั่นคือ -

Model.find (เงื่อนไขการโทรกลับ)

ฟังก์ชันนี้ค้นหาเอกสารทั้งหมดที่ตรงกับฟิลด์ในออบเจ็กต์เงื่อนไข ตัวดำเนินการเดียวกันที่ใช้ใน Mongo ยังทำงานในพังพอน ตัวอย่างเช่นจะดึงเอกสารทั้งหมดจากคอลเล็กชันของบุคคล

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

การดำเนินการนี้จะดึงเอกสารทั้งหมดที่มีชื่อช่อง "Ayush" และอายุ 20 ปี

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

เรายังสามารถจัดเตรียมการฉายภาพที่เราต้องการได้เช่นช่องที่เราต้องการ ตัวอย่างเช่นหากเราต้องการเฉพาะไฟล์names ของคนที่ nationalityคือ"อินเดีย"เราใช้ -

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

Model.findOne (เงื่อนไขการโทรกลับ)

ฟังก์ชันนี้จะดึงเอกสารเดียวที่เกี่ยวข้องมากที่สุด มีอาร์กิวเมนต์ที่แน่นอนเหมือนกับ Model.find ()

Model.findById (id โทรกลับ)

ฟังก์ชันนี้ใช้เวลาในไฟล์ _id(กำหนดโดย mongo) เป็นอาร์กิวเมนต์แรกสตริงการฉายภาพที่เป็นทางเลือกและการเรียกกลับเพื่อจัดการการตอบสนอง ตัวอย่างเช่น,

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

มาสร้างเส้นทางเพื่อดูบันทึกทุกคน

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);

การอัปเดตเอกสาร

พังพอนมีฟังก์ชันสามอย่างในการอัปเดตเอกสาร

Model.update (เงื่อนไขการอัปเดตการติดต่อกลับ)

ฟังก์ชันนี้รับเงื่อนไขและอัพเดตอ็อบเจ็กต์เป็นอินพุตและใช้การเปลี่ยนแปลงกับเอกสารทั้งหมดที่ตรงกับเงื่อนไขในคอลเลกชัน ตัวอย่างเช่นรหัสต่อไปนี้จะอัปเดตเอกสาร Person ทั้งหมดให้มีสัญชาติ "อเมริกัน"

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

Model.findOneAndUpdate (เงื่อนไขการอัปเดตการติดต่อกลับ)

มันไม่ตรงตามที่พูด ค้นหาเอกสารหนึ่งฉบับโดยยึดตามคิวรีและอัปเดตตามอาร์กิวเมนต์ที่สอง นอกจากนี้ยังใช้การโทรกลับเป็นอาร์กิวเมนต์สุดท้าย ตัวอย่างเช่น,

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

Model.findByIdAndUpdate (id, อัปเดต, โทรกลับ)

ฟังก์ชันนี้จะอัพเดตเอกสารเดียวที่ระบุโดย id ตัวอย่างเช่น,

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

มาสร้างเส้นทางเพื่ออัพเดทผู้คนกันเถอะ นี่จะเป็นเส้นทาง PUT โดยมี id เป็นพารามิเตอร์และรายละเอียดใน payload

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);

ในการทดสอบเส้นทางนี้ให้ป้อนข้อมูลต่อไปนี้ในเทอร์มินัลของคุณ (แทนที่ id ด้วย id จากบุคคลที่คุณสร้างขึ้น)

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

การดำเนินการนี้จะอัปเดตเอกสารที่เกี่ยวข้องกับ id ที่ระบุในเส้นทางพร้อมรายละเอียดข้างต้น

การลบเอกสาร

เราได้ครอบคลุม Create, Read และ Update ตอนนี้เราจะมาดูกันว่าพังพอนสามารถใช้เพื่อลบเอกสารได้อย่างไร มีสามฟังก์ชั่นที่นี่เหมือนกับการอัปเดต

Model.remove (เงื่อนไข [โทรกลับ])

ฟังก์ชั่นนี้รับวัตถุเงื่อนไขเป็นอินพุตและลบเอกสารทั้งหมดที่ตรงกับเงื่อนไข ตัวอย่างเช่นหากเราต้องการเอาคนอายุ 20 ออกทั้งหมด

Person.remove({age:20});

Model.findOneAndRemove (เงื่อนไข [โทรกลับ])

ฟังก์ชันนี้จะลบไฟล์ singleเอกสารที่เกี่ยวข้องมากที่สุดตามวัตถุเงื่อนไข ตัวอย่างเช่น,

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

Model.findByIdAndRemove (id, [โทรกลับ])

ฟังก์ชันนี้จะลบเอกสารเดียวที่ระบุโดย id ตัวอย่างเช่น,

Person.findByIdAndRemove("507f1f77bcf86cd799439011");

ตอนนี้มาสร้างเส้นทางเพื่อลบบุคคลออกจากฐานข้อมูลของเรา

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);

ในการทดสอบสิ่งนี้ให้ใช้คำสั่ง curl ต่อไปนี้ -

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

การดำเนินการนี้จะลบบุคคลที่มีรหัสที่ระบุซึ่งสร้างข้อความต่อไปนี้ -

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

นี่เป็นการสรุปวิธีที่เราสามารถสร้างแอปพลิเคชัน CRUD ง่ายๆโดยใช้ MongoDB, พังพอนและ Koa หากต้องการสำรวจพังพอนเพิ่มเติมโปรดอ่านเอกสาร API

ในการสร้างแอปพลิเคชันมือถือแอปพลิเคชันหน้าเดียวใช้การโทร AJAX และให้ข้อมูลกับลูกค้าคุณจะต้องมี API รูปแบบสถาปัตยกรรมยอดนิยมของวิธีการจัดโครงสร้างและตั้งชื่อ API เหล่านี้และจุดสิ้นสุดเรียกว่าREST(Representational Transfer State). HTTP 1.1 ได้รับการออกแบบโดยคำนึงถึงหลักการ REST REST ได้รับการแนะนำโดยRoy Fielding ในปี 2000 ในเอกสารของเขา Fielding Dissertations

URI และวิธีการ RESTful ให้ข้อมูลเกือบทั้งหมดที่เราต้องการในการดำเนินการตามคำขอ ตารางต่อไปนี้สรุปว่าควรใช้กริยาต่างๆอย่างไรและควรตั้งชื่อ URI อย่างไร เราจะสร้างภาพยนตร์ API ในตอนท้ายดังนั้นมาคุยกันว่าจะมีโครงสร้างอย่างไร

วิธี URI รายละเอียด ฟังก์ชัน
รับ /ภาพยนตร์ ปลอดภัยสามารถเข้าถึงได้ รับรายชื่อภาพยนตร์ทั้งหมดและรายละเอียด
รับ / movies / 1234 ปลอดภัยสามารถเข้าถึงได้ รับรายละเอียดของ Movie id 1234
โพสต์ /ภาพยนตร์ ไม่มี สร้างภาพยนตร์ใหม่พร้อมรายละเอียดที่ให้ไว้ การตอบกลับมี URI สำหรับทรัพยากรที่สร้างขึ้นใหม่นี้
วาง / movies / 1234 Idempotent แก้ไขรหัสภาพยนตร์ 1234 (สร้างใหม่หากยังไม่มี) การตอบกลับมี URI สำหรับทรัพยากรที่สร้างขึ้นใหม่นี้
ลบ / movies / 1234 Idempotent ควรลบ Movie id 1234 หากมีอยู่ การตอบกลับควรมีสถานะของคำขอ
ลบหรือวาง /ภาพยนตร์ ไม่ถูกต้อง ควรจะไม่ถูกต้อง DELETE และ PUT ควรระบุทรัพยากรที่กำลังทำงานอยู่

ตอนนี้มาสร้าง API นี้ใน Koa เราจะใช้ JSON เป็นรูปแบบข้อมูลการขนส่งของเราเนื่องจากใช้งานง่ายใน JavaScript และมีประโยชน์อื่น ๆ อีกมากมาย แทนที่ไฟล์ index.js ของคุณด้วยสิ่งต่อไปนี้ -

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);

ตอนนี้เราได้ตั้งค่าแอปพลิเคชันแล้วให้เรามีสมาธิในการสร้าง API ตั้งค่าไฟล์ movies.js ก่อน เราไม่ได้ใช้ฐานข้อมูลเพื่อจัดเก็บภาพยนตร์ แต่กำลังจัดเก็บไว้ในหน่วยความจำดังนั้นทุกครั้งที่เซิร์ฟเวอร์รีสตาร์ทภาพยนตร์ที่เราเพิ่มจะหายไป สิ่งนี้สามารถเลียนแบบได้อย่างง่ายดายโดยใช้ฐานข้อมูลหรือไฟล์ (โดยใช้โมดูลโหนด fs)

นำเข้า koa-router สร้างเราเตอร์และส่งออกโดยใช้ 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;

รับเส้นทาง

กำหนดเส้นทาง GET สำหรับการรับภาพยนตร์ทั้งหมด

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

แค่นั้นแหละ. หากต้องการทดสอบว่าใช้งานได้ดีหรือไม่ให้เรียกใช้แอปของคุณจากนั้นเปิดเทอร์มินัลแล้วป้อน -

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET localhost:3000/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}]

เรามีเส้นทางในการรับชมภาพยนตร์ทั้งหมด ตอนนี้มาสร้างเส้นทางเพื่อรับภาพยนตร์เฉพาะโดยใช้รหัส

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;
}

สิ่งนี้จะทำให้เราได้รับภาพยนตร์ตาม ID ที่เราให้ไว้ ในการทดสอบสิ่งนี้ให้ใช้คำสั่งต่อไปนี้ในเทอร์มินัลของคุณ

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

คุณจะได้รับคำตอบเป็น -

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

หากคุณเยี่ยมชมเส้นทางที่ไม่ถูกต้องจะทำให้เกิดข้อผิดพลาดไม่สามารถ GET ได้ในขณะที่หากคุณไปที่เส้นทางที่ถูกต้องโดยมีรหัสที่ไม่มีอยู่จะทำให้เกิดข้อผิดพลาด 404

เราทำเส้นทาง GET เสร็จแล้ว ตอนนี้ขอไปที่เส้นทาง POST

POST เส้นทาง

ใช้เส้นทางต่อไปนี้เพื่อจัดการข้อมูลที่โพสต์

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;
}

การดำเนินการนี้จะสร้างภาพยนตร์ใหม่และจัดเก็บไว้ในตัวแปรภาพยนตร์ หากต้องการทดสอบเส้นทางนี้ให้ป้อนข้อมูลต่อไปนี้ในอาคารผู้โดยสารของคุณ -

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

คุณจะได้รับคำตอบดังต่อไปนี้ -

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

หากต้องการทดสอบว่าสิ่งนี้ถูกเพิ่มลงในออบเจ็กต์ภาพยนตร์หรือไม่ให้เรียกใช้ get request for / movies / 105 อีกครั้ง คุณจะได้รับคำตอบดังต่อไปนี้ -

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

มาสร้างเส้นทาง PUT และ DELETE

PUT เส้นทาง

เส้นทาง PUT เกือบจะเหมือนกับเส้นทาง POST ทุกประการ เราจะระบุรหัสสำหรับวัตถุที่จะอัปเดต / สร้างขึ้น สร้างเส้นทางด้วยวิธีต่อไปนี้ -

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};
      }
   }
}

เส้นทางนี้จะทำหน้าที่ที่เราระบุไว้ในตารางด้านบน มันจะอัปเดตวัตถุด้วยรายละเอียดใหม่หากมีอยู่ หากไม่มีอยู่ก็จะสร้างวัตถุใหม่ ในการทดสอบเส้นทางนี้ให้ใช้คำสั่ง curl ต่อไปนี้ การดำเนินการนี้จะอัปเดตภาพยนตร์ที่มีอยู่ หากต้องการสร้างภาพยนตร์ใหม่เพียงแค่เปลี่ยนรหัสเป็นรหัสที่ไม่มีอยู่

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

การตอบสนอง

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

ลบเส้นทาง

ใช้รหัสต่อไปนี้เพื่อสร้างเส้นทางการลบ

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."};
   }
}

ทดสอบเส้นทางในแบบเดียวกับที่เราทำกับคนอื่น ๆ เมื่อลบสำเร็จ (เช่นรหัส 105) คุณจะได้รับ -

{message: "Movie id 105 removed."}

สุดท้ายไฟล์ movies.js ของเรามีลักษณะดังนี้ -

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;

เสร็จสมบูรณ์ REST API ของเรา ตอนนี้คุณสามารถสร้างแอปพลิเคชันที่ซับซ้อนมากขึ้นโดยใช้รูปแบบสถาปัตยกรรมที่เรียบง่ายนี้และ Koa

การบันทึกมีประโยชน์มากเมื่อสร้างเว็บแอปพลิเคชันเนื่องจากจะบอกเราว่าเกิดข้อผิดพลาดตรงไหน นอกจากนี้เรายังได้รับบริบทของสิ่งที่ผิดพลาดและสามารถหาทางแก้ไขที่เป็นไปได้สำหรับสิ่งเดียวกัน

ในการเปิดใช้งานการบันทึกใน Koa เราจำเป็นต้องมีมิดเดิลแวร์ koa-logger. ติดตั้งโดยใช้คำสั่งต่อไปนี้

$ npm install --save-dev koa-logger

ตอนนี้ในแอปพลิเคชันของคุณให้เพิ่มรหัสต่อไปนี้เพื่อเปิดใช้งานการบันทึก

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)

เรียกใช้เซิร์ฟเวอร์นี้และเยี่ยมชมเส้นทางใด ๆ บนเซิร์ฟเวอร์ คุณควรเห็นบันทึกเช่น -

ตอนนี้หากคุณได้รับข้อผิดพลาดในเส้นทางหรือคำขอที่เฉพาะเจาะจงบันทึกเหล่านี้จะช่วยให้คุณทราบว่ามีอะไรผิดพลาดในแต่ละรายการ

นั่งร้านช่วยให้เราสร้างไฟล์ skeleton for a web application. เราสร้างไดเรกทอรีสาธารณะของเราด้วยตนเองเพิ่มมิดเดิลแวร์สร้างไฟล์เส้นทางแยกต่างหาก ฯลฯ เครื่องมือนั่งร้านจะตั้งค่าสิ่งเหล่านี้ทั้งหมดให้เราเพื่อให้เราสามารถเริ่มต้นสร้างแอปพลิเคชันของเราได้โดยตรง

นั่งร้านที่เราจะใช้เรียกว่า Yeoman. เป็นเครื่องมือนั่งร้านที่สร้างขึ้นสำหรับ Node.js แต่ยังมีเครื่องกำเนิดไฟฟ้าสำหรับเฟรมเวิร์กอื่น ๆ อีกมากมาย (เช่นกระติกน้ำราง django ฯลฯ ) ในการติดตั้ง yeoman ให้ป้อนคำสั่งต่อไปนี้ในเทอร์มินัลของคุณ

$ npm install -g yeoman

Yeoman ใช้เครื่องกำเนิดไฟฟ้าเพื่อใช้งานแอพพลิเคชั่น เพื่อตรวจสอบเครื่องกำเนิดไฟฟ้าที่มีอยู่บน NPM เพื่อใช้งานร่วมกับองค์รักษ์, ตรงไปที่นี่ สำหรับจุดประสงค์ของบทช่วยสอนนี้เราจะใช้ 'generator-koa' ในการติดตั้งเครื่องกำเนิดไฟฟ้านี้ให้ป้อนคำสั่งต่อไปนี้ในเทอร์มินัลของคุณ

$ npm install -g generator-koa

ในการใช้เครื่องกำเนิดไฟฟ้านี้ให้ป้อน -

yo koa

จากนั้นจะสร้างโครงสร้างไดเร็กทอรีและจะสร้างไฟล์ต่อไปนี้ให้คุณ นอกจากนี้ยังจะติดตั้งโมดูล npm และส่วนประกอบ bower ที่จำเป็นสำหรับคุณ

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.

เครื่องกำเนิดไฟฟ้านี้สร้างโครงสร้างที่เรียบง่ายสำหรับเรา

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

สำรวจเครื่องกำเนิดไฟฟ้ามากมายสำหรับ Koa และเลือกเครื่องที่เหมาะกับคุณ ขั้นตอนในการทำงานกับเครื่องกำเนิดไฟฟ้าทั้งหมดเหมือนกัน คุณจะต้องติดตั้งเครื่องกำเนิดไฟฟ้าเรียกใช้โดยใช้ Yeoman มันจะถามคำถามคุณแล้วสร้างโครงกระดูกสำหรับแอปพลิเคชันของคุณตามคำตอบของคุณ

ต่อไปนี้เป็นรายการทรัพยากรที่เราใช้ขณะพัฒนาบทช่วยสอนนี้ -

  • Koajs.com

  • Koajs - ตัวอย่างรายการตัวอย่างที่สร้างโดยชุมชน

  • รายการอย่างเป็นทางการและ 3 ถ middlewares บุคคล

  • CRUD API โดยใช้ koa.js - screencast สั้น ๆ ที่จะต้องสร้าง CRUD API ใน Koa.js

  • หน้าจอเริ่มต้น Koa.js Quickstart

  • ข้อมูลเบื้องต้นเกี่ยวกับ Koa.js และเครื่องกำเนิดไฟฟ้า