hyphen คือ: คุณกำลังดูกระทู้
เนื้อหาต่อไปนี้ จะเป็นการทำความรู้จักกับ Routing ใน Express
รวมทั้งรูปแบบ และการใช้งานเบื้องต้น เพื่อเป็นแนวทางสำหรับ
เนื้อหาต่อๆ ไป เกี่ยวกับ Express
ต่อจากบทความ Express web framework เบื้องต้น http://niik.in/906
เรามาดูไฟล์ app.js ที่เราได้ทดสอบรันผ่าน บราวเซอร์มาแล้ว
const express = require('express') // ใช้งาน module express const app = express() // สร้างตัวแปร app เป็น instance ของ express const port = 3000 // port // ส่งกลับข้อความ "hello world" เมื่อมี GET request มายังหน้า homepage app.get('/', function (req, res) { res.send('hello world ') }) app.listen(port, function() { console.log(`Example app listening on port ${port}!`) })
Table of Contents
Routing คืออะไร
Routing คือการกำหนด URL หรือ Path ที่ใช้ในการเรียกข้อมูลผ่าน HTTP request เช่น
GET POST PUT หรือ DELETE แล้วให้ทำการ response หรือส่งกลับข้อมูลหรือการทำงานใดๆ
ให้สอดคล้องกับ URL ใดๆ ที่ระบุเข้ามา
การ response หรือส่งกลับข้อมูลด้วยการทำคำสั่งใดๆ นั้น เราสามารถกำหนดได้ว่า จะให้ทำคำสั่ง
เดียวหรือหลายคำสั่ง เมื่อผู้ใช้ request เข้ามายัง path และเข้าเงื่อนไขการทำงาน ยกตัวอย่าง
จากโค้ดด้านบน
app.get('/',function(){});
รูปแบบการกำหนด Route
app.METHOD(PATH, HANDLER)
โดย
app คือ instance ของ express (เข้าใจง่ายๆ “ฉัน (app)” คือตัวแทนของ express )
METHOD คือ HTTP request method ใช้เป็นตัวเล็ก หมายถึง ทำการเรียกข้อมูลผ่าน HTTP ด้วยวิธี
* get | post | put | delete
PATH คือ URL หรือ ส่วนของโดนเมนนับตั้งแต่ “/” ตัวที่ 3 เป็นต้นไป เช่น
*http://niik.in/forum จะได้ PATH คือ “/fourn” ถ้าเป็น Root PATH ก็คือ “/”
HANDLER คือฟังก์ชั่นที่กำหนดให้ทำงาน เมื่อ PATH ตรงกับค่าที่กำหนด
โค้ดด้านล่าง แสดงถึงการกำหนด Route อย่างง่าย โดย response หรือส่งกลับคำว่า “hello world”
ไปแสดงที่หน้าแรก หรือ homepage
// ส่งกลับข้อความ "hello world" เมื่อมี GET request มายังหน้า homepage app.get('/', function (req, res) { res.send('hello world ') })
Express ไม่เพียงแค่รองรับ GET POST PUT หรือ DELETE method แต่ยังสามารถรองรับ method ต่างๆ
ตามลิสรายการด้านล่าง โดยวิธีการทำงาน ก็จะสัมพันธ์กับชื่อที่ใช้เรียก Method นั้นๆ แต่อย่างไรก็ตาม
การใช้งานส่วนใหญ่เกือบทั้งหมด ก็จะเป็นการใช้งานใน 4 method ข้างต้น
Route methods
Route method นั้นถูกแปลงมาจาก HTTP method แล้วนำมาผูกเข้ากับ instance ของ express class
ตัวอย่างด้านล่าง คือโค้ดบางส่วนของการกำหนด route แบบ GET และ POST method ให้กับ Root ของ app
// GET method route app.get('/', function (req, res) { res.send('GET request to the homepage') }) // POST method route app.post('/', function (req, res) { res.send('POST request to the homepage') })
โดยเมื่อมี HTTP request ขึ้น ก็จะทำให้เกิด request object และ response object โดย object ทั้งสอง
เราสามารถนำเข้าไปใช้งานในฟังก์ชั่น เพื่อกำหนด หรือทำงานต่างๆ ต่อไปได้ ในโค้ดตัวอย่างใช้ตัวแปรอักษร
3 ตัวแบบย่อคือ req = request และ res = response
ตัวอย่าง ค่า req บางค่าก็เช่น req.url หรือ req.method เป็นต้น
ตัวอย่าง ค่า res บางค่าก็เช่น res.rawHeaders หรือ res.statusCode เป็นต้น
นอกจาก Method ต่างๆ ข้างต้นแล้ว ยังมี method พิเศษ ในการกำหนด Routing คือ app.all() ซึ่งใช้สำหรับ
กำหนดให้ทำงานใน middleware ฟังก์ชั่น หรือ ฟังก์ชั่นที่ใช้สำหรับจัดการกับ HTTP request ทุก method
ใดๆ ก็ตามที่เกิดขึ้น เข้าใจอย่างง่ายก็คือ สมมติเกิด GET request มาที่ “/” เราสามารถใช้ฟังก์ชั่น middleware
มาดักจับตัว request แล้วปรับปรุงเปลี่ยนแปลงค่าต่างๆ ก่อนที่ค่านั้น จะผ่านเข้ามาในฟังก์ชั่น HANDLER ของ
method นั้น ยกตัวอย่าง เราเพิ่มโค้ด การใช้งาน app.all() เข้าไปก่อนการ เรียกใช้ GET method ดังนี้
// ดักจับทุกๆ method app.all('/', function (req, res, next) { console.log('Accessing the secret section ...') res.myobj = 1; // สมมติเราเพิ่ม req property ที่ชื่อ myobj เท่ากับ 1 next() // ให้ไปทำงานต่อ handler ฟังก์ชั่นในลำดับถัดไป }) // ส่งกลับข้อความ "hello world" เมื่อมี GET request มายังหน้า homepage app.get('/', function (req, res) { console.log(res.myobj) // ทดสอบแสดงค่า ที่เราปรับแต่ง req res.send('hello world ') })
ดูผลลัพธ์
จะเห็นว่าข้อความ “Accessing the secret section …” ซึ่งอยู่ใน middleware function
ที่เรากำหนดเอง แสดงก่อน จากนั้น เราก็ทำการเพิ่ม property เข้าไปใน req object ชื่อ
myobj กำหนดค่า เท่า 1 เสร็จแล้วก็ใช้ฟังก์ชั่น next() เพื่อไปทำคำสั่ง ลำดับถัดไป
ซึ่งก็คือฟังก์ชั่นที่ทำงานเมื่อมี GET Request มาที่ “/” ก็จะแสดง req.myobj ค่าที่เราได้ปรับแต่ง
เพิ่มเติม ถูกส่งเข้ามา และแสดงผลออกทาง console ตามรูป นั่นก็หมายความว่า การดักจับการทำงาน
หรือการแทรกการทำงานด้วย middleware ฟังก์ชั่นข้างต้น สามารถทำงานได้
นอกจาก middleware ที่เรากำหนดแล้ว ยังมี middleware ฟังก์ชั่นอื่นๆ ที่เราสามารถเรียกใช้งานได้
ซึ่งจะได้รู้จักในลำดับต่อๆ ไป
Route paths
เราได้รู้จักเกี่ยวกับ route path บางส่วนไปแล้ว ซึ่งส่วนของ Path เป็นส่วนที่ใช้งานร่วมกับ
request method โดยสามารถกำหนดเป็น
stinrg เช่น “/” , “/about” , “/random.text” เป็นต้น
string pattern เช่น “/ab?cd” , “/ab+cd” , “‘/ab*cd'” เป็นต้น
regular expression เช่น /a/ , /.*fly$/ เป็นต้น
ตัวอักขระ ?, +, * และ () เป็นส่วนหนึ่งของรูปแบบ regular expression
สัญลักษณ์ (-) hyphen และ dot (.) เป็นส่วนหนึ่งของ string
สัญลักษณ์ ($) dollar sign สามารถกำหนดใน path โดยต้องไว้ในในเครื่องหมาย ([ และ ])
ยกตัวอย่าง เช่น เรียกไปที่ path “/data/$book” ต้องกำหนดเป็น “/data/([\$])book”
ตัวอย่างการกำหนด route path ในรูปแบบต่าง
รูปแบบ String
app.get('/', function (req, res) {}) // Root route: / app.get('/about', function (req, res) {}) // route: /about app.get('/random.text', function (req, res) {}) // route: /random.text
รูปแบบ String Pattern
app.get('/ab?cd', function (req, res) {}) // route: /acd และ abcd // เครื่องหมาย ? วางอยู่หลังตัวอักขระใดๆ หมายถึง ตัวนั้นๆจะมี หรือไม่มีก็ได้ app.get('/ab+cd', function (req, res) {}) // route: /abcd และ /abbcd และ /abbbcd...ไปเรื่อยๆ // เครื่องหมาย + วางอยู่หลังตัวอักขระใดๆ หมายถึง ต้องมีตัวนั้นๆ อย่างน้อย 1 หรือก็คือ มี b กี่ตัวก็ได้ app.get('/ab*cd', function (req, res) {}) // route: /abcd, /abxcd, /abRANDOMcd ...ไปเรื่อยๆ // เครื่องหมาย * วางอยู่ตำแหน่งใดๆ เหมือนถึงไม่มี หรือมีตัวอักษระใดๆ ก็ได้ app.get('/ab(cd)?e', function (req, res) {}) // route: /abe และ /abcde // เครื่องหมายวงเล็บใช้จัดกลุ่มของข้อมูล และใช้ร่วมกับเครื่องหมายอื่น ดังนั้นจึงหมายถึง มี cd หรือไม่ก็ได้
รูปแบบ Regular Expression
app.get(/a/, function (req, res) {}) // route: ทุกๆ path ที่มี "a" อยุ่ในนั้น เช่น // route: /about , /contact app.get(/.*fly$/, function (req, res) {}) // route: ทุกๆ path ที่ลงท้ายด้วย fly เช่น // route: /butterfly , /dragonfly
Route parameters
Route parameter หรือเรียกอีกอย่างหนึ่งว่า URL segments เป็นส่วนที่ใช้สำหรับเก็บค่าไว้ในตำแหน่งต่างๆ
ของ URL โดยค่าเหล่านี้ จะถูกเรียกใช้งานผ่าน req.params object กล่าวคือ โดยชื่อของ parameter
จะกำหนดเป็นชื่อ key ในรูปแบบ :[key ชื่อ parameter] เรียงตามลำดับ
Route path: /users/:userId/books/:bookId Request URL: http://localhost:3000/users/34/books/8989 req.params: { "userId": "34", "bookId": "8989" }
สังเกต ชื่อ parameter จาก URL ข้างต้น จะมีด้วยกัน 2 key คือ :userId และ :bookId
ในการกำหนด route path ที่มี route parameter ตามรูปแบบข้างต้น สามารถทได้ดังนี้
app.get('/users/:userId/books/:bookId', function (req, res) { res.send(req.params) })
ชื่อ parameter ต้องกำหนดเป็น ข้อความที่เป็นตัวเลขและตัวอักษรภาษาอังกฤษตามรูปแบบ
([A-Za-z0-9_]) ประกอบด้วยตัวพิมพ์เล็กหรือตัวพิมพ์ใหญ่หรือตัวเลขหรือสัญลักษณ์ _ (underscore)
สำหรับ hyphen (-) และ dot (.) สามารถใช้งานร่วมกับ route parameter เพื่อวัตถุประสงค์พิเศษ
บางอย่างได้ เช่น เชื่อม parameter 2 ตัวด้วย (-) หรือ (.) เข้าด้วยกัน
Route path: /flights/:from-:to Request URL: http://localhost:3000/flights/LAX-SFO req.params: { "from": "LAX", "to": "SFO" }
Route path: /plantae/:genus.:species Request URL: http://localhost:3000/plantae/Prunus.persica req.params: { "genus": "Prunus", "species": "persica" }
นอกจากนั้น เรายังสามารถใช้วงเล็บ () ต่อท้าย parameter ที่เราต้องการกำหนดรูปแบบของข้อมูลที่
จะใช้งานได้ เช่่น (\d+) คือ ต้องมีตัวเลข ตัวอย่างการกำหนดเพิ่มเติม
\d -- ตัวเลขทุกตัว 0 - 9 \D -- ตัวอักขระทุกตัว ยกเว้น เลข 0 - 9 \s -- ช่องว่างทุกตัว \S -- ตัวอักขระทุกตัว ยกเว้นช่องว่าง \w -- ตัวอักษร ตัวเลข ทุกตัว ยกเว้นตัวอักขระพิเศษ . \ + * ? [ ^ ] % $ ( ) { } = ! < > | : - \W -- ตัวขระพิเศษทุกตัว และช่องว่าง ยกเว้น ตัวอักษร และตัวเลข
ซึ่งกรณีมีการใช้งาน \ ใน regular expression ให้เราเพิ่มเป็น \\ เพราะถ้ามีตัวเดียว
จะถูกตีความว่าเป็น string ตัวหนึ่งเท่านั้น ทำให้ไมีมีการแปลงความหมายของค่ากำหนด
กล่าวคือ ถ้ากำหนดเป็น \d จะมอง \ และ d เป็น string ปกติทั่วไป แต่ถ้า กำหนดเป็น \\d
จะตีความหมายและแปลงเป็นเงื่อนไขว่า เป็นตัวเลขทุกตัว 0-9 แบบนี้เป็นต้น
app.get('/users/:userId(\\d+)', function (req, res) { res.send(req.params) })
Route handlers
Route handler หรือก็คือฟังก์ชั่นส่วนที่ทำงานเมื่อเข้าเงื่อนไข หรือ url ที่ผู้ใช้งานเรียกเข้ามา
ตรงกับรูปแบบที่เรากำหนด อย่างที่ได้เข้าใจไปบ้างแล้วในตอนต้นกริ่นนำว่า เราสามารถกำหนดให้ ทำ
ฟังก์ชั่นได้มากกว่า 1 ฟังก์ชั่น โดยใช้ middleware function เข้ามาช่วย โดยมีคำสั่ง next()
เพื่อส่งไปทำงานฟังก์ชั่นที่เหลือ
เราสามารถกำหนด route handler ในรูปแบบของฟังก์ชั่น ,อาเรย์ของฟังก์ชั่น หรือทั้งสองอย่างรวมกันก็ได้
ตัวอย่างด้านล่างเป็นรูปแบบฟังก์ชั่นเดี่ยว ที่เราเห็นตัวอย่างมาบ่อยแล้ว
รูปแบบฟังก์ชั่นเดียว
app.get('/example/a', function (req, res) { res.send('Hello from A!') })
รูปแบบหลายฟังก์ชั่น
app.get('/example/a', function (req, res, next) { req.myobj = 'Hello from A!' next() },function(req, res){ req.myobj += ' Again!!!' res.send(req.myobj) })
ฟังก์ชั่นแรก เรากำหนด req.myobj เท่ากับ ‘Hello from A!’ จากนั้นส่งต่อไปฟังก์ชั่นที่ สอง
โดยเพิ่มคำว่า ‘ Again!!’ เข้าไป เสร็จแล้ว ส่งออกไปแสดงหน้าบราวเซอร์ จะได้ผลลัพธ์ดังรูป
รูปแบบ array ของฟังก์ชั่น
var func_a = function(req, res, next) { req.myobj = 'A' next(); } var func_b = function(req, res, next) { req.myobj += ' B' next(); } var func_c = function(req, res) { req.myobj += ' C' res.send(req.myobj); } app.get('/example/a', [func_a,func_b,func_c])
รูปแบบผสมหลายแบบ
var func_a = function(req, res, next) { req.myobj = 'A' next(); } var func_b = function(req, res, next) { req.myobj += ' B' next(); } app.get('/example/a', [func_a,func_b],function (req, res, next){ req.myobj += ' C' next(); },function(req, res){ req.myobj += ' D' res.send(req.myobj); });
Response methods
ใน response นั้น (res – response object) จะมี method ที่ทำหน้าที่ส่งกลับข้อมูลมายังผู้ใช้งาน และสิ้นสุดการทำงาน
ของกระบวนการ request response ที่เกิดขึ้น ซึ่งถ้าไม่มีการใช้งาน method ในส่วนนี้ การ request จากฝั่งผู้ใช้ อาจจะ
มีอาการค้างหรือหยุดการทำงานไป
รายการ response method ที่ใช้บ่อย ประกอบไปด้วย
res.download()
ทำการดาวน์โหลดไฟล์ที่ต้องการ
res.download('/report-12345.pdf'); res.download('/report-12345.pdf', 'report.pdf'); res.download('/report-12345.pdf', 'report.pdf', function(err){ if (err) { // อาจจะส่งข้อความแจ้งว่า ดาวน์โหลดไม่สำเร็จ หรืออื่นๆ โดยใช้ res.send() } else { // ทำคำสั่งอื่นๆ เช่น นับจำนวนการดาวน์โหลด } });
// ตัวอย่างดาวน์โหลดโฟล์ app.js2 ซึ่งไม่มีไฟล์ดังกล่าง เป็นชื่อ mysavefile.txt app.get('/download',function(req, res){ res.download('app.js2','mysavefile.txt',function(err){ if (err) { // console.log(res.headersSent) console.log(err) console.log("Can't downlaod") res.send("Can't download file!") } else { console.log("file downloaed") } }) })
res.end()
จบการทำงาน โดยไม่ส่งค่าใดๆ กลับ
res.end(); res.status(404).end();
res.json()
ส่งกลับข้อมูลในรูปแบบ JSON string
res.json(null); res.json({ user: 'tobi' }); res.status(500).json({ error: 'message' });
res.jsonp()
ส่งกลับข้อมูลในรูปแบบ JSON string รองรับ JSONP
res.jsonp(null); // => callback(null) res.jsonp({ user: 'tobi' }); // => callback({ "user": "tobi" }) res.status(500).jsonp({ error: 'message' }); // => callback({ "error": "message" }) // ?callback=foo res.jsonp({ user: 'tobi' }); // => foo({ "user": "tobi" }) // กรณีกำหนด callback name เป็นชื่ออื่น app.set('jsonp callback name', 'cb'); // ?cb=foo res.status(500).jsonp({ error: 'message' }); // => foo({ "error": "message" })
res.redirect()
ลิ้งค์หรือเปลี่ยน path ไปยัง url ที่กำหนด เช่น
res.redirect('/foo/bar'); res.redirect('http://example.com'); res.redirect(301, 'http://example.com'); res.redirect('../login'); res.redirect('..'); // การย้อนกลับมา 1 path res.redirect('back'); // การย้อนกลับไป path ก่อนหน้า
res.render()
สร้าง HTML string จาก view template แล้วส่งออกมาแสดง เราจะได้ศึกษาเพิ่มเติม เกี่ยวกับ view template
res.send()
ส่งข้อมูลกลับมาแสดง โดยสามารถเป็น Buffer Object , String ข้อความ , Object และ Array เช่น
res.send(new Buffer('whoop')); res.send({ some: 'json' }); res.send('<p>some html</p>'); res.send([1,2,3]); res.status(404).send('Sorry, we cannot find that!'); res.status(500).send({ error: 'something blew up' });
res.sendFile()
ส่งไฟล์ หรือนำข้อมูลไฟล์มาแสดง Send a file as an octet stream
app.get('/about',function(req, res){ // ตัวอย่งแสดงไฟล์ about.html ที่อยู่ใน root // ซึ่งเวลาใช้งานจริง เราจะใช้ path module มาข่วย จะไม่กำหนดลักษณะนี้ // res.sendFile(path.join(__dirname+'/about.html')); // กรณีใช้ path module res.sendFile("C:\\projects\\expressjs\\about.html") })
res.sendStatus()
กำหนด status code และ ส่งข้อความแจ้ง เช่น
res.sendStatus(200); // มีค่าเท่ากับใช้คำสั่ง res.status(200).send('OK') res.sendStatus(403); // มีค่าเท่ากับใช้คำสั่ง res.status(403).send('Forbidden') res.sendStatus(404); // มีค่าเท่ากับใช้คำสั่ง res.status(404).send('Not Found') res.sendStatus(500); // มีค่าเท่ากับใช้คำสั่ง res.status(500).send('Internal Server Error')
ข้างต้น เป็น response method ที่เราจะได้เจอบ่อยๆ ในการใช้งาน express ยังมี method อื่นๆ อีก
รวมถึง method ที่กล่าวมายังมีรายละเอียด ที่เราต้องศึกษาเพิ่มเติมในลำดับต่อๆ ไป
app.route()
เราสามารถเชื่อมการทำงานให้กับ route เป็นฟังก์ชั่นต่อๆ กัน หรือที่เรียกว่า chain โดยการใช้งาน app.route()
ซึ่งจะช่วยลดขั้นตอนที่ซับซ้อนและป้องกันความผิดพลาดในการพิมพ์ เพราะบางครั้ง เรามีการกำหนด route path
ซ้ำๆ กันให้กับ method ต่างๆ ดังนั้น การกำหนด route path ที่เดียว แล้วกำหนด method แยกย่อยลงไป จะทำให้
ลดขั้นตอนการเขียนลงได้ ตามตัวอย่างด้านล่าง
app.route('/book') .get(function (req, res) { res.send('Get a random book') }) .post(function (req, res) { res.send('Add a book') }) .put(function (req, res) { res.send('Update the book') })
express.Router
ในการพัฒนา web app ที่มีความซับซ้อนหรือมีโครงสร้างการทำงานจำนวนมาก การกำหนด route path ไว้ในไฟล์ app.js
คงไม่ใช่วิธีที่ถูกต้องหรือเหมาะสม การสร้างไฟล์แยกเป็นอีก module หรือก็คือการสร้าง mini-app แยกย่อย แล้วค่อยนำมา
เรียกใช้งานในไฟล์หลัก จึงเป็นวิธีที่เหมาะสมที่ถูกนำมาใช้งาน
โดยเราสามารถใช้ express.Router class เพื่อสร้าง module หรือสร้างไฟล์ module ใหม่ ที่สามารถเชื่อมกับการจัดการ
ของฟังก์ชั่นใน route ตัว Router ที่เป็น instance ของ expressRouter ก็คือ middleware ตัวหนึ่งที่เราสามารถเรียกใช้งาน
ในไฟล์หลัก
ทดสอบ เพื่อทำควาเข้าไจ ตามลำดับดังนี้
ให้เราสร้างไฟล์ birds.js ไว้ใน root โฟลเดอร์ ที่เดียวกับ app.js แล้วกำหนดโค้ดตามตัวอย่างด้านล่าง
var express = require('express') // เรียกใช้งาน express mudule var router = express.Router() // กำหนด router instance ให้กับ express.Router class // เราใช้คำสั่ง use() เพื่อเรียกใช้งาน middleware function // middleware ที่กำงานใน router instance ก่อนเข้าไปทำงานใน route function router.use(function timeLog (req, res, next) { console.log('Time: ', Date.now()) next() }) // กำหนด route หลัก หรือ root route router.get('/', function (req, res) { res.send('Birds home page') }) // กำหนด route เพิ่มเติม router.get('/about', function (req, res) { res.send('About birds') }) module.exports = router // ส่ง router ที่เราสร้าง ออกไปใช้งานภายนอกไฟล์
จากนั้นมาที่ไฟล์ app.js เราจะทำการโหลด router module จากไฟล์ birds.js ที่เราสร้างมาใช้งาน โดยทำได้ดังนี้
const express = require('express') // ใช้งาน module express const app = express() // สร้างตัวแปร app เป็น instance ของ express const port = 3000 // port const birds = require('./birds') // ใช้งาน router module // เรีรยกใช้งานในรูปแบบ middlewar โดยใช้ use app.use('/birds', birds) // ส่งกลับข้อความ "hello world" เมื่อมี GET request มายังหน้า homepage app.get('/', function (req, res) { res.send('hello world ') }) app.listen(port, function() { console.log(`Example app listening on port ${port}!`) })
จะเห็นว่า เราสามารถกำหนด กี่ module เข้ามาก็ได้ โดยใช้ use()
ถ้าเราสังเกตดีๆ จะพบว่า ในไฟล์ app.js มีการกำหนด route path ของหน้าแรก app ไว้แล้ว คือให้แสดง hello world
แล้วทำไมในไฟล์ birds จึงมีการกำหนด root route path เหมือนกัน แล้ว จะมีการเรียกไปที่ path ไหนเมื่อเข้าหน้าแรก
คำตอบคือ ให้สังเกตจากการกำหนด path ของ router module ที่เราเรีรยกใช้ เรากำหนดเป็น
app.use('/birds', birds)
นั่นหมายความว่า router.get(‘/’) ในไฟล์ birds.js จึงหมายถึง path: /birds
และ router.get(‘/about’) ในไฟล์ birds.js จึงหมายถึง path: /birds/about
แล้วถ้าเราเปลี่ยนหน้า app.js เป็น
app.use('/', birds)
ลักษณะแบบนี้ คือเป็นการเปลี่ยน route path หลักไปที่ birds module ดังนั้น เมื่อเข้าหน้าแรก
จึงเข้าไปทำงานในไฟล์ birds.js แทน และไม่แสดงคำว่า hello worldl
ดูตัวอย่างผลลัพธ์ประกอบ
สมมติเราเปลี่ยนเป็น app.use(‘/’, birds) ก็จะได้หน้าแรกเป็นดังนี้
ในเนื้อหาตอนนี้ เราได้เข้าใจส่วนต่างๆ ของ Routing ไปพอสมควรแล้ว หวังว่าจะเป็นแนวทาง
สำหรับทำความเข้าใจในส่วนอื่นๆ เพิ่มเติมต่อไป
[NEW] การใช้ Nouns คำนามคืออะไร มีกี่แบบ กี่ประเภท การเปลี่ยนรูป เอกพจน์ พหูพจน์ | hyphen คือ – NATAVIGUIDES
การใช้ Nouns คำนามคืออะไร มีกี่แบบ กี่ประเภท การเปลี่ยนรูป เอกพจน์ พหูพจน์
เรียนภาษาอังกฤษ เรื่อง Noun การใช้คำนามในภาษาอังกฤษ การแยกคำนามออกเป็นประเภทต่างๆ เบื้องต้น และกฎการเปลี่ยนรูปคำนามเอกพจน์ ให้เป็นคำนามพูพจน์
Nouns หมายถึง คำที่ใช้เรียกชื่อคน สัตว์ และสิ่งของ ซึ่งนับจำนวนได้และนับจำนวนไม่ได้
หน้าที่ของ Nouns ที่สำคัญมีดังนี้
1. เป็นประธานของกิริยา (subject of Verb) จะอยู่หน้ากิริยา
ตัวอย่างประโยคภาษาอังกฤษ
– Horses eat grass.
2. เป็นกรรมของกิริยา (object of Verb) จะอยู่หลังกิริยา ซึ่งเป็นได้ทั้งกรรมตรง(direct object) และกรรมรอง
(indirect object)
ตัวอย่างประโยคภาษาอังกฤษ
– Horses eat grass. (กรรมตรง)
– John gives his friend a pen. (กรรมรอง)
3. เป็นกรรมของบุพบท (object of preposition) จะอยู่หลังคำบุพบท
ตัวอย่างประโยคภาษาอังกฤษ
– Mary talked to her children.
– John borrowed notebook from his friend.
4. ทำให้ประโยคมีความหมายสมบูรณ์ขึ้น โดยถ้าต้องการให้ประธานมีความหมายสมบูรณ์จะต้องอยู่หลัง Verb to be หรือ ถ้าต้องการให้กรรมมีความหมายสมบูรณ์ขึ้นต้องอยู่หลังกรรม
ตัวอย่างประโยคภาษาอังกฤษ
– Mary is a doctor.
– John chose this pen a birthday gift.
5. ประกอบนาม (noun adjunct) ทำหน้าที่เหมือนคำคุณศัพท์อยู่หน้านาม
ตัวอย่างประโยคภาษาอังกฤษ
– We will meet you at this coffee shop.
6. ขยายคำนาม ที่เป็นประธานและเป็นกรรม โดยขยายประธานจะอยู่หลังคำนามที่เป็นประธาน และขยายกรรม
จะอยู่หลังคำนามที่เป็นกรรมของประโยค
ตัวอย่างประโยคภาษาอังกฤษ
– Sombat, a famous actor, plays tennis.
– We visited Chiangmai , the North of Thailand.
Compound Nouns
Compound Nouns หมายถึง คำนามที่เกิดจากการประสมคำตั้งแต่ 2 คำขึ้นไป ได้แก่
1. คำนามประสมที่เกิดจากผสมคำนาม 2 คำ มีลักษณะเป็นคำเดียวเขียนติดกันหรือมี hyphen – คั่น เมื่อเป็นพหูพจน์ให้เปลี่ยนเฉพาะนามตัวหลังตามกฎเท่านั้น
ตัวอย่างเช่น girlfriend เปลี่ยนเป็นพหูพจน์เป็น girlfriends
2. คำนามประสมที่เกิดจากการผสมคำนามกับคำอื่น ๆ เช่น
adjective + noun.
noun + preposition + noun.
จะมีลักษณะเป็นคำเดียวเขียนติดกันหรือมี hyphen – คั่น
เมื่อเป็นพหูพจน์ให้เปลี่ยนเฉพาะคำนามตามกฎเท่านั้น
ตัวอย่างเช่น
adjective + noun : gentleman เป็น gentlemen
noun + preposition + noun. : father-in-law เป็น fathers-in-law
หลักการเปลี่ยนรูปคำนามจากเอกพจน์เป็นพหูพจน์
1. ถ้าเป็นคำนามทั่วไป จะต้องเติม s
2. คำนามที่ลงท้ายด้วย ch , sh , s , ss, x และ z ต้องเติม es
3. คำนามที่ลงท้ายด้วย o หน้า o เป็นพยัญชนะต้องเติม es
4. คำนามที่ลงท้ายด้วย y หน้า y เป็นพยัญชนะ ให้เปลี่ยน y เป็น I แล้วเติม es แต่ถ้าเป็นคำนามที่ลงท้ายด้วย y แต่หน้า y เป็นสระให้เติม s
5. คำนามที่ลงท้ายด้วย f ,fe ให้เปลี่ยนเป็น ves
6. คำนามที่ต้องเปลี่ยนรูปเมื่อเป็นพหูพจน์ ได้แก่
– woman เปลี่ยนเป็น women
– tooth เปลี่ยนเป็น teeth
– mouse เปลี่ยนเป็น mice
– child เปลี่ยนเป็น children
7. คำนามที่เป็นชื่อเฉพาะ เมื่อเป็นพหูพจน์ต้องเติม s
8. ตัวอักษร , ตัวเลขเดี่ยว เมื่อเป็นพหูพจน์ต้องเติม ’s
9. อักษรตัวย่อและปี ค.ศ. เมื่อเป็นพหูพจน์ต้องเติม ’s หรือ s ซึ่งปัจจุบันนิยมใส่ s เท่านั้น
10. คำนามต่อไปนี้มีรูปเหมือนกันทั้งเอกพจน์และพหูพจน์ เช่น
– deer = deer
– swine = swine
– salmon = salmon
– aircraft = aircraft
– species = species
11. คำนามต่อไปนี้ไม่เปลี่ยนรูปเป็นพหูพจน์เมื่อมีจำนวน
นับประกอบข้างหน้า เช่น
dozen stone
gross head
foot hundredweight
hundred thousand
million score
12. คำนามบางคำเมื่อใช้ประกอบนามอีกตัวหนึ่ง แม้จะมีความหมายเป็นพหูพจน์ เช่น a two-foot animal
13. คำนามที่มีรูปเอกพจน์ แต่มีความหมายเป็นพหูพจน์ เช่น
people(ประชาชน) police(ตำรวจ)
minority(คนส่วนน้อย) gentry(พวกผู้ดี)
14. คำนามที่มีรูปพหูพจน์ แต่มีความหมายเป็นเอกพจน์ เช่น
news(ข่าว)
works(ผลงาน)
15. คำนามที่มีรูปพหูพจน์ และมีความหมายเป็นพหูพจน์ เช่น
clothes(เสื้อผ้า)
goods (สินค้า)
16. คำนามบอกสัญชาติที่ลงท้ายด้วย ss , se นามเอกพจน์ และนามพหูพจน์จะใช้รูปแบบเดียวกัน เช่น
นามเอกพจน์ ใช้ a Swiss
นามพหูพจน์ ใช้ six Swiss
How to Correctly Use Hyphens in English (-)
https://bit.ly/3nFoX3j ← Learn English for everyday life with your free PDF Lessons
https://bit.ly/3pepKc6 ← Ask Alisha your question now! ↓Check how below↓
To send your question to Alisha it’s simple and will take you less than 30 seconds.
Step 1: Go to https://bit.ly/3pepKc6
Step 2: Sign up for a Free Lifetime Account
Step 3: Ask any question to Alisha and get your question answered in a video!
In this video, Alisha answers 5 questions.
What’s the difference between so and so that?
The word \”congratulations\”\” is used on big occasions. What should we say to a person who bought new shoes directly from the seller? Or other exciting event?
Hi Alisha, what’s the difference between \”no way\” and \”impossible\”?
What is the difference between rich and wealthy?
I would like to know when do use the hyphen in some words
You’ve got questions about life in the United States, American culture, or any English related questions you don’t want to sift through textbooks for the answer? Your favourite English teacher Alisha takes the questions you’ve been asking and lay them out in an easytofollow format. Turn those question marks into exclamation points and get on with your English study. Interact with Alisha to clear up any confusion you have or just satisfy your curiosity. Not only you’ll be able to send questions but also power up your language with your free lifetime account. Learning English is made easy for you.
Follow and write to us for more free content:
■ Facebook: https://www.facebook.com/EnglishClass101
■ Twitter: https://twitter.com/EnglishClass101
■ Instagram:: https://www.instagram.com/wwwEnglishClass101com
■ Alisha’s Twitter: https://twitter.com/arishaintokyo
■ Alisha’s Instagram: https://instagram.com/arishaintokyo
English LearnEnglish EnglishClass101 EnglishLesson
นอกจากการดูบทความนี้แล้ว คุณยังสามารถดูข้อมูลที่เป็นประโยชน์อื่นๆ อีกมากมายที่เราให้ไว้ที่นี่: ดูเพิ่มเติม
Grammar 102 07 Hyphens
A hyphen () is a punctuation mark that’s used to join words or parts of words.
Hyphens signal words that work together for a single purpose.
Soninlaw
rockforming minerals
checkin
[4K] 엔하이픈 ENHYPEN ‘Tamed-Dashed’ 뮤직뱅크 1위 앵콜 직캠 (ENHYPEN Encore Fancam)│@MusicBank 211022
ENHYPEN Tamed_Dashed 뮤직뱅크 엔하이픈
More from KBSKPOP
Twitter: https://twitter.com/StudioK_twit
ENHYPEN (엔하이픈) ‘Tamed-Dashed’ Official MV
ENHYPEN (엔하이픈) ‘TamedDashed’ Official MV
Credits:
Director: Yong Seok Choi (Lumpens)
CoDirector: Jihye Yoon (Lumpens)
Assistant Director: Ran Ro (Lumpens)
PA: Hye Jeong Park, Hye Jin Jang
Producer: Emma Sungeun Kim (GE Production)
Location Manager: Taesu Kim
Assistant Location Manager: Wonsun Yoon
Production Assistant: Hyoseok Kim, Seungwon Choi
Director of Photography: EumKo
B Cam Operator: Sangwoo Yun
Focus Puller: Sungju Min, Sungyun Jo
2nd AC: Eunil Lee, Eunki Kim
DIT: Yuntae Ko
3rd AC: Youngseo Park
Gaffer: Hyunsuk Song(Real Lighting)
Lighting Crew: Junghyun Choi, Uigyu Hwang, Chanbin Sung, Gyutae Park, Hyeongrae Lee, Yeonghwan Park, Wigeon Yoo, Choi Ung
Unit B: Lee Yuseok, Choi Hyeon, Kim Mingyu, Lee Wongyu
Production designer, Art Director: Bona Kim, Jinsil Park (MU:E)
Assistant Art team: Yeri Kang, Jieun Yoon, Ayeong Choi (MU:E)
Artteam Manager: ilho Heo (MU:E)
Jimmy Jib Operator: Dongjin Lee, Gwangho Song
Jimmy Jib Assistant: Hojun Choi, Jeonghyun Yoo, Daihwa Choi
VFX: Plastic Beach
VFX Supervisor: Ohzeon
VFX Assistant Supervisor: Jojeem
VFX Project Manager: Chanyoung Song / Jieun Jeong
VFX Producer: Kyutae Jang / Sohyun Ahn
3D Artist: Kwangwon Lee, KIM Doyeon Kim, Jeonghwa Lee, Jiwon Jeon, Hyeji Kim
2D Artist: JANG Gihoon Jang, Hyunjun Lee, Yeonsung Shin
FX Artist: Jungjin We
Visual Creative: Gunhee Lee, Ara Choi
Brand Experience Design: Soyeon Sung, Min Ji Kim
DARK MOON with ENHYPEN
ⓒ BELIFT LAB Inc. All Rights Reserved
Connect with ENHYPEN
OFFICIAL WEBSITE https://ENHYPEN.com
ENHYPEN Weverse https://www.weverse.io/enhypen
OFFICIAL V LIVE https://channels.vlive.tv/9A0CA5
OFFICIAL YOUTUBE https://www.youtube.com/ENHYPENOFFICIAL
OFFICIAL TWITTER https://twitter.com/ENHYPEN
ENHYPEN TWITTER https://twitter.com/ENHYPEN_members
OFFICIAL FACEBOOK https://www.facebook.com/officialENHYPEN
OFFICIAL INSTAGRAM https://www.instagram.com/enhypen
OFFICIAL TIKTOK https://www.tiktok.com/@enhypen
OFFICIAL WEIBO https://weibo.com/ENHYPEN
OFFICIAL JAPAN TWITTER https://twitter.com/ENHYPEN_JP
ENHYPEN DIMENSION_DILEMMA Tamed_Dashed
บั๊กสุดแปลก แค่พูด Hyphen หน้าจอ iPhone ก็ดับ! รีสปริงเฉยเลย อะไรเนี่ย! บั๊กตลก + ประหลาด
บั๊กประหลาดใหม่ล่าสุดใน iOS 12 ที่แค่พูดสั้นๆ ก็ทำให้จอดับเฉย แถมเครื่องยังรีสปริงอีกต่างหาก ทำเองได้ ไม่อันตราย ไปชมกันครับ
ห่างหายจากบั๊กตลก อาการประหลาดบน iOS ไปซะนาน จากก่อนหน้าเรามีบั๊กตัวอักษรอินเดียที่ทำให้เครื่องเดี้ยงไปเลย หรือการส่งข้อความแปลกๆ การแตะแล้วลากให้เบรอในหน้าจอ Widget แล้วกดปุ่ม Home ทำให้เครื่องรีสปริง ซึ่งอาการล่าสุดนี้ก็ยังเป็นอยู่ใน iOS 12 จนถึง iOS 12.2 ตัวล่าสุด
วันนี้มีการเจอบั๊กตลก อาการประหลาดบน iOS 12 อีกแล้วครับ ซึ่งใน iOS 12 ก็ยังเป็นอยู่ เป็นบั๊กที่ดูแล้วต้องร้องว้าย เอ้ย พูดไม่ออก บอกไม่ถูก แต่เวลาที่จะทำให้เกิดบั๊กนี้ เราต้องพูด ใช่ครับ แค่พูด ก็เกิดบั๊กกันเลยทีเดียว อะไรจะขนาดนั้น 🍎
😍 แท็บชุมชนของสอนใช้ง่ายนิดเดียว : http://bit.ly/communityyoutube
สอนใช้ง่ายนิดเดียว
iOS12บั๊กHyphen
iOSบัีกตลกบวกประหลาด
😁 ถ้าเพื่อนๆ ดูคลิปนี้แล้วถูกใจ ช่วยกด Like กด Share กด \”Subscribe\”
ด้วยนะครับ แล้วมา \”คอมเมนต์\” คุยกันครับ 🙏❤️
✍️ อย่าลืมกดติดตาม เพื่อไม่พลาดเนื้อหาใหม่ๆ ทุกวันนะครับ 🙏❤️ https://goo.gl/LnkBtv
📧 ติดต่อเรื่องงาน [email protected]
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
เนื้อหาอื่นๆ ที่น่าสนใจสำหรับ iPhone, iPad และ iPod touch
🌟 ลืมรหัสผ่าน Apple ID ของ iPhone และ iPad รีเซ็ตตั้งใหม่ได้ใน 1 นาที! : https://youtu.be/KKjZ3QQPTbI
🌟 [2018] วิธีแก้ล็อค ปลดล็อค iPhone / iPad ติดรหัสผ่าน ง่ายๆ ทำเองได้ ไม่เสียตังค์ : https://youtu.be/5gFO8Q9k6M
🌟 5 เรื่องที่ Apple ไม่ได้บอกเกี่ยวกับ iPhone XR! : https://youtu.be/Pgz01WELGXc
🌟 24 ฟีเจอร์เด่น ฟีเจอร์ใหม่ของ iOS 12 ตัวเต็ม บน iPhone ที่ทำให้ต้องอัพเดต! https://www.youtube.com/watch?v=gtaeQaQbLlk
🌟 21 วิธีแก้ iOS 11 แบตหมดไว กินแบต ประหยัดขึ้น | สอนใช้ง่ายนิดเดียว https://youtu.be/HvquCv8wOf0
🌟 แบตเตอรี่ iPhone เสื่อมรึยัง เช็คข้อมูลแบตเตอรี่ครบทุกเรื่องฟรีใน 1 คลิก : https://youtu.be/Fa8hXSEVAiA
🌟 4 วิธีชาร์จแบตเตอรี่ iPhone ให้เร็วขึ้น แบตเต็มไว ทำเองได้ง่ายๆ : https://youtu.be/tS2Hh9V6orE
🌟 6 วิธีรีเซ็ตเครื่อง วิธีการ Reset iPhone และ iPad พบปัญหาการใช้ แก้ไขได้ง่ายๆ ด้วยตัวเอง : https://youtu.be/Pqq1cv767Fo
นอกจากการดูบทความนี้แล้ว คุณยังสามารถดูข้อมูลที่เป็นประโยชน์อื่นๆ อีกมากมายที่เราให้ไว้ที่นี่: ดูบทความเพิ่มเติมในหมวดหมู่MAKE MONEY ONLINE
ขอบคุณมากสำหรับการดูหัวข้อโพสต์ hyphen คือ