เข้าใจการทำหลังบ้านกับคอร์ส Express.js Crash Course

Learning Mar 5, 2021

ตอนนี้ทยอยเรียนคอร์สของ PasaComputer มาจนสุดสายของฝั่งหลังบ้านแล้วเนอะ

คอร์สที่ควรเรียนก่อนก็จะมี JavaScript Crash Course, Functional Programming in JavaScript และ Node.js Crash Course เราสรุปไว้แต่ละคอร์สดังนี้

เรียน JavaScript for Beginner กับคอร์สในชุด Crash Course Series
ก่อนหน้านี้เราได้เรียนคอร์ส JavaScript 21 Days Challenge กับทาง PasaComputer มาแล้ว และในตอนนี้ก็มีคอร์สที่เริ่มต้นศึกษา JavaScript ตั้งแต่เริ่มต้น บวกกับการเขียน React ในชุด Crash Course Series
https://www.mikkipastel.com/javascript-for-beginner-crash-course-series/
เรียน Node.js Crash Course แบบฟรีๆ เพื่อความเข้าใจที่มากขึ้น
ในยุคสมัยนี้ก็ใช้ Node.js มาหลังทำบ้านกัน ทางเราเองก็ไม่เคยเรียนมาก่อน แต่ดันมาทำ chatbot และใช้งาน Firebase Cloud Function จึงต้องเรียนรู้พื้นฐานมันก่อน
https://www.mikkipastel.com/node-js-crash-course/

มาดูกันว่าเราจะเรียนอะไรกันบ้างในคอร์สนี้

  • What is Express? Express คืออะไร แล้วทำไมเราต้องใช้
  • Routes บอกว่าถ้า browser ส่ง request มา เราจะตอบกลับมันอย่างไร
  • Requests & Responses request บอกข้อมูลที่ browser ส่งมาให้เราใช้ต่อ ส่วน response บอกวิธีการตอบกลับ request เหล่านั้น
  • Middleware เป็น concept ที่สำคัญ ทำให้เราแปลงข้อมูลต่างๆได้ รวมถึงอ่านข้อมูลที่ user ส่งมาได้
  • Template Engines เป็นตัวที่เราสร้างหน้า page HTML จาก data ที่เรามีได้

จบคอร์สเราก็สามารถเขียน API ได้ และสร้างเว็บเพจของตัวเองได้

สามารถเข้าไปเรียนที่ Skooldio ได้เลย ตามลิ้งด้านล่างนี้

Express.js Crash Course
skooldio
https://www.skooldio.com/courses/expressjs-crash-course

เอ้อออ แล้วถามสงสัยว่า API คืออะไร ทำงานยังไง ลองอ่านบล็อกนี้ของพี่เนยดูนะ ตอบครบจบทุกอย่าง เข้าใจได้ง่ายๆเลยจ้า

NuuNeoI - โครงสร้างพื้นฐาน(มาก)ของการติดต่อแอป ฯ กับ Database ฝั่ง Server สำหรับผู้เริ่มต้น
ทุกวันนี้ทำแอป ฯ แค่ Offline มันไม่พอแล้ว เพราะแอป ฯ ที่นิ่งเฉยไม่มีอะไรเปลี่ยนแปลงผู้คนจะใช้แค่ครั้งสองครั้งแล้วก็เลิก ดังนั้นไม่ต้องแปลกใจที่แอป ฯ เกือบทั้งหมดที่เราใช้ทุกวันนี้จึงเป็นแอป ฯ แบบ Onli
https://nuuneoi.com/blog/blog.php?read_id=906

What is Express?

คือ web application framework สำหรับ Node.js มีขนาดเล็ก ทำงานได้รวดเร็ว ไม่บังคับว่าต้องใช้อะไรแก้ไขปัญหา มีอิสระในการทำ สิ่งที่นำไปใช้คือ สร้าง web application และสร้าง API สร้างหลังบ้าน ซึ่งเป็นที่นิยมกว่า เพราะตัวเว็บหน้าบ้านมักจะใช้ Angular, React และ Vue.js กัน และเป็นการแยกส่วนหน้าบ้านและหลังบ้านออกจากกันด้วย โดยฝั่งหน้าบ้านเรียก API ที่สร้างด้วย Express ไปใช้

แล้วทำไมถึงเป็นที่นิยมมากหล่ะ? เพราะว่าข้อดีมีเยอะมาก มีขนาดที่เล็กมาก ใช้งานง่าย ทำงานได้รวดเร็ว มีอิสระในการทำงาน ใช้บน Node.js ทำให้คนเขียน JavaScript เป็นนั้น นำไปประยุกต์ใช้ในส่วนของหลังบ้านได้ และ microservice สามารถสร้าง API ย่อยๆแยกกันอย่างชัดเจน ทำให้จัดการตัวโครงสร้างได้ง่ายขึ้น และ maintain ได้ง่าย และหลายๆบริษัทก็นำไปใช้งาน เช่น Uber Twitter IBM PayPal

Getting Started with Express

  • install Node.js กันก่อน
  • เราจะใช้ editor ยอดนิยมที่ชื่อว่า VS Code
  • ใช้โปรแกรม Postman ในการยิง API ของเรา (โปรแกรมนี้ควรมีติดเครื่องไว้นะทุกคน ใช้ทั้งหน้าบ้านและหลังบ้านเลย)
  • สร้าง project เปล่า ซึ่งก็ไม่มีอะไรข้างใน จากนั้นสร้าง package.json โดยพิมพ์ npm init
  • install package ของ Express กันโดย npm install express --save
  • install package ของ nodemon โดย npm install nodemon --save-dev ทำให้ restart server ให้เราอัตโนมัติเมื่อเรา save file code ของเรา จากนั้นไปแก้ scripts ใน package.json ดังนี้
{
  "name": "express.js-crash-course",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "^2.0.7"
  }
}
  • สร้าง index.js เป็นไฟล์ใช้ run server
  • import Express เข้ามา
const express = require('express');
  • สร้างตัวแปรนึง โดยจะ return object ของแอพออกมา และมีหลายๆ methos ให้เราเลือกใช้
const app = express();
  • สร้าง server โดยใส่ port ที่เราต้องการ และ callback ลงไป
app.listen(3000, () => {
    console.log('Listening to port 3000');
});
  • จากนั้นเราจะทำการ start server โดย npm start
  • กลับมาดูที่ browser หน่อย ตัว server ของเรารันแล้ว แต่ไม่เจอหน้า home page ของเราเนอะ
  • จากนั้นเราจะสร้างหน้า home page ขึ้นมา โดยใช้ get() ซึ่งเป็น method ตัวนึงในการสร้าง api เมื่อทำการยิงจากการพิมพ์ url จากหน้า browser จะมาเข้า method นี้
app.get('/', (req, res) => {
    //TODO
});

เมื่อ save แล้วไปดูหน้า browser ตอนนี้ทำงานได้หล่ะ แต่จะยังหมุนอยู่ เพราะยังไม่ได้ใส่ใส้ใน callback นะ

จากนั้นใส่ให้แสดง text เพิ่มออกมาในหน้าเว็บ

app.get('/', (req, res) => {
    res.send('<h1>Hello Express</h1>');
});

จะได้ดังนี้

Basic Routing

Routes นั้น build-in กับตัว Express เลย ใช้เพื่อบอกว่า เราต้องการต่อ request ในรูปแบบไหน

RESTful API

REST ย่อมาจาก REpresentational State Transfer เป็น guideline ในการสร้าง API ผ่าน HTTP protocol มีคุณสมบัติอะไรบ้าง? จะต้องมี CRUD อันได้แก่ Create (สร้าง), Read (อ่าน), Update, Delete (ลบ)

CRUD operation เวลาเอาไปใช้ยิง request จะแบ่งเป็น method ของ RESTful API ดังนี้

  • Create -> POST
  • Read -> GET
  • Update -> PUT
  • Delete -> DELETE

เช่น สร้างแอพสั่งอาหาร ระบบจะต้องรองรับในการแสดงร้านค่า เพิ่มลบข้อมูลร้านค้าต่างๆ

  • POST /apis/restaurants สร้างร้านค้าใหม่
  • GET /apis/restaurants ดึงร้านค้าทั้งหมดมาแสดง
  • GET /apis/restaurants/1 ดึงเฉพาะร้านอาหารที่มี id = 1 ร้านเดียว
  • PUT /apis/restaurants/1 อัพเดตข้อมูลร้านอาหาร โดยเราจะอัพเดตร้านเดียว คือร้านที่มี id = 1 เนอะ
  • DELETE /apis/restaurants/1 ลบข้อมูลร้านอาหาร โดยเราจะลบร้านที่มี id = 1 ร้านเดียว เหมือนของ PUT เลย
ตาม convention แล้วจะขึ้นต้นเป็น /apis

จากนั้นเราจะมาสร้าง RESTful API แต่ละตัวกันดีกว่า

GET Method

parameter แรกใส่ route path เข้าไป แล้วตามด้วย callback โดยในบทนี้จะสร้าง callback แบบง่ายๆกันก่อนจ้า

app.get('/apis/restaurants', (req, res) => {
    res.send('GET API');
});

POST Method

app.post('/apis/restaurants', (req, res) => {
    res.send('POST API');
});

การทดสอบเราจะใช้ Postman เพราะตัว POST มักจะให้เราแนบ Body เข้าไปด้วยเนอะ

PUT Method

เรารับ id ของ restaurants โดยใส่เป็น : ตามด้วยชื่อตัวแปร

app.put('/apis/restaurants/:id', (req, res) => {
    res.send('PUT API');
});

จากนั้นเราจะทำการททดสอบผ่าน Postman เหมือนเดิม

DELETE Method

app.delete('/apis/restaurants/:id', (req, res) => {
    res.send('DELETE API');
});

GET with Parameters

app.get('/apis/restaurants/:id', (req, res) => {
    res.send('GET ONE API');
});

Express Router

ถ้าเรามี API โค้ดเราจะมั่วมากเลย ดังนั้นควรย้ายไปอยู่ในไฟล์ใหม่ซะ โดยสร้าง folder ชื่อว่า routes และไฟล์ใหม่ชื่อว่า restaurants.js

ก่อนอื่น import Express

const express = require('express');

สร้างตัวแปร router ใช้ในการ set route ต่างๆ

const router = express.Router();

เอาตัว api ที่ทำเมื่อกี้ไปในไฟล์นี้เลย แล้วเปลี่ยนตัว app ให้เป็น router

outer.get('/apis/restaurants', (req, res) => {
    res.send('GET API');
});

router.get('/apis/restaurants/:id', (req, res) => {
    res.send('GET ONE API');
});

router.post('/apis/restaurants', (req, res) => {
    res.send('POST API');
});

router.put('/apis/restaurants/:id', (req, res) => {
    res.send('PUT API');
});

router.delete('/apis/restaurants/:id', (req, res) => {
    res.send('DELETE API');
});

และ export ออกมา เพื่อเอาไปใช้ที่อื่นต่อ

module.exports = router;

กลับมาที่ index.js เรา import restaurants.js เข้ามา

const restaurantsRouter = require('./routes/restaurants');

นำมาใช้งาน โดยใช้ use() ข้างในใส่ url ของเรา ตามด้วยตัว router ของเรา ถ้า api ขึ้นต้นด้วยอันนี้และ match กันก็จะเรียกอันนี้ไปใช้งาน

app.use('/apis/restaurants', restaurantsRouter);

และลบ route เดิมใน restaurants.js ออก โค้ดทั้งหมดจะเป็นแบบนี้

สุดท้ายมันจะต้องทำงานได้ถูกต้องเนอะ

Requests & Responses

ทุกๆ request ที่ส่งเข้าไปใน server นั้น ก็จะมี object ของ request และ response อยู่

Request เป็น Object ที่ประกอบด้วยข้อมูลที่เราส่งไปหา server โดยมี property ต่างๆให้เราอ่านข้อมูลได้ เช่น

  • req.params อ่านข้อมูลตัว variable ที่เรา set ให้กับตัว route เช่น ที่เราทำไปเมื่อกี้ ที่เป็น /:id
  • req.query อ่านข้อมูลของ query string ที่ user ส่งเข้ามาผ่าน url
  • req.body การอ่านข้อมูลที่ user ส่งมาผ่าน request body

Response ก็จะมี method ต่างๆในการส่งข้อมูลกลับไปหา client ได้

  • res.send() ส่งข้อมูลปกติไปหา client
  • res.sendFile() ใช่ส่งไฟล์
  • res.sendStatus() set http status code ต่างๆ เช่น ยิง request มาหาข้อมูลอันนี้ แล้วไม่พบในระบบ จะส่ง 404 ไป, ถ้า user ไม่ได้ login ก็จะส่ง 401 หรือถ้า user นั้นไม่มีสิทธิ์เข้าถึงข้อมูลตรงนี้ก็จะส่ง 403 ไป

ถ้าอยากเข้าใจเพิ่มเติม ดูที่นี่ได้เลยจ้า ดูหน้าน้องก็น่าจะเก็ทได้ไม่ยาก

HTTP Cats
API for HTTP Cats
https://http.cat/
  • res.json() ส่งข้อมูล json กลับไปหา client และเป็นที่นิยมมากที่สุดในปัจจุบัน

Implementing Requests & Responses

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

จากนั้นเรา import ตัว data เมื่อกี้เข้ามาในโปรเจก และให้ get() send data กลับไปเป็น json โดย res.json() แปลงข้อมูลเป็น json ให้เรา

const restaurants = require('../data');

router.get('/', (req, res) => {
    res.json(restaurants);
});

ผลที่ได้ เราก็จะได้ api ที่นำไปใช้งานได้ 1 ตัวล้าวนะ

จากนั้นทำ get() ที่รับ parameter มา โดย parameter ที่ได้มานั้นจะเป็น String ดังนั้นเราจะมาแปลงเป็น Int ก่อน เนื่องจากตัว id เป็น Int เนอะ และ parameter ตัวที่ 2 ของ Number.parseInt ใส่เลข 1o เนาะ เพราะเป็นเลขฐาน 10 แล้วก็นำ id ที่ได้ไป search หาในก้อนว่ามีไหม

router.get('/:id', (req, res) => {
    const restaurantId = Number.parseInt(req.params.id, 10);
    const restaurant = restaurants.find(
        (restaurant) => restaurant.id === restaurantId
    );
    res.json(restaurant);
});

ถ้ามีก็แสดงออกมาเป็นก้อน json แบบนี้

ถ้า id นั้นไม่มีหล่ะ? ถึงจะได้ 200 ก็ตาม ก็จะได้เปล่าๆออกมางี้ (อันนี้คนสอนไม่ได้บอกแหละ แต่คิดว่าน่าจะส่ง 204 หรือเปล่านะ เพราะทำงานสำเร็จ แต่หาไม่เจองาย)

แล้วก็ไปที่ delete() กันต่อเลย

ก่อนอื่นเราจะหาว่า id นี้อยู่ index ที่เท่าไหร่ จากนั้นนำเลข index ที่ได้เอาไปลบ data ออกจาก array และลบกี่ตัว ในที่นี้ลบตัวเดียวก็ใส่ 1 เนอะ และเราไม่มี data ส่งกลับไปให้ client ดังนั้นเราจะส่ง 204 เพราะ ทำงานเสร็จสมบูรณ์ ไม่มีอะไรส่งกลับไปให้ client

router.delete('/:id', (req, res) => {
    const restaurantId = Number.parseInt(req.params.id, 10);
    const restaurantIndex = restaurants.findIndex(
        (restaurant) => restaurant.id === restaurantId
    );
    restaurants.splice(restaurantIndex, 1);
    res.sendStatus(204);
});

ถ้าทำถูกต้องจะได้แบบนี้

เมื่อ get มาใหม่จะพบว่าข้อมูลร้านอาหารที่ลบไปจะไม่มีแล้วเนอะ

ส่วน post() กับ put() เราจะทำกันในบท Middleware เนอะ เพราะถ้าลอง console.log() ดูจะพบว่า res.body เป็น undefined เนอะ

Middleware

คือ function ที่ถูกเรียกอัตโนมัติโดย Express ซึ่ง Middleware จะถูกเรียกก่อนที่ Express จะเรียกตัว function ของเรา ตัวอย่าง ถ้าเรายิง request เข้าไป ตัว Express จะ check ว่ามี Middleware ไหม ถ้ามีก็ใช้งาน Middleware เมื่อทำงานเสร็จก็ check ต่อว่ามีอีกไหม ถ้ามีก็ทำงานไปแบบนี้จนหมด ก่อนที่จะเรียก function ของเรา

ถ้าในโปรเจกนี้ user สร้างร้านค้าใหม่ ก็จะเรียก POST /apis/restaurant ตัว Express จะ check ว่ามี Middleware ไหม อ่ะมี ชื่อว่า Logging ตัวนี้เอาไว้เก็บข้อมูลว่ามี request อะไรบ้างที่ยิงหา server ก็จะเรียกตัว Logging พอทำงานเสร็จก็จะ check ต่อว่ามี Middleware อีกไหม อ่ะมี ชื่อว่า User Auth ใช้ check ว่า user คนนี้มีสิทธิ์เพิ่มร้านค้าไหม แล้วก็ใช้งานอันนี้ พอหมดแล้วก็ไป function ที่เราสร้างไว้

Implementing Middleware

set ตัว middleware ก่อนที่จะทำการ implement ในส่วน post() และ put() เนื่องจาก res.body เป็น undefined

ไปที่ index.js เพิ่ม middleware ในที่นี้เราจะใช้ตัว build-in เนอะ มี 2 ตัวที่เราจะต้องเพิ่มกัน เพื่อทำให้เราอ่านข้อมูลที่เป็น json ได้

//Middleware at index.js
app.use(express.json());
app.use(express.urlencoded({ extended: false}));

ไปที่ Postman ใส่ header ที่มี key เป็น Content-Type และมี value เป็น application/json

และที่ Body ใส่ json เข้าไปเพิ่ม ประมาณนี้

เมื่อทำการ console.log ดูพบว่าเราอ่าน json ที่ส่งแนบมาใน Body ได้หล่ะ

จากนั้นเราจะสร้างตัวแปร newRestaurant และ pass data ที่เราได้จาก req.body เข้าไป และนำไป push data ใส่ข้อมูล array ของเรา และส่ง response กลับไปเป็นข้อมูลที่เราเพิ่มไป

router.post('/', (req, res) => {
    const newRestaurant = {
        ...req.body
    }
    restaurants.push(newRestaurant);
    res.json(newRestaurant);
});

จะได้แบบนี้

จริงๆตัว id นั้น คนยิงก็ไม่รู้หรอกว่า id อะไรแล้ว และจริงๆ id มันไม่ควรซํ้าเนอะ ดังนั้น server จะต้องเป็นคน generate id ให้เราเนอะ

ในโค้ดของเราเพิ่มตัวแปร currentRestaurantId เพื่อบอกว่าตอนนี้มีกี่อันแล้วนะ ขออนุญาตใช้เป็น length ของ array แล้วกันเนอะ

let currentRestaurantId = restaurants.length;

พอตัว post() ถูกเรียก ก็จะให้ค่า currentRestaurantId เพิ่มไป 1 แล้วทำการใส่ id เข้าไปในนั้น

router.post('/', (req, res) => {
    currentRestaurantId += 1;
    const newRestaurant = {
        id: currentRestaurantId,
        ...req.body
    }
    restaurants.push(newRestaurant);
    res.json(newRestaurant);
});

จากนั้นกลับไปที่ Postman แล้วเพิ่ม body โดยเราลบ id ออก ไม่งั้นเบิ้ลเนอะ พอ post() แล้วเลข id ที่ได้ก็จะขยับขึ้น

เมื่อดูทั้งหมด id มันก็จะไม่ซํ้ากันเนอะ

ไป put() กันต่อเลยยยยย จะเหมือนตรง delete() ที่เราจะเอา index ที่ได้จากการหา data ไปใช้ต่อ จากนั้นสร้าง Object ใหม่ชื่อว่า updatedRestaurant มี id เดียวกับ id ที่เรา update data และนำไป update ใน array ที่ index ที่ได้ จากนั้นส่ง response เป็น updatedRestaurant กลับไป

router.put('/:id', (req, res) => {
    const restaurantId = Number.parseInt(req.params.id, 10);
    const restaurantIndex = restaurants.findIndex(
        (restaurant) => restaurant.id === restaurantId
    );

    const updatedRestaurant = {
        id: restaurantId,
        ...req.body
    };
    restaurants[restaurantIndex] = updatedRestaurant;
    res.send(updatedRestaurant);
});

ตอนนี้เราจะได้ API ครบทุกเส้นแล้วนะ

Creating Your Own Middleware

ถ้าเราอยากสร้าง middleware ของเราเองนั้น ต้องทำยังไงนะ?

ก่อนอื่นสร้าง folder ที่ชื่อว่า middleware และสร้างไฟล์ใหม่ชื่อว่า logger.js โดยเขาจะ print ตัว request ต่างๆที่เข้ามาทาง server ด้วย console.log

สร้าง function ที่ชื่อว่า logger() มี parameter ปกติทั่วไปสองตัวคือ req และ res และมี parameter ที่พิเศษตัวนึง คือ next เป็น function ที่บอกว่าตัว middleware ของเราทำงานเสร็จหรือยัง ถ้าเสร็จแล้วเราจะเรียกใช้ next() เพื่อบอก Express ว่า ทำงานเสร็จแล้วนะ จะได้ไปเรียก middleware ตัวอื่นๆต่อ

function logger(req, res, next) {
    console.log(`[Logger]: Requesting to ${req.method} ${req.url}`);
    next()
}

module.exports = logger;

แล้ว import ที่ index.js และเรียกใช้ middleware ของเรา

const logger = require('./middleware/logger');

//Custom middleware
app.use(logger);

ทุกครั้งที่มีการเรียก API แล้ว จะมี log มาด้วย แบบนี้

ตอนนี้จบ session หลังบ้านแล้วน้าาา บทต่อมาเป็นการเอา Express ไปสร้างเว็บหน้าบ้าน

Template Engines

เป็นเครื่องมือที่ทำให้เราสร้าง HTML ตามข้อมูลที่เรามีอยู่ได้ โดยจะเป็น dynamic website เนอะ เว็บไซต์สามารถเปลี่ยนแปลงข้อมูลหน้าเว็บ เมื่อมีข้อมูลใหม่ๆส่งเข้าไป ตัว template engines มันจะครอบ HTML และ data เอาไว้ และ generate ออกมาเป็นหน้าเว็บ

Web Pages with Template Engines

ใน Express มี Template Engines เยอะมากๆเลย ที่นิยมก็คือตัว Pug ที่เป็นน้องหมาปั๊ก และตัวที่เราจะใช้ในบทนี้คือ express-handlebars นั่นเอง

ส่วน Template Engines ตัวอื่นๆสามารถดูได้ที่ link นี้เลย

https://expressjs.com/en/resources/template-engines.html

ก่อนอื่นเรามาลงเจ้า express-handlebars กันก่อน npm install express-handlebars --save

จากนั้นไปที่ index.js เพื่อทำการ import express-handlebars เข้ามา

const hbs = require('express-handlebars');

แล้ว set ตัว Template Engines ขึ้นมา โดยเราจะใช้ extension เพราะว่าถ้าเราสร้างไฟล์ .handlebars คือนามสกุลมันยาว เลยจะย่อให้เหลือ .hbs กัน และบอก Express ว่าตัว Template Engines นั้นเราจะใช้แบบ hbs กันนะ

app.engine('hbs', hbs({ extname: 'hbs'}));
app.set('view engine', 'hbs');

ต่อไปสร้างหน้า HTML กันตามนี้

  • ./views/layouts/main.hbs ใช้ในการ reuse ในหลายๆหน้า เช่น ใส่ nav-bar ไว้ที่นี่ แล้วหน้าอื่นเราก็จะมี nav-bar ด้วย ในไฟล์นี้เราจะสร้าง HTML โดยใน VS Code เราจะพิมพ์ ! และตามด้วย tab เราก็จะได้ template HTML มา

ที่น่าสนใจคือ section main ใส่ special syntax ของ hbs นั่นคือ เปิดตัวปีกกาสามอัน และข้างในใส่เป็น body  ซึ่งเป็น variable ตัวนึง ที่เวลาเราไปสร้างหน้าอื่นๆ content หน้าอื่นๆจะถูกนำมาใส่ใน body ตรงนี้

  • ./views/index.hbs เป็น content ข้างในเป็น <h1>Hello</h1>

ใน index.js เปลี่ยนตรง res.send('<h1>Hello Express</h1>'); เป็นแบบนี้

app.get('/', (req, res) => {
    res.render('index');
});

เพื่อให้ render หน้าเว็บที่เราทำมะกี้ โดยมันจะรู้เองว่าไปดึงจาก index.hbs เมื่อไปดูที่หน้าเว็บจะได้แบบนี้

และ refactor code ให้สวยงาม โดยแยกส่วนเมื่อกี้ออกเป็นอีกไฟล์นึง ชื่อว่า ./routes/index.js

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {
    res.render('index');
});

module.exports = router;

แล้วเอาไปใช้ใน index.js โดยตอน import ถ้าไฟล์นั้นชื่อ index อยู่แล้ว เราสามารถละ index ได้

const indexRouter = require('./routes');

//route
app.use('/', indexRouter);

ผลที่ได้จะต้องทำงานได้เหมียนเดิมนะ

จากนั้นไปแสดงข้อมูลร้านค้ากัน ไปที่ ./route/index.js pass data เข้าไป render ในหน้าเว็บของเรา เข้าไปใน parameter ที่สอง แต่เนื่องจากชื่อ key กับ value ของ object นี้เหมือนกัน จึงใส่ชื่อไปอย่างเดียวได้

router.get('/', (req, res) => {
    res.render('index', {
        restaurants
    });
});

ไปที่ index.hbs ทำการแสดงข้อมูลของร้านค้าออกมาที่หน้าเว็บของเรา โดยใช้ #each เป็นการวนลูปเหมือน foreach ธรรมดา แล้วสร้าง view พร้อมใส่ value ที่จะแสดงลงไป

ผลที่ได้แน่นอนว่าไม่สวยงาม แล้วรูปไม่เท่ากัน รูปแรกเราใหญ่มากกกกก เท่าไดโนเสาร์เลย กลายเป็นว่าเราเป็นไดโนเศร้าเลย มุแงงง ต้าวชานมมม

แน่นอนว่าต้องสร้าง css เนอะ โดยสร้าง folder ใหม่นามว่า public ไว้เก็บไฟล์ที่เป็น static ต่างๆเอาไว้ในนั้น เช่นไฟล์รูปภาพ css js เป็นต้น โดยเราต้องเพิ่ม middleware ใหม่ตัวนึงเพื่อบอก Express ว่าเราเก็บพวก static file ไว้ที่ไหน

const path = require('path');

/Middleware
app.use(express.static(path.join(__dirname, 'public')));

และสร้างไฟล์ css

แล้วไปกำหนดตัว css ในไฟล์ main.hbs ที่ section head ว่า <link ref="stylesheet" href="index.css">

สุดท้ายจะได้ดังนี้ อ่า สวยงามมม

เอาจริงๆก็คิดถึงเมนูหมี่กรอบผัดซีอิ้วร้านราดหน้ายอดผัก สูตร 40 ปีอ่ะ

สุดท้ายคนสอนจะ recap ทั้งหมดเนอะ


download แอพอ่านบล็อกใหม่ของเราได้ที่นี่

MikkiPastel - Apps on Google Play
First application from “MikkiPastel” on play store beta feature- read blog from https://www.mikkipastel.com by this application- read blog content by chrome custom tab- update or refresh new content by pull to refresh- share content to social network
https://play.google.com/store/apps/details?id=com.mikkipastel.blog

ติดตามข่าวสารและบทความใหม่ๆได้ที่

อย่าลืมกด like กด share บทความกันด้วยนะคะ :)

Posted by MikkiPastel on Sunday, 10 December 2017

และช่องทางใหม่ใน Twiter จ้า

Tags

Minseo Chayabanjonglerd

I am a full-time Android Developer and part-time contributor with developer community and web3 world, who believe people have hard skills and soft skills to up-skill to da moon.