-
Refactor ExpresscodeStates front-end/node(server) 2023. 2. 8. 20:13๋ฐ์ํ
๐ Refactor Express
๐Express
Express ์ค์น
npm install express
Hello world! ์์ ๋ง๋ค๊ธฐ
Express "Hello World" ์์
Hello world ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ด ์ฑ์ ์ฌ๋ฌ๋ถ์ด ์์ฑํ ์ ์๋ ๊ฐ์ฅ ๊ฐ๋จํ Express ์ฑ์ผ ๊ฒ์ ๋๋ค. ์ด ์ฑ์ ํ๋์ ํ์ผ๋ก ๋ ์ฑ์ด๋ฉฐ Express ์์ฑ๊ธฐ๋ฅผ ํตํด ์ป๊ฒ ๋๋ ์ฑ๊ณผ๋ ๊ฐ์ง ์์ต๋๋ค. (์ด ์์
expressjs.com
๊ณต์๋ฌธ์๋ฅผ ํตํด ์คํ
- myapp ๋๋ ํ ๋ฆฌ ์์ฑ
- npm init ์คํ
- app.js ๋ผ๋ ์ด๋ฆ์ ํ์ผ์ ์์ฑ ํ
- ๋ค์ ์ฝ๋ ์์ฑ
const express = require('express') const app = express() const port = 3000 app.get('/', (req, res) => { res.send('Hello World!') }) app.listen(port, () => { console.log(`Example app listening on port ${port}`) })
๐ก Express๋?
๐ Express๋ ์น ๋ฐ ๋ชจ๋ฐ์ผ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ์ผ๋ จ์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ๊ฐ๊ฒฐํ๊ณ ์ ์ฐํ Node.js ์น ์ ํ๋ฆฌ์ผ์ด์ ํ๋ ์์ํฌ์ ๋๋ค.
๐กExpress๋ ์ ์จ์?
๐ ๊ฐ๋ณ๊ฒ ์น ์๋ฒ๋ฅผ ๊ตฌํํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค
Mini-Node Server
๐ Mini-Node Server ๐์๋ฒ์คํ node server/basic-server.js ๐ ํ์ต ๋ชฉํ POST์ ๋ฌธ์์ด์ ๋ด์ ์์ฒญ์ ๋ณด๋ผ ๋๋ HTTP ๋ฉ์์ง์ body(payload)๋ฅผ ์ด์ฉํฉ๋๋ค. ์๋ฒ๋ ์์ฒญ์ ๋ฐ๋ฅธ ์ ์ ํ ์๋ต์ ํด๋ผ์ด์ธํธ๋ก
hwantech.tistory.com
๐๐ mini node server Express๋ก ๊ตฌํ ํด๋ณด๊ธฐ
basic.server.js
๋ํผ๋ฐ์ค์์ cors ์ค์นํ๊ธฐ ๋๋ฌธ์ cors ์ด์ฉ
npm install cors
const express = require('express') const app = express() const cors = require('cors') app.use(cors()) // ๋ชจ๋ ์์ฒญ์ cors ํ์ฉ //npm install cors --save ํฐ๋ฏธ๋์์ ์ค์น app.use(express.json({strict : false})) // const jsonParser = express.json({ // strict: false // }) // jsonParser๋ฅผ ๋ณ์๋ก ์ ์ธํด ํ๋์ฉ ๋ฃ์ด์ค๋ ๋๊ณ // ์์ฒ๋ผ ๋ชจ๋ ์์ฒญ์ ์ ์ฉํ ์๋ ์๋ค const port = 4999 // ํฌํธ๋ฒํธ ํ์ธ app.get('/', (req, res) => { res.send('hello world') }) app.post('/lower', (req, res) => { res.json(req.body.toLowerCase()) }) app.post('/upper' , (req, res) => { res.json(req.body.toUpperCase()) }) app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) })
๐Middleware
๋ฏธ๋ค์จ์ด๋ ์ด์์ฒด์ ์ ์์ฉ ํ๋ก๊ทธ๋จ ์ฌ์ด์์ ์คํ๋๋ ์ํํธ์จ์ด์ด๋ค.
์์ฒญ๊ณผ ์๋ด์ ์ค๊ฐ์ ์์นํด์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ฑฐ๋ ๋์ ์์ฒญ์ ๊ฑธ๋ฌ๋ธ๋ค
' ์๋์ฐจ ๊ณต์ฅ์ ๊ณต์ ๊ณผ๋ ๋น์ท' , ๋ฏธ๋ค์จ์ด๋ Express์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ด๋ค
๋ฏธ๋ค์จ์ด์ ๋ํ์ ์ฌ์ฉ (npm์ผ๋ก ๋ค์ด ๊ฐ๋ฅ )
Morgan ์ต์คํ๋ ์ค ํ๋ ์์ํฌ๊ฐ ๋์ํ๋ฉด์ ๋์ค๋ ๋ฉ์์ง๋ค์ ์ฝ์์ ํ์ํด์ค Compression ํ์ด์ง๋ฅผ ์์ถํด์ ์ ์กํด์ค Session์ ์ธ์ ์ฌ์ฉํ ์ ์๊ฒํจ Body-parser์ ํผ์์ ์ ์ก๋๋ POST ๊ฐ์ ์ฌ์ฉํ ์ ์๊ฒ ํจ Cookie-parser๋ ์ฟ ํค๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํจ Method-override๋ REST API์์ PUT๊ณผ DELETE ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํจ Cors ํฌ๋ก์ค์ค๋ฆฌ์ง(๋ค๋ฅธ ๋๋ฉ์ธ ๊ฐ์ AJAX ์์ฒญ)์ ๊ฐ๋ฅํ๊ฒ ํด์ค Multer ํ์ผ์ ๋ก๋๋ฅผ ํ ๋ ์ฃผ๋ก ์ฐ์
๋ฏธ๋ค์จ์ด ์คํ
app.set('port', process.env.PORT || 3000) // app.use() => ๋ชจ๋ ์์ฒญ์ ๋ํด์ ์ด ๋ฏธ๋ค์จ์ด๊ฐ ์คํ๋๋ค app.use((req,res,next) =>{ console.log('๋ชจ๋ ์์ฒญ์ ๋ค ์คํ๋จ') next() }) app.get('/', (req, res, next) =>{ console.log('GET, / ์์ฒญ์์๋ง ์คํ๋จ') next()// ๋ค๋ฅธ ์์ฒญ์ ๋ณด๋ }),(req,res) => { throw new Error('์๋ฌ๋ ์๋ฌ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ก ๊ฐ') } // ์๋ฌ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด app.use((err, req, res, next) => { console.log(err) res.status(500).send(err.message) // res.send()๋ก ์๋ต์ ๋ณด๋ }) app.listen(app.get('port'),()=>{ })
๋ผ์ฐํ
URL ์์ฒญ์ ๋ฐ๋ฅธ ์๋ต ์ฒ๋ฆฌ๋ฅผ ์๋ฏธ
// ์๋ ์ฝ๋์ฒ๋ผ rest API๋ฑ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ณ ๋งค๊ฒ๋ณ์๋ก ์ฃผ์๋ฅผ, ๊ทธ ํ ์ฒ๋ฆฌํ ๋ด์ฉ์ ๋ฃ์ด ์๋ app.get('/', (req, res) => { res.send('hello, world!'); })
Express ์ค๋ช
์ผ๋ฐ์ ์ผ๋ก ์ฒซ ์ค์์ ๋ง์ง๋ง์ค๋ก ์งํ
๋ฏธ๋ค์จ์ด ์ ํ -(์์ฒญ์ด ์ค๋ฉด)-> ๋ผ์ฐํธ -(if X)-> error
but, ๋ผ์ฐํธ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์๋ฌ์ฒ๋ฆฌ๊ฐ ์ ๋๋ ๊ฒฝ์ฐ๊ฐ ์๋ค?
-> ๋ผ์ฐํธ ์์ next()๊ฐ ๋ค์ด์์ง ์๊ธฐ ๋๋ฌธ!
-------------------------------------------------------------------------
์ด๊ฒ๋ง ๊ธฐ์ตํ์!
์๋ฒ๋ฅผ ์ฒ์ ์คํ ์ํค๋ฉด ๋ฏธ๋ค์จ์ด ์ ํ ๋ถ๋ถ์ด ๋์
๊ทธํ '์ฃผ์/'๋ฅผ ๋ค์ด๊ฐ๊ฒ ๋๋ฉด ๋ผ์ฐํธ ๋ถ๋ถ์ด ์คํ๋๊ณ ๋ค์ ์์ฒญ์ ๊ธฐ๋ค๋ฆผ
์ฃผ์/๊ฐ ์๋ ๊ฒฝ์ฐ ๋ค๋ฅธ ์ฃผ์๋ก ๋ค์ด๊ฐ๋ฉด ๋ผ์ฐํธ ์คํ x ์๋ฌ์ฒ๋ฆฌ ๋์
์ด๊ฑธ๋ณด๊ณ ๋ฏธ๋ค์จ์ด ์คํ์ ๋ค์๋ณด๋ฉด ์ดํด๊ฐ ๊ฐ๋ค!
--------------------------------------------------------------------------
๐๋ฏธ๋ค์จ์ด๊ฐ ์์ฃผ ์ฌ์ฉ๋๋ ์ํฉ
POST ์์ฒญ ๋ฑ์ ํฌํจ๋ body(payload)๋ฅผ ๊ตฌ์กฐํํ ๋(์ฝ๊ฒ ์ป์ด๋ด๊ณ ์ ํ ๋) ๋ชจ๋ ์์ฒญ/์๋ต์ CORS ํค๋๋ฅผ ๋ถ์ฌ์ผ ํ ๋ ๋ชจ๋ ์์ฒญ์ ๋ํด url์ด๋ ๋ฉ์๋๋ฅผ ํ์ธํ ๋ ์์ฒญ ํค๋์ ์ฌ์ฉ์ ์ธ์ฆ ์ ๋ณด๊ฐ ๋ด๊ฒจ์๋์ง ํ์ธํ ๋
case 1: ๋ชจ๋ ์์ฒญ์ ๋ํด url์ด๋ ๋ฉ์๋๋ฅผ ํ์ธํ ๋
var myLogger = function (req, res, next) { console.log(req.method, req.url); next(); }; app.use(myLogger) // POSR /upper // ๋ชจ๋ ์์ฒญ์ ๋ํด์ ๋ฏธ๋ค์จ์ด๊ฐ ๋ก๊ทธ๊ฐ ์ฐํ๊ธฐ ๋๋ฌธ์ // ๋๋ฒ๊น ํ ๋ ํธ๋ฆฌํ๋ค
case 2: POST ์์ฒญ ๋ฑ์ ํฌํจ๋ body(payload)๋ฅผ ๊ตฌ์กฐํํ ๋
node.js๋ก HTTP body(payload)๋ฅผ ๋ฐ์ ๋์๋ Buffer๋ฅผ ์กฐํฉํด์ ๋ค์ ๋ณต์กํ ๋ฐฉ์์ผ๋ก body๋ฅผ ์ป์ ์ ์์๋ค
let body = []; request.on('data', (chunk) => { body.push(chunk); }).on('end', () => { body = Buffer.concat(body).toString(); // body ๋ณ์์๋ ๋ฌธ์์ด ํํ๋ก payload๊ฐ ๋ด๊ฒจ์ ธ ์์ต๋๋ค. }); // ------------------------------------------------------------ // body-parser ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ๊ณผ์ ์ ๊ฐ๋จํ ์ฒ๋ฆฌ // ๋ค๋ฃฐ ์ ์๋ ๋ฐ๋ ํ์์ json, text, buffer ๋ง ๊ฐ๋ฅ const jsonParser = express.json() // ์๋ต app.post('/api/users', jsonParser, function (req, res) { // req.body์๋ JSON์ ํํ๋ก payload๊ฐ ๋ด๊ฒจ์ ธ ์์ต๋๋ค. })
case 3: ๋ชจ๋ ์์ฒญ/์๋ต์ CORS ํค๋๋ฅผ ๋ถ์ผ ๋
node.js ์ฝ๋์ CORS ํค๋๋ฅผ ๋ถ์ด๋ ค๋ฉด, ์๋ต ๊ฐ์ฒด์ writeHead ๋ฉ์๋ ๋ฑ์ ์ด์ฉํ๊ณ Access-Control-Allow-* ํค๋๋ฅผ ๋งค๋ฒ ์ฌ์ ์ ํด์ค์ผ ํ๋ค
๊ทธ๋ฆฌ๊ณ OPTIONS ๋ฉ์๋์ ๋ํ ๋ผ์ฐํ ๋ ๋ฐ๋ก ๊ตฌํํด์ผ ํ๋คconst defaultCorsHeader = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Accept', 'Access-Control-Max-Age': 10 }; // ์๋ต if (req.method === 'OPTIONS') { res.writeHead(201, defaultCorsHeader); res.end() }
cos ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํด ๊ฐ๋จํ ์ฒ๋ฆฌ
// npm cors ์ค์น ํ const cors = require('cors') // ์๋ต app.get('/products/:id', cors(), function (req, res, next) { res.json({msg: 'This is CORS-enabled for a Single Route'}) })
case 4: ์์ฒญ ํค๋์ ์ฌ์ฉ์ ์ธ์ฆ ์ ๋ณด๊ฐ ๋ด๊ฒจ์๋์ง ํ์ธํ ๋
HTTP ์์ฒญ์์ ํ ํฐ์ด ์๋์ง๋ฅผ ํ๋จํ์ฌ, ์ด๋ฏธ ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ผ ๊ฒฝ์ฐ ์ฑ๊ณต, ์๋ ๊ฒฝ์ฐ ์๋ฌ ์์
ํ ํฐ(Token) : ์ฃผ๋ก ์ฌ์ฉ์ ์ธ์ฆ์์ ์ฌ์ฉ
app.use((req, res, next) => { // ํ ํฐ์ด ์๋์ง ํ์ธ, ์์ผ๋ฉด ๋ฐ์์ค ์ ์์. if(req.headers.token){ req.isLoggedIn = true; next(); } else { res.status(400).send('invalid user') } })
๋ฐ์ํ'codeStates front-end > node(server)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
My Agora states server (0) 2023.02.09 StatesAirline Server (0) 2023.02.09 Mini-Node Server (0) 2023.02.08 CORS ๊ฐ์ (0) 2023.02.06 REST API - ๋๋ง์ ์ธ์ด๋ก ๋ธ๋ก๊น ํด๋ณด๊ธฐ (0) 2023.01.31