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 และเครื่องกำเนิดไฟฟ้า