๐ํค์๋: ์ต์คํ๋ ์ค, ๋ฏธ๋ค์จ์ด, ๋ผ์ฐํ ๋ถ๋ฆฌ, rep์ res ๊ฐ์ฒด, ํ ํ๋ฆฟ ์์ง
- ์ต์คํ๋ ์ค: http ๋ชจ๋์ ์์ฒญ๊ณผ ์๋ต ๊ฐ์ฒด์ ์ถ๊ฐ ๊ธฐ๋ฅ์ ๋ถ์ฌํ๋ค.
1. pakage.json ์์ฑ
โ learn-express ํด๋๋ฅผ ๋ง๋ ๋ค.
โก ํญ์ package.json์ ์ ์ผ ๋จผ์ ์์ฑํ๋ค.
- npm init ๋ช ๋ น์ด๋ก ๋จ๊ณ์ ์ผ๋ก ๋ด์ฉ๋ฌผ์ ์ ๋ ฅํ๊ฑฐ๋
- npm init -y๋ฅผ ์ ๋ ฅํด ํ์ผ์ ๋ง๋ ๋ค ๋ด์ฉ์ ์์ ํ๋ค.
โข versoin, descripition, author, license๋ ์์ ๋ก์ด ์์ ํ๋ค.
package.json
{
"name": "learn-express",
"version":"0.0.1",
"description":"์ต์คํ๋ ์ค๋ฅผ ๋ฐฐ์ฐ์",
"main":"app.js",
"scripts":{
"start":"nodemon app" //app.js๋ฅผ nodemon์ผ๋ก ์คํ
},
author: "ZeroCho",
"license": "MIT"
}
์ฝ์
$ npm i express
$ npm i -D nodemon
- script์ start๋ ๊ผญ ๋ฃ์ด์ผ ํ๋ค.
- nodemon ๋ชจ๋: ์๋ฒ๋ฅผ ์๋์ผ๋ก ์ฌ์์
→ nodemon์ด ์๋ฒ๋ฅผ ์๋์ผ๋ก ์ฌ์์+์คํ๋๋ ์ฝ์์ rs๋ฅผ ์ ๋ ฅํด ์๋์ผ๋ก ์ฌ์์ ๊ฐ๋ฅ
- nodemon์ ๊ฐ๋ฐ์ฉ์ผ๋ก๋ง ์ฌ์ฉ ๊ถ์ฅ
2. app.js ์์ฑ
app.js
const express = require('express');
const app = express(); //Express ๋ชจ๋์ ์คํํด app ๋ณ์์ ํ ๋น
app.set('port', process.env.PORT || 3000); // ์๋ฒ๋ก ์คํ๋ ํฌํธ๋ฅผ ์ค์
app.get('/', (req, res) => { //GET ์์ฒญ์ ์ด๋ค ๋์์ ํ ์ง
res.send('Hello, Express');
});
app.listen(app.get('port'), () => { //http ์น ์๋ฒ์ ๋์ผ, ํฌํธ ์ฐ๊ฒฐ ํ ์๋ฒ ์คํ
console.log(app.get('port'), '๋ฒ ํฌํธ์์ ๋๊ธฐ ์ค'); // app.get('port')๋ก ํฌํธ๋ฅผ ๊ฐ์ ธ์ด
});
โ Express ๋ชจ๋์ ์คํํด app ๋ณ์์ ํ ๋น
- Express ๋ด๋ถ์ http ๋ชจ๋์ด ๋ด์ฅ๋์ด ์๋ค. → ์๋ฒ์ ์ญํ ์ํ ๊ฐ๋ฅ
โก app.set('port', ํฌํธ): ์๋ฒ๊ฐ ์คํ๋ ํฌํธ ์ค์
- process.env ๊ฐ์ฒด์ PORT ์์ฑ์ด ์๋ค๋ฉด ๊ทธ ๊ฐ์, ์๋ค๋ฉด ๊ธฐ๋ณธ 3000 ํฌํธ ์ด์ฉ
โข app.get(์ฃผ์, ๋ผ์ฐํฐ)
- GET ์์ฒญ ์ ์ด๋ค ๋์์ ํ ์ง
- req=์์ฒญ์ ๋ํ ์ ๋ณด๊ฐ ๋ค์ด์๋ ๊ฐ์ฒด, res=์๋ต์ ๊ดํ ์ ๋ณด๊ฐ ๋ค์ด์๋ ๊ฐ์ฒด
- GET ์์ฒญ ์ธ์๋ POST, PUT, PATCH, DELETE, OPTIONS์ ๋ํ ๋ผ์ฐํฐ๋ฅผ ์ํ ๋ฉ์๋๊ฐ ์กด์ฌํ๋ค.
โฃ listen์ ํ๋ ๋ถ๋ถ์ http ์น ์๋ฒ์ ๋์ผ
์ฝ์
$ npm start
> learn-express@0.0.1 start
> nodemon app
[nodemon] 2.0.16
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node app.js`
3000 ๋ฒ ํฌํธ์์ ๋๊ธฐ ์ค
→ http://localhost:3000์ผ๋ก ์ ์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ์ด์ง๊ฐ ํ์๋๋ค.
โป HTML๋ก ์๋ตํ๊ณ ์ถ๋ค๋ฉด ํ์ผ์ ๊ฒฝ๋ก๋ฅผ path ๋ชจ๋์ ์ฌ์ฉํด ์ง์ ํ ๋ค res.senFile ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค.
- ๋ฏธ๋ค์จ์ด(middleware): ์์ฒญ๊ณผ ์๋ต์ ์ค๊ฐ์ ์์นํ๋ ์ต์คํ๋ ์ค์ ํต์ฌ
- ๋ฏธ๋ค์จ์ด๋ ์์์๋ถํฐ ์๋๋ก ์์๋๋ก ์คํ๋๋ค.
- ๋ฏธ๋ค์จ์ด๋ ์์ฒญ๊ณผ ์๋ต์ ์กฐ์ํด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ธฐ๋ ํ๊ณ , ๋์ ์์ฒญ์ ๊ฑธ๋ฌ๋ด๊ธฐ๋ ํ๋ค.
1. ์ต์คํ๋ ์ค ์๋ฒ์ ๋ฏธ๋ค์จ์ด ์ฐ๊ฒฐ
app.js
app.set('port', process.env.PORT || 3000);
app.use((req, res, next) => { //app.use(๋ฏธ๋ค์จ์ด) ๊ผด๋ก ์ฌ์ฉ
console.log('๋ชจ๋ ์์ฒญ์ ๋ค ์คํ๋ฉ๋๋ค.');
next();
});
app.get('/', (req, res, next) => {
console.log('GET / ์์ฒญ์์๋ง ์คํ๋ฉ๋๋ค.');
next();
}, (req, res) => {
throw new Error('์๋ฌ๋ ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ก ๊ฐ๋๋ค.')
});
app.use((err, req, res, next) => { //์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด
console.error(err);
res.status(500).send(err.message);
});
app.listen(app.get('port'), () => {
...
โ app.use(๋ฏธ๋ค์จ์ด) ๊ผด๋ก ์ฌ์ฉ
- app.use์ ๋งค๊ฐ๋ณ์๊ฐ req, res, next์ธ ํจ์๋ฅผ ๋ฃ๋๋ค.
- next๋ฅผ ์คํํ์ง ์์ผ๋ฉด ๋ค์ ๋ฏธ๋ค์จ์ด๊ฐ ์คํ๋์ง ์๋๋ค.
- ์ฃผ์๋ฅผ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋ฃ์ง ์๋๋ค๋ฉด ๋ชจ๋ ์์ฒญ์์ ์คํ๋๋ค.
โก ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด
- ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ err, req, res, next๋ก ๋ค ๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ๋๋ค.
- ๋ชจ๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ง ์๋๋ผ๋ ๋งค๊ฐ๋ณ์๊ฐ ๋ฐ๋์ ๋ค ๊ฐ์ฌ์ผ ํ๋ค.
- res.status๋ก HTTP ์ํ ์ฝ๋๋ฅผ ์ง์ , ๊ธฐ๋ณธ๊ฐ์ 200 (์ฑ๊ณต)
- ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ฅผ ์ง์ ์ฐ๊ฒฐํ์ง ์์๋ ์ต์คํ๋ ์ค๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ์ง๋ง, ์ค๋ฌด์์๋ ์ง์ ์ฐ๊ฒฐํด ์ฃผ๋ ๊ฒ์ด ์ข๋ค.
2. ์ค๋ฌด์์ ๋ง์ด ์ฐ์ด๋ ํจํค์ง ์ค์น
์ฝ์
$ npm i morgan cookie-parser express-session dotenv
app.js
const express = require('express');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const dotenv = require('dotenv');
const path = require('path');
dotenv.config();
const app = express();
app.set('port', process.env.PORT || 3000);
app.use(morgan('dev'));
app.use('/', express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
name: 'session-cookie',
}));
app.use((req, res, next) => {
console.log('๋ชจ๋ ์์ฒญ์ ๋ค ์คํ๋ฉ๋๋ค.');
next();
});
...
.env
COOKIE_SECRET=cookiesecret
์์ธํ ๋ด์ฉ์ ์ฑ ์ฐธ์กฐ...
3. ๊ฐ๊ฐ์ ๋ฏธ๋ค์จ์ด ์ดํด๋ณด๊ธฐ
โ morgan: ์ฐ๊ฒฐ ํ localhost:3000์ ๋ค์ ์ ์ํ๋ฉด ์ถ๊ฐ์ ์ธ ๋ก๊ทธ๋ฅผ ๋ณผ ์ ์๋ค.
app.use(morgan('dev' | 'combined' | 'short' | 'tiny')); // ๊ดํธ ์ ํ๋์ ์์๋ง ์์ฑ
โก static: ์ ์ ์ธ ํ์ผ์ ์ ๊ณตํ๋ ๋ผ์ฐํฐ ์ญํ ์ ํ๋ค.
app.use('์์ฒญ ๊ฒฝ๋ก', express.static('์ค์ ๊ฒฝ๋ก'));
โข body-parser: ์์ฒญ์ ๋ณธ๋ฌธ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ํด์ํด req.body ๊ฐ์ฒด๋ก ๋ง๋ค์ด์ค๋ค.
app.use(express.json());
app.use(express.urlenconded({extended: false}));
โฃ cookie-parser: ์์ฒญ์ ๋๋ด๋ ์ฟ ํค๋ฅผ ํด์ํด req.cookies ๊ฐ์ฒด๋ก ๋ง๋ ๋ค.
app.use(cookieParser(๋น๋ฐ ํค));
โค express-session: ์ธ์ ๊ด๋ฆฌ์ฉ ๋ฏธ๋ค์จ์ด, ์ธ์ ๊ตฌํ์ด๋ ๋ฐ์ดํฐ๋ฅผ ์์์ ์ฅํ ๋ ์ ์ฉํ๋ค.
โฅ ๋ฏธ๋ค์จ์ด์ ํน์ฑ ํ์ฉํ๊ธฐ
(1) rep, res, next๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๊ฐ๋ ํจ์๋ก app.use, app.post๋ฑ์ผ๋ก ์ฅ์ฐฉํ๋ค.
(2) ํน์ ์ฃผ์์ ์์ฒญ์๋ง ์คํ๋๊ฒ ํ๋ ค๋ฉด ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ฃผ์๋ฅผ ๋ฃ๋๋ค.
(3) ์ฌ๋ฌ ๊ฐ์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฅ์ฐฉํ ์ ์๊ณ , ๋ค์ ๋ฏธ๋ค์จ์ด๋ก ๋์ด๊ฐ๋ ค๋ฉด next ํจ์๋ฅผ ํธ์ถํด์ผ ํ๋ค.
โป ๋ฏธ๋ค์จ์ด ์ฅ์ฐฉ ์์์ ๋ฐ๋ผ ์ด๋ค ๋ฏธ๋ค์จ์ด๋ ์คํ๋์ง ์์ ์๋ ์๋ค.
โป next(err)๋ฅผ ํตํด ๋ผ์ฐํฐ์์ ์๋ฌ๊ฐ ๋ฐ์ํ ๋ ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ก ๋๊ธด๋ค.
โฆ ๋ฏธ๋ค์จ์ด ์ฌ์ฉ ์ ์ ์ฉํ ํจํด: ๋ฏธ๋ค์จ์ด ์์ ๋ฏธ๋ค์จ์ด ๋ฃ๊ธฐ
app.use(morgan('dev'));
// ๋๋
app.use((req, res, next) => {
morgan('dev')(req, res, next);
});
- ๊ธฐ์กด ๋ฏธ๋ค์จ์ด์ ๊ธฐ๋ฅ์ ํ์ฅํ ์ ์๋ค. (ex) ๋ถ๊ธฐ ์ฒ๋ฆฌ
โง multer: ์ด๋ฏธ์ง, ๋์์ ๋ฑ์ ๋น๋กฏํ ์ฌ๋ฌ ๊ฐ์ง ํ์ผ์ ๋ฉํฐํํธ ํ์์ผ๋ก ์ ๋ก๋ ์ ์ฌ์ฉํ๋ ๋ฏธ๋ค์จ์ด
const multer = require('multer');
const upload = multer({
storage: multer.diskStorage({ //storage: ์ด๋์(destination), ์ด๋ค ์ด๋ฆ์ผ๋ก(filename) ์ ์ฅํ ์ง
destination(req, file, done) { //req: ์์ฒญ์ ๋ํ ์ ๋ณด, file: ์
๋ก๋ํ ํ์ผ์ ์ ๋ณด, done: ํจ์
done(null, 'uploads/');
},
filename(req, file, done) { //req: ์์ฒญ์ ๋ํ ์ ๋ณด, file: ์
๋ก๋ํ ํ์ผ์ ์ ๋ณด, done: ํจ์
const ext = path.extname(file.originalname);
done(null, path.basename(file.originalname, ext) + Date.now() + ext); //Date.now(): ํ์ผ๋ช
์ ์ค๋ณต ๋ฐฉ์ง
},
}),
limits: { fileSize: 5 * 1024 * 1024 }, //์
๋ก๋์ ๋ํ ์ ํ ์ฌํญ ์ค์ : fileSize๋ 5MB
});
- uploads ํด๋๊ฐ ์๋ฒ์ ๊ผญ ์กด์ฌํด์ผ ํ๋ค.
- upload ๋ณ์๊ฐ ์๊ธด ๋ค, ๋ค์ํ ์ข ๋ฅ์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ๋ค.
• single ๋ฏธ๋ค์จ์ด: ํ๋์ ํ์ผ๋ง ์ ๋ก๋ํ๋ ๊ฒฝ์ฐ
• array ๋ฏธ๋ค์จ์ด: ์ฌ๋ฌ ํ์ผ์ ์ ๋ก๋ํ๋ ๊ฒฝ์ฐ
• fileds ๋ฏธ๋ค์จ์ด: ์ฌ๋ฌ ํ์ผ์ ์ ๋ก๋ํ์ง๋ง, input ํ๊ทธ๋ ํผ ๋ฐ์ดํฐ์ ํค๊ฐ ๋ค๋ฅธ ๊ฒฝ์ฐ
• none ๋ฏธ๋ค์จ์ด: ํ์ผ์ ์ ๋ก๋ํ์ง ์๊ณ ๋ ๋ฉํฐํํธ ํ์์ผ๋ก ์ ๋ก๋ํ๋ ๊ฒฝ์ฐ
- ๋ผ์ฐํฐ๋ฅผ ๋ง์ด ์ฐ๊ฒฐํ๋ฉด app.js ์ฝ๋๊ฐ ๋งค์ฐ ๊ธธ์ด์ง๋ค.
→ ์ต์คํ๋ ์ค์์ ๋ผ์ฐํฐ๋ฅผ ๋ถ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค.
1. app.use๋ก ์ฐ๊ฒฐํ๊ธฐ
- routes ํด๋๋ฅผ ๋ง๋ค๊ณ ๊ทธ ์์ index.js์ user.js๋ฅผ ์์ฑํ๋ค.
routes/index.js
const express = require('express');
const router = express.Router();
// GET / ๋ผ์ฐํฐ
router.get('/', (req, res) => {
res.send('Hello, Express');
});
module.exports = router;
routes/user.js
const express = require('express');
const router = express.Router();
// GET /user ๋ผ์ฐํฐ
router.get('/', (req, res) => {
res.send('Hello, User');
});
module.exports = router;
- app.use๋ฅผ ์ด์ฉํด index.js์ user.js๋ฅผ app.js์ ์ฐ๊ฒฐํ๋ค.
app.js
...
const path = require('path');
dotenv.config();
const indexRouter = require('./routes'); //index.js๋ ์๋ต ๊ฐ๋ฅ
const userRouter = require('./routes/user'); //user.js๋ ๋ค๋ฅธ ์ฃผ์์ ๋ผ์ฐํฐ ์ญํ
...
name: 'session-cookie',
}));
app.use('/', indexRouter); //index.js ์ฐ๊ฒฐ
app.use('/user', userRouter); //user.js ์ฐ๊ฒฐ
app.use((req, res, next) => {
res.status(404).send('Not Found');
}); //์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด ์์ 404 ์ํ ์ฝ๋๋ฅผ ์๋ตํ๋ ๋ฏธ๋ค์จ์ด ์ถ๊ฐ
app.use((err, req, res, next) => { //์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด
...
2. next('route')
- next('route'): ๋ผ์ฐํฐ์ ์ฐ๊ฒฐ๋ ๋๋จธ์ง ๋ฏธ๋ค์จ์ด๋ค์ ๊ฑด๋๋ฐ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
router.get('/', (req, res, next) => {
next('route'); // ๋, ์ธ๋ฒ์งธ ๋ฏธ๋ค์จ์ด๋ ์คํํ์ง ์๊ณ , ์ฃผ์์ ์ผ์นํ๋ ๋ค์ ๋ผ์ฐํฐ๋ก ์ด๋
}, (req, res, next) => {
console.log('์คํ๋์ง ์์ต๋๋ค');
next();
}, (req, res, next) => {
console.log('์คํ๋์ง ์์ต๋๋ค');
next();
});
router.get('/', (req, res) => {
console.log('์คํ๋ฉ๋๋ค');
res.send('Hello, Express');
});
- ์ฌ๋ฌ ๊ฐ์ ๋ผ์ฐํฐ๊ฐ ์์ด๋ next()๋ฅผ ํธ์ถํ๋ฉด ๋ค์ ๋ฏธ๋ค์จ์ด๊ฐ ์คํ๋๋ค.
3. ๋ผ์ฐํธ ๋งค๊ฐ๋ณ์ ํจํด
router.get('/user/:id', (req, res) => {
console.log(req.params, req.query);
});
โ ๋ค์ํ ๋ผ์ฐํฐ๋ฅผ ์์ฐ๋ฅด๋ ์์ผ๋์นด๋ ์ญํ ์ ํ๋ฏ๋ก ์ผ๋ฐ ๋ผ์ฐํฐ๋ณด๋ค ๋ค์ ์์นํด์ผ ํ๋ค.
- ์ฃผ์์ ์ฟผ๋ฆฌ์คํธ๋ง์ ์ฐ๋ ๊ฒฝ์ฐ๋ ์๋ค. (์ฟผ๋ฆฌ์คํธ๋ง์ ํค-๊ฐ ์ ๋ณด๋ req.query ๊ฐ์ฒด ์์ ์ ์ฅ๋๋ค.)
- ์ต์คํ๋ ์ค์ req, res ๊ฐ์ฒด๋ http ๋ชจ๋์ req, res ๊ฐ์ฒด๋ฅผ ํ์ฅํ ๊ฒ
→ http ๋ชจ๋์ ๋ฉ์๋์ ์ต์คํ๋ ์ค๊ฐ ์ถ๊ฐํ ๋ฉ์๋๋ ์์ฑ์ ์ฌ์ฉํ ์ ์๋ค.
- ์์ฃผ ์ฐ์ด๋ rep ๊ฐ์ฒด์ ๋ฉ์๋
• req.app: req ๊ฐ์ฒด๋ฅผ ํตํด app ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๋ค. req.app.get('port')์ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
• req.body: body-parser ๋ฏธ๋ค์จ์ด๊ฐ ๋ง๋๋ ์์ฒญ์ ๋ณธ๋ฌธ์ ํด์ํ ๊ฐ์ฒด์ด๋ค.
• req.cookies: cookie-parser ๋ฏธ๋ค์จ์ด๊ฐ ๋ง๋๋ ์์ฒญ์ ์ฟ ํค๋ฅผ ํด์ํ ๊ฐ์ฒด์ด๋ค.
• req.ip: ์์ฒญ์ ip ์ฃผ์๊ฐ ๋ด๊ฒจ ์๋ค.
• req.params: ๋ผ์ฐํธ ๋งค๊ฐ๋ณ์์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊ธด ๊ฐ์ฒด์ด๋ค.
• req.query: ์ฟผ๋ฆฌ์คํธ๋ง์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊ธด ๊ฐ์ฒด์ด๋ค.
• req.signedCookies: ์๋ช ๋ ์ฟ ํค๋ค์ req.cookies ๋์ ์ฌ๊ธฐ์ ๋ด๊ฒจ์๋ค.
• req.get(ํค๋ ์ด๋ฆ): ํค๋์ ๊ฐ์ ๊ฐ์ ธ์ค๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ ๋ฉ์๋์ด๋ค.
- ์์ฃผ ์ฐ์ด๋ res ๊ฐ์ฒด์ ๋ฉ์๋
• res.app: res ๊ฐ์ฒด๋ฅผ ํตํด app ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๋ค.
• res.cookie(ํค, ๊ฐ, ์ต์ ): ์ฟ ํค๋ฅผ ์ค์ ํ๋ ๋ฉ์๋์ด๋ค.
• res.clearCookie(ํค, ๊ฐ, ์ต์ ): ์ฟ ํค๋ฅผ ์ ๊ฑฐํ๋ ๋ฉ์๋์ด๋ค.
• res.end(): ๋ฐ์ดํฐ ์์ด ์๋ต์ ๋ณด๋ธ๋ค.
• res.json(JSON): JSON ํ์์ ์๋ต์ ๋ณด๋ธ๋ค.
• res.locals: ํ๋์ ์์ฒญ ์์์ ๋ฏธ๋ค์จ์ด ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ ๊ฐ์ฒด์ด๋ค.
• res.redirect(์ฃผ์): ๋ฆฌ๋ค์ด๋ ํธ ํ ์ฃผ์์ ํจ๊ป ์๋ต์ ๋ณด๋ธ๋ค.
• res.render(๋ทฐ, ๋ฐ์ดํฐ): ๋ค์ ์ ์์ ๋ค๋ฃฐ ํ ํ๋ฆฟ ์์ง์ ๋ ๋๋ง ํด์ ์๋ตํ ๋ ์ฌ์ฉํ๋ ๋ฉ์๋์ด๋ค.
• res.send(๋ฐ์ดํฐ): ๋ฐ์ดํฐ์ ํจ๊ป ์๋ต์ ๋ณด๋ ๋๋ค. ๋ฐ์ดํฐ๋ ๋ฌธ์์ด์ผ ์๋, HTML์ผ ์๋, ๋ฒํผ์ผ ์๋, ๊ฐ์ฒด๋ ๋ฐฐ์ด์ผ ์๋ ์๋ค.
• res.sendFile(๊ฒฝ๋ก): ๊ฒฝ๋ก์ ์์นํ ํ์ผ์ ์๋ตํ๋ค.
• res.set(ํค๋, ๊ฐ): ์๋ต์ ํค๋๋ฅผ ์ค์ ํ๋ค.
• res.status(์ฝ๋): ์๋ต ์์ HTTP ์ํ ์ฝ๋๋ฅผ ์ง์ ํ๋ค.
- ํ ํ๋ฆฟ ์์ง: ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํด HTML์ ๊ฐ๋จํ๊ฒ ์ฒ๋ฆฌํด ๋ ๋๋ง ํ ์ ์๊ฒ ํ๋ค.
1. ํผ๊ทธ(์ ์ด๋)
โ HTML๊ณผ ํผ๊ทธ์ ์ฐจ์ด์
- ํ์ด๊ดํธ(<>) ์ ๋ซ๋ ํ๊ทธ๊ฐ ์๋ค.
- ํญ ๋๋ ์คํ์ด์ค๋ก๋ง ํ๊ทธ์ ๋ถ๋ชจ ์์ ๊ด๊ณ๋ฅผ ๊ท๋ช ํ๋ค.
- ํ๊ทธ๋ช ๋ค์ ์๊ดํธ๋ก ๋ฌถ์ด ์ ๋๋ค.
- div ๋ฌธ์๋ ์๋ต ๊ฐ๋ฅํ๋ค.
- HTML ํ ์คํธ๋ ํ๊ทธ ๋๋ ์์ฑ ๋ค์ ํ ์นธ์ ๋๊ณ ์ ๋ ฅํ๋ค.
- ์ฌ๋ฌ ์ค์ ํ ์คํธ ์ ๋ ฅ ์ ํ์ดํ (|)๋ฅผ ๋ฃ๋๋ค.
- style, script ํ๊ทธ๋ ํ๊ทธ ๋ค์ ์ (.)์ ๋ถ์ธ๋ค.
ํผ๊ทธ | HTML |
doctype html html head title=title; link(rel='stylesheet', href='/stylesheets/style.css') |
<!DOCTYPE html> <html> <head> <title>์ต์คํ๋ ์ค</title> <link rel="stylesheet" href="/style.css" /> </head> </html> |
#login-button .post-image |
|
p Welcome to Express p | ์๋ ํ์ธ์ | ์ฌ๋ฌ ์ค์ ์ ๋ ฅํฉ๋๋ค br | ํ๊ทธ๋ ์ค๊ฐ์ ๋ฃ์ ์ ์์ต๋๋ค |
|
style. h1{...} script. ... |
โก ๋ณ์
- HTML๊ณผ ๋ค๋ฅด๊ฒ ์๋ฐ์คํฌ๋ฆฝํธ ๋ณ์๋ฅผ ํ ํ๋ฆฟ์ ๋ ๋๋งํ ์ ์๋ค.
- res.render(ํ ํ๋ฆฟ, ๋ณ์ ๊ฐ์ฒด): ์ต์คํ๋ ์ค๊ฐ res ๊ฐ์ฒด์ ์ถ๊ฐํ ํ ํ๋ฆฟ ๋ ๋๋ง์ ์ํ ๋ฉ์๋
router.get('/', (req, res, next) => {
res.locals.title = 'Express';
res.render('index');
});
- res.render์ ๋ณ์ ๊ฐ์ฒด์ res.locals ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ๋ณ์๋ฅผ ๋ฃ์ผ๋ฉด ๋ค๋ฅธ ๋ฏธ๋ค์จ์ด์์๋ ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๋ค.
→ ๋ค๋ฅธ ๋ฏธ๋ค์จ์ด์์ ํ ํ๋ฆฟ ์์ง์ฉ ๋ณ์๋ฅผ ๋ฏธ๋ฆฌ ๋ฃ์ ์ ์๋ค.
- ํ ์คํธ ์ค๊ฐ์ ๋ณ์๋ฅผ ๋ฃ์ผ๋ ค๋ฉด #{๋ณ์}๋ฅผ ์ฌ์ฉํ๋ค.
- ํผ๊ทธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํน์๋ฌธ์๋ฅผ HTML ์ํฐํฐ๋ก ์ด์ค์ผ์ดํ ํ๋ฏ๋ก, ์ด์ค์ผ์ดํ๋ฅผ ์ํ์ง ์์ผ๋ฉด !=์ ์ฌ์ฉํ๋ค.
โข ๋ฐ๋ณต๋ฌธ
- ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ ์ ์๊ณ , each์ for๋ก ๋ฐ๋ณต๋ฌธ์ ๋๋ฆด ์ ์๋ค.
โฃ ์กฐ๊ฑด๋ฌธ
- ์กฐ๊ฑด๋ฌธ์ผ๋ก ๋ถ๊ธฐ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๊ณ , if, else if, else์ case๋ฌธ์ ์ฌ์ฉํ ์ ์๋ค.
โค include
- ๋ค๋ฅธ ํผ๊ทธ๋ HTML ํ์ผ์ ๋ฃ์ ์ ์๋ค.
- ์น ์ ์ ์ ๊ณตํต๋๋ ๋ถ๋ถ์ ๋ฐ๋ก ๊ด๋ฆฌํ ์ ์์ด ํ์ด์ง๋ง๋ค ๋์ผํ HTML์ ๋ฃ์ด์ผ ํ๋ ๋ฒ๊ฑฐ๋ก์์ ์์ค๋ค.
- include ํ์ผ ๊ฒฝ๋ก์ ๊ฐ์ ํํ๋ก ์ฌ์ฉํ๋ค.
โฅ extends์ block
- ๋ ์ด์์์ ์ ํ ์ ์๊ณ , ๊ณตํต๋๋ ๋ ์ด์์ ๋ถ๋ถ์ ๋ฐ๋ก ๊ด๋ฆฌํ ์ ์๋ค.
- block์ผ๋ก ํ์ด์ง๋ง๋ค ๋ฌ๋ผ์ง๋ ๋ถ๋ถ์ ๋น์๋๋ค.
2. ๋์ ์ค
- HTML ๋ฌธ๋ฒ์ ๊ทธ๋๋ก ์ฌ์ฉํ๋, ์ถ๊ฐ๋ก ์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค.
โ ๋ณ์
- ๋ณ์๋ { { } }๋ก ๊ฐ์ผ๋ค. (ex) { {title} }
- ๋ด๋ถ์ ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด { %set ๋ณ์= '๊ฐ' %}์ ์ฌ์ฉํ๋ค
- ์ด์ค์ผ์ดํ ํ๊ณ ์ถ์ง ์๋ค๋ฉด { {๋ณ์| safe} }๋ฅผ ์ฌ์ฉํ๋ค.
โก ๋ฐ๋ณต๋ฌธ
- ํน์ํ ๋ฌธ์ {% %} ์์ ์ฐ๋ฏ๋ก ๋ฐ๋ณต๋ฌธ๋ ์ด ์์ ์ด๋ค.
- for in๋ฌธ๊ณผ endfor ์ฌ์ด์ ์์นํ๋ค.
...
{% for item in fruits %}
<li>{{item}}</li>
{%endfor}
...
- loop.index๋ผ๋ ํน์ํ ๋ณ์๋ก ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
...
{% for item in fruits %}
<li>{{loop.index}}๋ฒ์งธ {{item}}</li>
{%endfor}
...
โข ์กฐ๊ฑด๋ฌธ
- {% if ๋ณ์ %} {% elif %} {% else %} {% endif %}๋ก ์ด๋ค์ ธ ์๋ค.
- case๋ฌธ์ ์์ง๋ง elif๋ฅผ ํตํด ๋ถ๊ธฐ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค.
- { { } } ์์์๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ๋ค.
<div>{{'์ฐธ' if isLoggedIn}}</div>
<div>{{'์ฐธ' if isLoggedIn else '๊ฑฐ์ง'}}</div>
โฃ include
- ๋ค๋ฅธ ํผ๊ทธ๋ HTML ํ์ผ์ ๋ฃ์ ์ ์๋ค.
- ์น ์ ์ ์ ๊ณตํต๋๋ ๋ถ๋ถ์ ๋ฐ๋ก ๊ด๋ฆฌํ ์ ์์ด ํ์ด์ง๋ง๋ค ๋์ผํ HTML์ ๋ฃ์ด์ผ ํ๋ ๋ฒ๊ฑฐ๋ก์์ ์์ค๋ค.
- include ํ์ผ ๊ฒฝ๋ก์ ๊ฐ์ ํํ๋ก ์ฌ์ฉํ๋ค.
โค extends์ block
- ๋ ์ด์์์ ์ ํ ์ ์๊ณ , ๊ณตํต๋๋ ๋ ์ด์์ ๋ถ๋ถ์ ๋ฐ๋ก ๊ด๋ฆฌํ ์ ์๋ค.
- block์ผ๋ก ํ์ด์ง๋ง๋ค ๋ฌ๋ผ์ง๋ ๋ถ๋ถ์ ๋น์๋๋ค.
- {% block [๋ธ๋ก๋ช ] %}์ผ๋ก ์ ์ธํ๋ค.
- {% endblock %}๋ก ๋ธ๋ก์ ์ข ๋ฃํ๋ค.
3. ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด
app.js
...
app.use((req, res, next) => {
const error = new Error(`${req.method} ${req.url} ๋ผ์ฐํฐ๊ฐ ์์ต๋๋ค.`);
error.status = 404;
next(error);
});
app.use((err, req, res, next) => {
res.locals.message = err.message;
//404 ์๋ฌ ๋ฐ์ ์ res.locals.message๋ '${req.method} ${req.url} ๋ผ์ฐํฐ๊ฐ ์์ต๋๋ค'๊ฐ ๋๋ค.
res.locals.error = process.env.NODE_ENV !== 'production' ? err : {};
res.status(err.status || 500);
res.render('error');
});
...
- error ๊ฐ์ฒด์ ์คํ ํธ๋ ์ด์ค๋ ์์คํ ํ๊ฒฝ์ด ๋ฐฐํฌํ๊ฒฝ(production)์ด ์๋ ๊ฒฝ์ฐ ํ์๋๊ณ , ๋ฐฐํฌ ํ๊ฒฝ์ธ ๊ฒฝ์ฐ ์๋ฌ๋ฉ์์ง๋ง ํ์๋๋ค.
- ์คํ ํธ๋ ์ด์ค๋ฅผ ํตํด ์๋ฒ ํด๋ ๊ตฌ์กฐ๋ฅผ ์ ์ถํ ์ ์์ผ๋ฏ๋ก ๋ฐฐํฌ ํ๊ฒฝ์์๋ ์จ๊ธด๋ค.
• Express ๊ณต์ ํํ์ด์ง: http://expressjs.com
• ํผ๊ทธ ๊ณต์ ํํ์ด์ง: https://pugjs.org
• ๋์ ์ค ๊ณต์ ํํ์ด์ง: https://mozilla.github.io/nunjucks
• morgan: https://github.com/expressjs/morgan
• body-parser: https://github.com/expressjs/body-parser
• cookie-parser: https://github.com/expressjs/cookie-parser
• static: https://github.com/expressjs/serve-static
• express-session: https://github.com/expressjs/session
• multer: https://github.com/expressjs/multer
• dotenv: https://github.com/motdotla/dotenv
1. http ๋ชจ๋์ ์์ฒญ๊ณผ ์๋ต ๊ฐ์ฒด์ ์ถ๊ฐ ๊ธฐ๋ฅ์ ๋ถ์ฌํ ๊ฒ์ ( )๋ผ ํ๋ค.
2. ์์ฒญ๊ณผ ์๋ต์ ์ค๊ฐ์ ์์นํ๋ ์ต์คํ๋ ์ค์ ํต์ฌ์ ( )๋ผ ํ๋ค.
3. ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ ( ), ( ), ( ), ( )๋ก ๋ค ๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ๋๋ค.
4. ๋ผ์ฐํฐ์ ์ฐ๊ฒฐ๋ ๋๋จธ์ง ๋ฏธ๋ค์จ์ด๋ฅผ ๊ฑด๋๋ฐ๊ณ ์ถ๋ค๋ฉด ( )๋ฅผ ์ฌ์ฉํ๋ค.
5. ์ต์คํ๋ ์ค์ res, req ๊ฐ์ฒด๋ ( )๋ชจ๋์ req, res ๊ฐ์ฒด๋ฅผ ํ์ฅํ ๊ฒ์ด๋ค.
6. ( )์ ์ด์ฉํ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํด HTML์ ๊ฐ๋จํ ์ฒ๋ฆฌํด ๋ ๋๋งํ ์ ์๋ค.
7. ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด์์ ์คํ ํธ๋ ์ด์ค๋ ์์คํ ํ๊ฒฝ์ด ( )์ด ์๋ ๊ฒฝ์ฐ ํ์๋๋ค.
8. ๋ค์์ ์ต์คํ๋ ์ค ๋ชจ๋์ ์ด์ฉํด ์๋ฒ๋ฅผ ๊ตฌ์ถํ๋ ์ฝ๋์ด๋ค. ๋น์นธ์ ์ฑ์ฐ์์ค.
const express = require('________'); // 1. Express ๋ชจ๋์ ๋ถ๋ฌ์ค๊ธฐ
const app = _________; // 2. Express ๋ชจ๋์ ์คํํด app ๋ณ์์ ํ ๋น
app.set('port', process.env.______ || 3000); // 3. ์๋ฒ๊ฐ ์คํ๋ ํฌํธ๋ฅผ ์ค์
app.______('/', (req, res) => { // 4. GET ์์ฒญ ์ ์ํํ ๋์ ์ ์
________________ // 5. ์๋ต์ผ๋ก 'Hello, Express' ๋ฉ์์ง ์ ์ก
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '๋ฒ ํฌํธ์์ ๋๊ธฐ ์ค');
});
9.
router.____('/', (req, res, next) => { //1. ์ ์ ํ ๋ฉ์๋ ์ถ๊ฐ
next('______'); // 2. ๋ ๋ฒ์งธ์ ์ธ ๋ฒ์งธ ๋ฏธ๋ค์จ์ด๋ฅผ ๊ฑด๋๋ฐ๊ณ , ์ฃผ์์ ์ผ์นํ๋ ๋ค์ ๋ผ์ฐํฐ๋ก ์ด๋
}, (req, res, next) => {
console.log('์คํ๋์ง ์์ต๋๋ค');
________; // 3. ๋ค์ ๋ฏธ๋ค์จ์ด๋ก ์ด๋
}, (req, res, next) => {
console.log('์คํ๋์ง ์์ต๋๋ค');
________; // 4. ๋ค์ ๋ฏธ๋ค์จ์ด๋ก ์ด๋
});
router.____('/', (req, res) => { //5. ์ ์ ํ ๋ฉ์๋ ์ถ๊ฐ
console.log('์คํ๋ฉ๋๋ค'); //
_________________; // 6. ํด๋ผ์ด์ธํธ์๊ฒ ์๋ต์ผ๋ก 'Hello, Express' ๋ฉ์์ง ์ ์ก
});
1. ์ต์คํ๋ ์ค
2. ๋ฏธ๋ค์จ์ด
3. err, req, res, next
4. next('route')
5. http
6. ํ ํ๋ฆฟ ์์ง
7. ๋ฐฐํฌ ํ๊ฒฝ (production)
8.
const express = require('express'); // 1. Express ๋ชจ๋์ ๋ถ๋ฌ์ค๊ธฐ
const app = express(); // 2. Express ๋ชจ๋์ ์คํํด app ๋ณ์์ ํ ๋น
app.set('port', process.env.PORT || 3000); // 3. ์๋ฒ๊ฐ ์คํ๋ ํฌํธ๋ฅผ ์ค์
app.get('/', (req, res) => { // 4. GET ์์ฒญ ์ ์ํํ ๋์ ์ ์
res.send('Hello, Express'); // 5. ์๋ต์ผ๋ก 'Hello, Express' ๋ฉ์์ง ์ ์ก
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '๋ฒ ํฌํธ์์ ๋๊ธฐ ์ค');
});
9.
router.get('/', (req, res, next) => {
next('route');
}, (req, res, next) => {
console.log('์คํ๋์ง ์์ต๋๋ค');
next();
}, (req, res, next) => {
console.log('์คํ๋์ง ์์ต๋๋ค');
next();
});
router.get('/', (req, res) => {
console.log('์คํ๋ฉ๋๋ค');
res.send('Hello, Express');
});
์ถ์ฒ) ์กฐํ์ , ใNode.js ๊ต๊ณผ์ ๊ฐ์ 3ํใ, ๊ธธ๋ฒ(2022), 6์ฅ
Corner node.js 2ํ
Editor : Sullivan
[๋ ธ๋ 2ํ] #9. ๋ชฝ๊ณ ๋๋น (3) | 2024.12.27 |
---|---|
[๋ ธ๋ 2ํ] #8. MySQL (3) | 2024.11.29 |
[๋ ธ๋ 2ํ] #6. http ๋ชจ๋๋ก ์๋ฒ ๋ง๋ค๊ธฐ & ํจํค์ง ๋งค๋์ (1) | 2024.11.15 |
[๋ ธ๋ 2ํ] #5. ๋ ธ๋ ๊ธฐ๋ฅ(2) (0) | 2024.11.08 |
[๋ ธ๋ 2ํ] #4.๋ ธ๋ ๊ธฐ๋ฅ ์์๋ณด๊ธฐ(1) (0) | 2024.10.11 |