4.06 [Express ]

Leeยท2023๋…„ 4์›” 6์ผ
0

์˜ค.๋ฐฐ.์ด.์•ˆ& ํšŒ๊ณ 

๋ชฉ๋ก ๋ณด๊ธฐ
32/46
post-thumbnail

์˜ค๋ฐฐ์ด์•ˆ ๐Ÿช™


Node.js ?

Node.js ๋ž€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ž‘๋™๋˜๋Š”๊ฒŒ ์•„๋‹Œ ์„œ๋ฒ„์—์„œ ์ž‘๋™๋˜๋„๋ก ํ•ด์ฃผ๋Š” ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์„ ๋งํ•œ๋‹ค.
์ด๊ฒƒ์ด ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” Chrome(ํฌ๋กฌ) ์˜ V8 ์—”์ง„์„ ์ด์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค!

Express?

Express ๋ž€ Node.js ํ™˜๊ฒฝ์—์„œ ์„œ๋ฒ„๋ฅผ ์ œ์ž‘์„ ๋ณด๋‹ค ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค!
๊ธฐ์กด์˜ HTTP ๋‚ด์žฅ ๋ชจ๋“ˆ๋กœ ๋งŒ๋“  ์„œ๋ฒ„๋ณด๋‹ค ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ธฐ ํŽธ๋ฆฌํ•˜๊ณ  ๊ฐ„ํŽธํ•œ ๊ธฐ๋Šฅ๋“ค์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์–ด ๊ฐ€์žฅ ๋งŽ์€ ๊ณณ์—์„œ ๋ณดํŽธ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค. (๋ฌผ๋ก  Express ๋ง๊ณ ๋„ ์—ฌ๋Ÿฌ ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์žˆ๋‹ค.)


Express ์„ค์น˜

์‚ฌ์ „์— Node.js ๊ฐ€ ์„ค์น˜ ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹น ๐Ÿ˜„

์„œ๋ฒ„๋ฅผ ๋ณด๊ด€ํ•  ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ž‘์„ฑ!

$ mkdir myapp
$ cd myapp

npm init ๋ช…๋ น์„ ์ด์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ package.json ํŒŒ์ผ์„ ์ž‘์„ฑ!
์ถ”๊ฐ€๋กœ js ํŒŒ์ผ๋„ ์ƒ์„ฑํ•˜๊ธฐ!

$ npm init

์ดํ›„ Express ์„ค์น˜

$ npm install express  --save 

๋งŒ์•ฝ ์ž„์‹œ๋กœ ์„ค์น˜ํ• ๋ ค๋ฉด --save ๋ฅผ ๋นผ์ฃผ๋ฉด ๋œ๋‹ค!

์„ค์น˜๊ฐ€ ๋‹ค๋๋‚˜๋ฉด package.json ์— express ๊ฐ€ ๋ณด์ผ ๊ฒƒ!


Http ๋‚ด์žฅ๋ชจ๋“ˆ๋กœ ์›น ์„œ๋ฒ„ ๋„์›Œ๋ณด๊ธฐ VS Express๋กœ ์›น ์„œ๋ฒ„ ๋„์›Œ๋ณด๊ธฐ

  • Http ๋‚ด์žฅ๋ชจ๋“ˆ๋กœ ์›น ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ

ํ„ฐ๋ฏธ๋„์— node ํŒŒ์ผ๋ช… ์„ ์ž…๋ ฅํ•ด๋ณด๋ฉด ์„œ๋ฒ„์ฃผ์†Œ๊ฐ€ ๋œฌ๋‹ค.
๋ธŒ๋ผ์šฐ์ €์— ์ž…๋ ฅํ•ด๋ณด์ž! 'hello http server!' ๊ฐ€ ๋ณด์ผ ๊ฒƒ!

const http = require('http');

http.createServer((request,response)=>{
    response.writeHead(200, {'Content-Type' : 'text/html'})
    response.write('hello http server!')
    response.end()
}).listen(3000, ()=>{
    console.log("http server runing http://127.0.0.1:3000/")
})
  • Express๋กœ ์›น ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ

Http ๋‚ด์žฅ ๋ชจ๋“ˆ๋กœ ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ ๋ณด๋‹ค ํ›จ์”ฌ ์ฝ”๋“œ๊ฐ€ ์ค„์—ˆ๋‹ค!

const express = require('express')
const app =express();
const port =3000;

app.get('/',(request,response)=>{
        response.send('hellow Express server!')
})

app.listen(port,()=>{
    console.log("Express server runing http://127.0.0.1:3000/")
})

Express ๋ผ์šฐํŒ…

๊ณต์‹ ๋ฌธ์„œ์˜ ๋ผ์šฐํŒ… ์ •์˜
๋ผ์šฐํŒ…์ด๋ž€ URI ๋ฐ ํŠน์ •ํ•œ HTTP ์š”์ฒญ ๋ฉ”์†Œ๋“œ์ธ ํŠน์ • ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•œ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‘๋‹ตํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

์š”์•ผ์ฟ  ์ฟ ๋‹ค์‚ฌ์ด

๋ผ์šฐํŒ…์ด๋ž€ ํด๋ผ์ด์–ธํŠธ์˜ ํŠน์ • ์š”์ฒญ ๋ฉ”์†Œ๋“œ์™€ ์—”๋“œํฌ์ธํŠธ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์‘๋‹ต ์ฒ˜๋ฆฌ ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.
์ฆ‰, ๋ถ„๊ธฐ์ ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋ผ์šฐํŒ…ํŒ…ํƒฑํƒฑ

์ด๊ฑด ๋ด์•ผํ•ด

ํด๋ผ์ด์–ธํŠธ๋Š” ํŠน์ •ํ•œ HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ(GET, POST ๋“ฑ)์™€ ํ•จ๊ป˜ ์„œ๋ฒ„์˜ ํŠน์ • URI(๋˜๋Š” ๊ฒฝ๋กœ)๋กœ HTTP ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๋ผ์šฐํŒ…์€ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์— ํ•ด๋‹นํ•˜๋Š” Endpoint์— ๋”ฐ๋ผ ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • Http ๋‚ด์žฅ๋ชจ๋“ˆ๋กœ ๋ผ์šฐํŒ…์„ ๊ตฌํ˜„ํ•ด๋ณด์ž…์‹œ๋”

'/lower'์—”๋“œํฌ์ธํŠธ๋กœ ๋ถ„๊ธฐ์ ์„ ์žก๊ณ  ๊ทธ ์•ˆ์—์„œ๋„ http์š”์ฒญ ๋ฉ”์„œ๋“œ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์‘๋‹ต์„ ๋‚ด๋ณด๋‚ด๋„๋ก ๋ผ์šฐํŒ… ๊ตฌํ˜„


const requestHandler = (req, res) => {
    if(req.url === '/lower') {
      if (req.method === 'GET') {
        res.end(data)
      } else if (req.method === 'POST') {
        req.on('data', (req, res) => {
          // do something ...
        })}}}
  • Express ์—์„œ ๋ผ์šฐํŒ… ํ•ด๋ณด์ž…์‹œ๋”
    ์ด๋ฏธ ์œ„์—์„œ ์ž‘์„ฑํ•œ Express ๋กœ ์›น ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ์— ์ž‘์„ฑํ•œ app.get ์ด ๋ถ€๋ถ„์€ ๋ผ์šฐํ„ฐ!

http ๋ฉ”์†Œ๋“œ ์•ˆ์— ์ธ์ž๋กœ ์—”๋“œํฌ์ธํŠธ๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ  ์ด ๊ฒฝ์šฐ ์–ด๋–ค ์‘๋‹ต์„ ๋‚ด๋ณด๋‚ผ๊ฑด์ง€ ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„


const router= express.Router()

router.get('/lower',(request,response)=>{
response.send(data);
})

router.post('/lower',(request,response)=>{
    ///
})

์ด๊ฑด ๋ญ์ ธ ?

const router= express.Router()

express.Router()

์œ„์—์„œ๋„ ๋งํ–ˆ์ง€๋งŒ Express ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ  ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ผ์šฐํŒ…์„ ๊น”๋”ํ•˜๊ฒŒ ๊ด€๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.!

์›น์ด ์ปค์ง€๋ฉด ์„œ๋ฒ„์—๋Š” app.get ๊ณผ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๊ฐ€ ์—ด๋ผ ๋งŽ์ด ์ƒ๊ฒจ ์ฝ”๋“œ๊ฐ€ ๋งค์šฐ ๊ธธ์–ด์ง„๋‹ค.

๊ทธ๋ž˜์„œ Express ์—์„œ๋Š” ๋ผ์šฐํ„ฐ๋ฅผ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•จ!

๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ express.Router( ) ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ!

  • ๊ฐ€์ •

๋ฉ”์ธํŒŒ์ผ : app.js
๋ผ์šฐํ„ฐ๋ฅผ ์ €์žฅํ•  ํŒŒ์ผ : index.js , user.js

index.js , user.js ํŒŒ์ผ๋“ค์„ routes ํด๋”์— ์ €์žฅ ์‹œํ‚จ๋‹ค๊ณ  ๊ฐ€์ก


// routes/index.js ํŒŒ์ผ
const express = require('express');

const router= express.Router()

router.get('/',(request,response)=>{
response.send('hello');
})

module.exports = router;

// routes/user.js ํŒŒ์ผ -----------------------

const express = require('express');

const router = express.Router();

router.get('/iam', (req, res) => {
    res.send('Hello, User');
});

module.exports = router;

app.js ํŒŒ์ผ

const express = require('express');

const app = express();

const indexRouter = require('./routes'); // router.get('/', (req, res) => { ... ์„ ๋ถˆ๋Ÿฌ์˜ด
const userRouter = require('./routes/user'); // router.get('/iam', (req, res) => { ... ์„ ๋ถˆ๋Ÿฌ์˜ด

app.set('port', process.env.PORT || 3000);

app.use('/', indexRouter); // ๊ฐ๊ธฐ ๋‹ค๋ฅธ ๊ฒฝ๋กœ์— ๋ฏธ๋“ค์›จ์–ด ์žฅ์ฐฉ
app.use('/user', userRouter); // ๊ฐ๊ธฐ ๋‹ค๋ฅธ ๊ฒฝ๋กœ์— ๋ฏธ๋“ค์›จ์–ด ์žฅ์ฐฉ

app.use((req, res, next) => { // ๊ธฐ๋ณธ๊ฒฝ๋กœ๋‚˜ /user๋ง๊ณ  ๋‹ค๋ฅธ๊ณณ ์ง„์ž…ํ–ˆ์„๊ฒฝ์šฐ ์‹คํ–‰
    res.status(404).send('Not Found');
});

app.listen(app.get('port'), () => {
   console.log(app.get('port'), '๋ฒˆ ํฌํŠธ์—์„œ ๋Œ€๊ธฐ ์ค‘');
});

index.js , user.js ๊ฐ€ ์ƒ๊ธด๊ฑด ๋น„์Šทํ•ด๋„ ์„œ๋กœ ๋‹ค๋ฅธ ์ฃผ์†Œ์˜ ๋ผ์šฐํ„ฐ ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ๋‹ค.

app.use๋กœ ์—ฐ๊ฒฐํ•  ๋•Œ์˜ ์ฐจ์ด ๋•Œ๋ฌธ!

indexRouter๋Š” app.use('/')์— ์—ฐ๊ฒฐํ–ˆ๊ณ  (index)

userRouter๋Š” app.use('/user')์— ์—ฐ๊ฒฐํ–ˆ๋‹ค.(user)

์„œ๋ฒ„๋กœ ์‹คํ–‰ํ•œ ๋’ค localhost:3000/๊ณผ localhost:3000/user/iam๋กœ ์ ‘์†ํ•˜๋ฉด ๊ฐ๊ฐ์— ํ•ด๋‹นํ•˜๋Š” ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.


next( ) ?

Express.Router( ) ์—๋Š” next ํ•จ์ˆ˜๊ฐ€ ์กด์žฌํ•œ๋‹ค. next ํ•จ์ˆ˜๋Š” ๋‹ค์Œ ๋ผ์šฐํ„ฐ๋กœ ๋„˜์–ด๊ฐ€๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

next('route')

const express = require('express');

const router = express.Router();

router.get('/', (req, res, next) => {
    next('route'); // ๋‹ค์Œ ๋ผ์šฐํ„ฐ ๋ฏธ๋“ค์›จ์–ด๋กœ ์ ํ”„ํ•œ๋‹ค.
}, (req, res, next) => {
    console.log('์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.');
    next();
});

router.get('/', (req, res) => {
    console.log('์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.');
    res.send('Hello, Express.');
});

next('route') ํ•จ์ˆ˜ ์‚ฌ์šฉ์œผ๋กœ ํ•ด๋‹น get ๋ฉ”์†Œ๋“œ์˜ ์„ธ๋ฒˆ์งธ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ  ๋‹ค์Œ get ๋ฉ”์†Œ๋“œ์˜ ๋ผ์šฐํ„ฐ๊ฐ€ ์‹คํ–‰๋œ๋‹ค!


๋ผ์šฐํ„ฐ ๊ทธ๋ฃนํ™”?

์—”๋“œํฌ์ธํŠธ๋Š” ๊ฐ™์€๋ฐ Http ๋ฉ”์†Œ๋“œ๋งŒ ๋‹ค๋ฅธ ๊ฒฝ์šฐ?
๊ทธ๋Ÿด ๋• ์ด๋ฅผ ํ•˜๋‚˜์˜ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์–ด ์ค„ ์ˆ˜ ์žˆ๋‹ค!

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

router.get('/abc', (req, res) => {  
    res.send('GET /abc');
});
router.post('/abc', (req, res) => {
    res.send('POST /abc');
});

๊ฐ™์€ ์—”๋“œํฌ์ธํŠธ์ธ /abc ๋กœ get ์š”์ฒญ๊ณผ post ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์žˆ๋‹ค.
์ด๋Ÿฐ๊ฒฝ์šฐ์— router.route ๋˜๋Š” app.route ๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ๋‹ค.

const express = require('express');
  
const router = express.Router();
  
router.route('/abc')
    .get((req,res) => {
        res.send('GET /abc');
    })
    .post((req, res) => {
        res.send('POST /abc');
    });

query parameter & path variable

ํ—ท๊ฐˆ๋ฆฌ๋ฉด์„œ๋„ ์•„๋‹Œ ๋‘๋…€์„

  • query parameter

๊ฒฝ๋กœ ๋’ค์— ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ํ•จ๊ป˜ ์ œ๊ณตํ•˜๋Š” ์‹์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

/user?id=10

์œ„์˜ ์ฝ”๋“œ์—์„œ ๋ฌผ์Œํ‘œ( ? ) ๋’ค์— ๋‚˜์˜ค๋Š” id=10 ์ด ๋ถ€๋ถ„์„ query string ์ด๋ผ๊ณ  ํ•˜๋ฉฐ
key ์™€ value ์˜ ์Œ์œผ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ๋‹ค. & ์—”๋“œ ํ‘œ์‹œ๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€๋กœ ๋ถ™์ผ ์ˆ˜๋„ ์žˆ๋‹ค.


- `path variable`

๊ฒฝ๋กœ๋ฅผ ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ

/user/{:id}

{:id} ์ด ๋ถ€๋ถ„์ด path ๋ถ€๋ถ„์ด๊ณ  ํ•ด๋‹น id ๊ฐ’์ด๋‚˜ ํ•„์š”ํ•œ ๊ฐ’์ด ๋“ค์–ด๊ฐ„๋‹ค.


Middleware ๋ž€?

๋ฏธ๋“ค์›จ์–ด๋Š” Express ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ  ์ค‘ ํ•˜๋‚˜์ด๋‹ค! ๊ฐ€์žฅ ํฐ ์ด์œ ๋ผ๊ณ  ํ•ด๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.
๋ฏธ๋“ค์›จ์–ด๋Š” HTTP ์š”์ฒญ๊ณผ ์‘๋‹ต ์‚ฌ์ด์—์„œ ๋‹จ๊ณ„๋ณ„ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

๋ฏธ๋“ค์›จ์–ด ๋™์ž‘์›๋ฆฌ

๋ฏธ๋“ค์›จ์–ด๋Š” HTTP Request(์š”์ฒญ)์ด ๋“ค์–ด์˜จ ์ˆœ๊ฐ„๋ถ€ํ„ฐ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹œ์ž‘๋œ๋‹ค.
HTTP ์š”์ฒญ๊ณผ ์‘๋‹ต ๊ฐ์ฒด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜, ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
HTTP ์‘๋‹ต์ด ๋งˆ๋ฌด๋ฆฌ๋  ๋•Œ๊นŒ์ง€ ๋ฏธ๋“ค์›จ์–ด ๋™์ž‘ ์‚ฌ์ดํด์ด ์‹คํ–‰๋œ๋‹ค. ์œ„์˜ ์‚ฌ์ง„ ์ฒ˜๋Ÿผ!


๊ทธ๋ž˜์„œ express ์—์„œ ๋ญ๊ฐ€ ๋ฏธ๋“ค์›จ์–ด์ธ๊ฑด๋ฐ?

๊ทธ๋ ‡๋‹ค ๋ฏธ๋“ค์›จ์–ด๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋ผ์šฐํ„ฐ๋ฅผ ์ž‘์„ฑํ• ๋•Œ ์—”๋“œํฌ์ธํŠธ ๋‹ค์Œ ์ธ์ž๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฏธ๋“ค์›จ์–ด๋ผ๊ณ  ํ•œ๋‹ค!

์ •ํ™•ํžˆ ๋งํ•˜์ž๋ฉด ์ธ์ž๋กœ req,res,next ๋ฅผ ๊ฐ–๋Š” ํ•จ์ˆ˜๋Š” ๋ฏธ๋“ค์›จ์–ด๋กœ ๋™์ž‘ ํ•  ์ˆ˜ ์žˆ๋‹ค.

next() ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์œผ๋ฉด ๋ฏธ๋“ค์›จ์–ด ์‚ฌ์ดํด์ด ๋ฉˆ์ถ”๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•ด์•ผ ๋œ๋‹ค.

app.use( ) ์™€ app.Http๋ฉ”์„œ๋“œ

app.use() ๋Š” ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
app.http๋ฉ”์„œ๋“œ ๋Š” ํ•ด๋‹น ๋ฉ”์„œ๋“œ ์š”์ฒญ์— ๋Œ€ํ•ด ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.


๊ณต์‹ ๋ฌธ์„œ
๋ผ์šฐํŒ… ์ฐธ๊ณ 
์ฐธ๊ณ  ๋ธ”๋กœ๊ทธ
๋ฏธ๋“ค์›จ์–ด ์ฐธ๊ณ 

0๊ฐœ์˜ ๋Œ“๊ธ€