2023.03.16 TIL

์ •์Šน์›ยท2023๋…„ 3์›” 19์ผ
0
post-thumbnail

๐Ÿ“’ ๋ชฉ์ฐจ

  • ๐Ÿ“Œ nodemon์„ ํ™œ์šฉํ•˜์—ฌ refresh ๋ฌธ์ œ ํ•ด๊ฒฐํ•˜๊ธฐ
  • ๐Ÿ“Œ ๋ผ์šฐํŒ… (Routing)์ด๋ž€?
  • ๐Ÿ“Œ Rest-API ๋งŒ๋“ค๊ธฐ
  • ๐Ÿ“Œ Rest-API ์š”์ฒญ ์‹ค์Šต (POSTMAN)
  • ๐Ÿ“Œ ํ•ธ๋“œํฐ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ›์•„ ์ธ์ฆ ํ† ํฐ ๋งŒ๋“ค๊ธฐ -> Rest-API๋กœ ๋งŒ๋“ค๊ธฐ
  • ๐Ÿ“Œ Swagger๋ฅผ ํ™œ์šฉํ•œ API-Docs ๋งŒ๋“ค๊ธฐ

๐Ÿ“Œ nodemon์„ ํ™œ์šฉํ•˜์—ฌ refresh ๋ฌธ์ œ ํ•ด๊ฒฐํ•˜๊ธฐ

๊ทธ๋™์•ˆ์€ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๊ฒŒ ๋˜๋ฉด API ์‘๋‹ต์„ ๋ฐ›์•„์˜ค๊ธฐ ์ „์— ๋งŒ์•ฝ ์„œ๋ฒ„๊ฐ€ ์ผœ์ ธ์žˆ์—ˆ๋‹ค๋ฉด ์„œ๋ฒ„๋ฅผ ๋‹ซ๊ณ  ๋‹ค์‹œ ์—ด์–ด์•ผ ํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ์—ˆ๋‹ค.
์ด๋Ÿฌํ•œ ๋ถˆํŽธํ•จ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ๊ฐ€ ์žˆ๋Š”๋ฐ, ๋ฐ”๋กœ nodemon์ด๋‹ค. nodemon์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ๋•Œ๋งˆ๋‹ค ๋งค๋ฒˆ ์„œ๋ฒ„๋ฅผ ๋‹ซ๊ณ ์—ฌ๋Š” ๊ณผ์ •์—†์ด ์ฆ‰๊ฐ์ ์œผ๋กœ ์„œ๋ฒ„๊ฐ€ refresh๋˜์–ด ์ˆ˜์ •๋œ ์ฝ”๋“œ๊ฐ€ ์ ์šฉ๋œ๋‹ค.
์ด์ œ nodemon์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ํ•„์š”ํ•œ ์ ˆ์ฐจ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž!

๋จผ์ €, nodemon์„ ์„ค์น˜ํ•˜๊ณ ์ž ํ•˜๋Š” ํด๋”์— ๋ณธ์ธ์ด ์œ„์น˜ํ•ด ์žˆ๋Š”์ง€ ํ™•์ธ๋ถ€ํ„ฐ ํ•ด์•ผํ•œ๋‹ค. ๊ทธ ํ›„, ํ„ฐ๋ฏธ๋„์— ๋ช…๋ น์–ด ls๋ฅผ ์—ฝ๋ ฅํ•˜์—ฌ package.jsonํŒŒ์ผ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ๋งŒ์•ฝ, package.json์ด ์—†๋‹ค๋ฉด yarn init ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ํŒŒ์ผ์„ ๋งŒ๋“ ๋‹ค. ํ™•์ธ์ด ์ „๋ถ€ ๋๋‚œ๋‹ค๋ฉด yarn add nodemon ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜์—ฌ nodemon์„ ์„ค์น˜ํ•œ๋‹ค. ์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด package.json ํŒŒ์ผ ์•ˆ์— nodemon์ด ์ถ”๊ฐ€๋˜์–ด์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
package.json ํŒŒ์ผ์— scripts๋ถ€๋ถ„์„ ์ž‘์„ฑํ•˜์—ฌ์•ผ ํ•œ๋‹ค. scripts ๋ถ€๋ถ„์˜ ์ž‘์„ฑ์„ ํ†ตํ•ด ์šฐ๋ฆฌ๊ฐ€ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, ์›ํ•˜๋Š” ๋ช…๋ น์–ด๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜๋ฅผ ๋ณด๊ฒŒ ๋˜๋ฉด start:dev๋ผ๋Š” ๋ช…๋ น์–ด๋ฅผ ๋งŒ๋“  ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

{
  "name": "03-01-rest-api-express",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
	"type": "module",
  "scripts": {
    "start:dev": "nodemon index.js"
  },
  "dependencies": {
    "express": "^4.18.1",
    "nodemon": "^2.0.19"
  }
}

์ด์ œ๋ถ€ํ„ฐ yarn start:dev๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ ์—ด๋ฆฌ๊ฒŒ ๋œ๋‹ค. ๋ฌผ๋ก  ์ž์‹ ์ด ์›ํ•  ๋•Œ, script ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•˜๋ฉด ๋‹ค๋ฅธ ๋ช…๋ น์–ด๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ„ฐ๋ฏธ๋„์„ ๋ณด๋ฉด start:dev ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ nodemon์ด ์ž‘๋™๋˜์–ด ๋ณ„๋„๋กœ ์„œ๋ฒ„๋ฅผ ์—ด๊ณ ๋‹ซ์ง€ ์•Š์•„๋„ ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ๋ฐ”๋กœ ์ ์šฉ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Nodemon ์„ค์น˜ํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๋ฒ• ์ •๋ฆฌ

  1. ์„ค์น˜ํ•˜๊ณ ์žํ•˜๋Š” ํด๋”์˜ ์œ„์น˜ ํ™•์ธํ•˜๊ธฐ
  2. pcackage.jsonํŒŒ์ผ ์œ ๋ฌด ํ™•์ธํ•˜๊ธฐ (์—†๋‹ค๋ฉด yarn initํ•˜์—ฌ ๋งŒ๋“ค๊ธฐ)
  3. yarn add nodemon ๋ช…๋ น์–ด ์ž…๋ ฅํ•˜์—ฌ nodemon ์„ค์น˜ํ•˜๊ธฐ
  4. package.jsonํŒŒ์ผ์•ˆ์— nodemon์ถ”๊ฐ€๋˜์—ˆ๋Š”์ง€ ํ™•์ธ ํ›„ scripts๋ถ€๋ถ„ ์ž‘์„ฑํ•˜๊ธฐ (์‹œ์ž‘ ๋ช…๋ น์–ด ๋งŒ๋“ค๊ธฐ)

๐Ÿ“Œ ๋ผ์šฐํŒ… (Routing)์ด๋ž€?

๋ผ์šฐํŒ…์ด๋ž€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญ(Request)๋ฅผ ํ–ˆ์„ ๋•Œ, ์‘๋‹ต(Response)ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.
๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

app: express์˜ ์ธ์Šคํ„ด์Šค
METHOD: HTTP์˜ ๋ฉ”์„œ๋“œ(POST, PUT, DELETE, GET)
PATH: ์„œ๋ฒ„์—์„œ์˜ ๊ฒฝ๋กœ
HANDLER: ๋ผ์šฐํ„ฐ๊ฐ€ ์ผ์น˜ํ•  ๋•Œ, ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜

app.METHOD(PATH, HANDLER)
// ํ™ˆํŽ˜์ด์ง€์—์„œ 'Hello World!๋กœ ์‘๋‹ต'
app.get('/', function (req, res) {
  res.send('Hello World!');
});
// user ๋ผ์šฐํŠธ์— ๋Œ€ํ•œ PUT ์š”์ฒญ์— ์‘๋‹ต
app.put('/user', function (req, res) {
  res.send('Got a PUT request at /user');
});

๐Ÿ“Œ Rest-API ๋งŒ๋“ค๊ธฐ

โœ… ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒํ•˜๋Š” API ๋งŒ๋“ค๊ธฐ

Rest-api์—์„œ ์กฐํšŒํ•˜๋Š” ๋ฉ”์„œ๋“œ๋Š” GET์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋งŒ์•ฝ /boards๋ผ๋Š” ์—”๋“œํฌ์ธํŠธ๋กœ GET ์š”์ฒญ์ด ๋“ค์–ด์˜จ๋‹ค๋ฉด, ๋ฐ์ดํ„ฐ๊ฐ€ ์กฐํšŒ๋  ์ˆ˜ ์žˆ๋„๋ก ๋กœ์ง์„ ์ž‘์„ฑํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

์•„์ง ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ ‘์†ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ถ€๋ถ„์€ ํ•™์Šตํ•˜์ง€ ๋ชปํ•ด ๋‹น์žฅ์€ ๊ฒฐ๊ณผ๊ฐ’์„ ํ•˜๋‚˜ํ•˜๋‚˜ ์ž‘์„ฑํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ค์Šต์„ ์ง„ํ–‰ํ–ˆ๋‹ค.

๋ณดํ†ต ๋ฐ์ดํ„ฐ๋Š” ํ•˜๋‚˜์˜ ๊ฐ’์œผ๋กœ๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ๋Š” ๋งŽ์ด ์—†๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜์ ์œผ๋กœ ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์„ ๋•Œ๋Š” ๋ฐฐ์—ด ์•ˆ์— ๊ฐ์ฒด๊ฐ€ ๋“ค์–ด์žˆ๋Š” ํ˜•ํƒœ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.
์ฆ‰, ๊ฒŒ์‹œ๊ธ€ ํ•˜๋‚˜๋Š” ๊ฐ์ฒด๋กœ ํ‘œํ˜„ํ•˜๊ณ , ๊ฒŒ์‹œ๊ธ€๋“ค์„ ๋ชจ์•„ result๋ผ๋Š” ํ•˜๋‚˜์˜ ๋ฐฐ์—ด์— ๋‹ด๋Š” ํ˜•์‹์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.

์•„๋ž˜์˜ getํ•จ์ˆ˜๋Š” ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ๋ฐ›๊ณ  ์žˆ์œผ๋ฉฐ, req์™€ res๋ผ๋Š” ๋ณ€์ˆ˜๋“ค์„ ๋ฐ›๊ณ  ์žˆ๋‹ค. req๋Š” (request)๋ฅผ ์ค„์—ฌ์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ณ€์ˆ˜๋ช…์ด๋ฉฐ, ์—ฌ๊ธฐ์—๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ณด๋‚ธ HTTP ์š”์ฒญ์ด ๋“ค์–ด์žˆ๋‹ค.
res๋Š” (response)๋ฅผ ์ค„์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋ณ€์ˆ˜๋ช…์ด๋ฉฐ, ์„œ๋ฒ„์—์„œ ๋ธŒ๋ผ์šฐ์ €๋กœ ์‘๋‹ต์„ ๋ณด๋‚ผ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

// index.js
// const express = require('express')
import express from 'express'

const app = express()

app.get('/boards', (req, res) => {
  // 1. ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ๋กœ์ง => DB์— ์ ‘์†ํ•ด์„œ ๋ฐ์ดํ„ฐ ๊บผ๋‚ด์˜ค๊ธฐ
	const result = [
		{ number: 1, writer: "์ฒ ์ˆ˜", title: "์ œ๋ชฉ์ž…๋‹ˆ๋‹ค~~", contents: "๋‚ด์šฉ์ด์—์š”!!!" },
    { number: 2, writer: "์˜ํฌ", title: "์˜ํฌ์ž…๋‹ˆ๋‹ค~~", contents: "์˜ํฌ์ด์—์š”!!!" },
    { number: 3, writer: "ํ›ˆ์ด", title: "ํ›ˆ์ด์ž…๋‹ˆ๋‹ค~~", contents: "ํ›ˆ์ด์ด์—์š”!!!" },
  ]

  // 2. ๊บผ๋‚ด์˜จ ๊ฒฐ๊ณผ ์‘๋‹ต ์ฃผ๊ธฐ
  res.send(result);
});

app.listen(3000, () => {
  console.log("๋ฐฑ์—”๋“œ API ์„œ๋ฒ„๊ฐ€ ์ผœ์กŒ์–ด์š”!!!")
})

์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ๊ฒŒ์‹œ๊ธ€์„ ๋“ฑ๋กํ•˜๋Š” API๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž!
๋ฐ์ดํ„ฐ๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋Š” POST์ด๋‹ค. ๋”ฐ๋ผ์„œ /boards๋กœ POST์š”์ฒญ์ด ์™”์„ ๋•Œ, ๋ฐ์ด๋ฒ„๋ฒ ์ด์Šค์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ€์ •์„ ํ•˜๊ณ  '๊ฒŒ์‹œ๋ฌผ ๋“ฑ๋ก์— ์„ฑ๊ณตํ•˜์˜€์Šต๋‹ˆ๋‹ค!!'๋ผ๋Š” ์‘๋‹ต ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋„๋ก ํ•ด๋ณด์ž.

ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์—์„œ ๋ณด๋‚ธ(request) ๋ฐ์ดํ„ฐ๋Š” req์— ์ €์žฅ ๋˜์–ด ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๊ตฌ์ฒด์ ์œผ๋กœ ์‚ดํŽด๋ณด๊ฒŒ ๋˜๋ฉด ์‹ค์ œ ๋ฐ์ดํ„ฐ๋Š” req.body์•ˆ์— ๋‹ด๊ฒจ์ ธ ์˜ค๊ฒŒ ๋œ๋‹ค.

๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” req.body ๊ฐ์ฒด ์•ˆ์— ์žˆ๋Š” ๊ฐ’์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ํ™•์ธ์„ ํ•˜๊ณ  res.send()๋ฅผ ํ†ตํ•ด ์‘๋‹ต ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ๋‹ค. ์ด๋ฒˆ ์‹ค์Šต๋•Œ๋Š” ์•„์ง ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋ฐฐ์šฐ์ง€ ๋ชปํ•ด ํ•˜๋“œ์ฝ”๋”ฉ์œผ๋กœ ๋™์ž‘์ด ์ด๋ฃจ์–ด์กŒ์ง€๋งŒ, ํ–ฅํ›„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ•™์Šต์„ ํ†ตํ•ด api๋ฅผ ์™„์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ง€๊ธˆ์˜ ํ•™์Šต ๋กœ์ง์ด ๋งค์šฐ ์ค‘์š”ํ•˜๋‹ค!!

// index.js

// const express = require('express')
import express from 'express';

const app = express();

app.get('/boards', (req, res) => {
  // 1. ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ๋กœ์ง => DB์— ์ ‘์†ํ•ด์„œ ๋ฐ์ดํ„ฐ ๊บผ๋‚ด์˜ค๊ธฐ
	const result = [
		{ number: 1, writer: "์ฒ ์ˆ˜", title: "์ œ๋ชฉ์ž…๋‹ˆ๋‹ค~~", contents: "๋‚ด์šฉ์ด์—์š”!!!" },
    { number: 2, writer: "์˜ํฌ", title: "์˜ํฌ์ž…๋‹ˆ๋‹ค~~", contents: "์˜ํฌ์ด์—์š”!!!" },
    { number: 3, writer: "ํ›ˆ์ด", title: "ํ›ˆ์ด์ž…๋‹ˆ๋‹ค~~", contents: "ํ›ˆ์ด์ด์—์š”!!!" },
  ]

  // 2. ๊บผ๋‚ด์˜จ ๊ฒฐ๊ณผ ์‘๋‹ต ์ฃผ๊ธฐ
  res.send(result);
});

app.post('/boards', (req, res) => {
  // 1. ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ณด๋‚ด์ค€ ๋ฐ์ดํ„ฐ ํ™•์ธํ•˜๊ธฐ
	console.log(req)
  console.log("=========================")
  console.log(req.body) // ์ถ”๊ฐ€
	
	// 2. DB์— ์ ‘์† ํ›„, ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ => ๋ฐ์ดํ„ฐ ์ €์žฅํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •

  // 3. DB์— ์ €์žฅ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ธŒ๋ผ์šฐ์ €์— ์‘๋‹ต(response) ์ฃผ๊ธฐ
  res.send("๊ฒŒ์‹œ๋ฌผ ๋“ฑ๋ก์— ์„ฑ๊ณตํ•˜์˜€์Šต๋‹ˆ๋‹ค.")
});

app.listen(3000, () => {
  console.log("๋ฐฑ์—”๋“œ API ์„œ๋ฒ„๊ฐ€ ์ผœ์กŒ์–ด์š”!!!");
});

๐Ÿ“Œ Rest-API ์š”์ฒญ ์‹ค์Šต (POSTMAN)

์ง€๊ธˆ๊นŒ์ง€ ์„œ๋ฒ„๋ฅผ ์—ฌ๋Š” ๊ฒƒ๋„ ๋ฐฐ์šฐ๊ณ , api๋กœ ์š”์ฒญ์„ ๋ณด๋ƒˆ์„ ๋•Œ, ์‘๋‹ต์„ ๋ฐ›๋Š” ๋กœ์ง๋„ ํ•™์Šตํ•˜์˜€๋‹ค.
์ด์ œ ์‹ค์ œ๋กœ api์— ์š”์ฒญ์„ ๋ณด๋‚ด๋ณด๋„๋ก ํ•˜์ž!
rest-api ์‹ค์Šต์„ ์œ„ํ•ด POSTMAN์„ ํ™œ์šฉํ•ด๋ณด๋„๋ก ํ•˜์ž.
postman ํŽ˜์ด์ง€์— ์ ‘์†ํ•˜์—ฌ api์— ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ๋จผ์ € ์กฐํšŒ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ์ธ GET์„ ์„ ํƒํ•˜๊ณ ,
URL์„ ์ ์–ด์ค€๋‹ค. ์—ฌ๊ธฐ์„œ ํฌํŠธ๋ฒˆํ˜ธ๊ฐ€ 3000๋ฒˆ์ธ ์ด์œ ๋Š” ์•ž์„œ ์šฐ๋ฆฌ๊ฐ€ 3000๋ฒˆ ํฌํŠธ๋ฒˆํ˜ธ๋กœ ์„ค์ •์„ ํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์ด์ œ ๋ชจ๋“  ์ค€๋น„๋Š” ๋์ด๋‚ฌ๋‹ค. api ๋กœ์ง์ด ์ด์ƒ์ด ์—†๋‹ค๋ฉด, send ๋ฒ„ํŠผ ํด๋ฆญ ์ดํ›„, ๊ฒฐ๊ณผ๊ฐ€ ์•„๋ž˜์ฒ˜๋Ÿผ ์‘๋‹ตํ•ด์ฃผ๊ฒŒ๋œ๋‹ค.

๋‹ค์Œ์€ ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก์„ ํ•ด๋ณด์ž!
์•ž์„œ ํ•ด๋ณธ ์กฐํšŒ์™€ ์ „์ฒด์ ์ธ ๋งฅ๋ฝ์€ ๋น„์Šทํ•˜์ง€๋งŒ, ์ฐจ์ด์ ์ด ์กด์žฌํ•œ๋‹ค.
๋จผ์ €, ๋ฉ”์†Œ๋“œ๋ฅผ ๋“ฑ๋ก์„ ํ•˜๊ธฐ ์œ„ํ•ด POST๋กœ ๊ต์ฒดํ•œ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๊ฒŒ์‹œ๋ฌผ์„ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. ์ด ๋ฐ์ดํ„ฐ๋Š” body์— ๋‹ด๊ฒจ์˜ค๋Š” ๋ฐ์ดํ„ฐ์ด๋‹ค.
์ข€ ๋” ๊ตฌ์ฒด์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด req.body์•ˆ์— ๋‹ด๊ฒจ์žˆ๋‹ค.
์ด์ œ body ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ๋’ค, rawํ˜•์‹์˜ JSON์„ ์„ ํƒํ•˜๊ณ  ์•„๋ž˜์˜ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
send ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ฒŒ ๋˜๋ฉด '๊ฒŒ์‹œ๋ฌผ ๋“ฑ๋ก์— ์„ฑ๊ณตํ•˜์˜€์Šต๋‹ˆ๋‹ค'๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋œ๋‹ค.

โœ… app.use(express.json())

POSTMAN์—์„œ ์‘๋‹ต์„ ํ™•์ธํ•œ ํ›„, ์š”์ฒญ ๊ฐ’์ด ์ž˜๋“ค์–ด์™”๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ฝ˜์†”์ฐฝ์„ ํ™•์ธํ•ด๋ณด๋ฉด req๋Š” ์ž˜ ๋‚˜์™”์ง€๋งŒ req.body๋Š” undefined๊ฐ€ ๋‚˜์˜จ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
์–ด์งธ์„œ ๊ทธ๋Ÿฐ ๊ฒƒ์ผ๊นŒ?
expressํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ jsonํ˜•ํƒœ๋ฅผ ์ง€์›ํ•˜๊ณ  ์žˆ์ง€ ์•Š๋‹ค!!
๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„์—์„œ json์„ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก app.use(express.json())์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์–ด์•ผ ์ •์ƒ์ ์œผ๋กœ req.body๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.

// index.js

import express from 'express';

const app = express();

app.use(express.json()); // ์ถ”๊ฐ€๋œ ์ฝ”๋“œ
app.get('/boards', (req, res) => {

// ... ์ƒ๋žต

๐Ÿ“Œ ํ•ธ๋“œํฐ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ›์•„ ์ธ์ฆ ํ† ํฐ ๋งŒ๋“ค๊ธฐ -> Rest-API๋กœ ๋งŒ๋“ค๊ธฐ

ํ•ธ๋“œํฐ ๋ฒˆํ˜ธ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ž…๋ ฅ ๋ฐ›์•˜๋Š”์ง€ ๊ฒ€์ฆํ•œ ๋’ค, ์ธ์ฆ๋ฒˆํ˜ธ๋ฅผ ์ „์†กํ•ด์ฃผ๋Š” api๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž!!
์•„๋ž˜๋Š” ๋ฒˆํ˜ธ๊ฐ€ ์ •์ƒ์ ์ธ์ง€ ๊ฒ€์ฆํ•˜๋Š” ๋กœ์ง์ด๋‹ค.

	// 1. ํœด๋Œ€ํฐ๋ฒˆํ˜ธ ์ž๋ฆฟ์ˆ˜ ๋งž๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ(10~11์ž๋ฆฌ)
  const isValid = checkPhone(myphone);
  if (isValid === false) return;

  // 2. ํ•ธ๋“œํฐ ํ† ํฐ 6์ž๋ฆฌ ๋งŒ๋“ค๊ธฐ
  const mytoken = getToken();

  // 3. ํ•ธ๋“œํฐ๋ฒˆํ˜ธ์— ํ† ํฐ ์ „์†กํ•˜๊ธฐ
  sendTokenToSMS(myphone, mytoken);

์ด์ œ ์œ„ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ POST ์š”์ฒญ์ด ์™”์„ ๋•Œ, ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” api๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž

myphone ๋ณ€์ˆ˜์— req.body.qqq ์ฆ‰, ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ›์•„ ๊ฒ€์ฆ๊ณผ์ •์„ ๊ฑฐ์นœ ๋’ค, ์ธ์ฆ๋ฒˆํ˜ธ๋ฅผ responseํ•˜์—ฌ ์ „๋‹ฌํ•˜๋Š” ๊ณผ์ •์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.

// index.js
app.post("/tokens/phone", (req, res) => {
  const myphone = req.body.qqq; 

  // 1. ํœด๋Œ€ํฐ๋ฒˆํ˜ธ ์ž๋ฆฟ์ˆ˜ ๋งž๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ(10~11์ž๋ฆฌ)
  const isValid = checkPhone(myphone);
  if (isValid === false) return;

  // 2. ํ•ธ๋“œํฐ ํ† ํฐ 6์ž๋ฆฌ ๋งŒ๋“ค๊ธฐ
  const mytoken = getToken();

  // 3. ํ•ธ๋“œํฐ๋ฒˆํ˜ธ์— ํ† ํฐ ์ „์†กํ•˜๊ธฐ
  sendTokenToSMS(myphone, mytoken);
  res.send("์ธ์ฆ์™„๋ฃŒ!!!");
});

์ถ”๊ฐ€์ ์œผ๋กœ, ์—ฌ๊ธฐ์„œ ๊ทธ๋ƒฅ POSTMAN์„ ํ†ตํ•ด ์š”์ฒญ์„ ๋‚ ๋ฆฌ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด index.js ํŒŒ์ผ ๋‚ด๋ถ€์—๋Š” checkPhone, getToken, sendTokenToSMS ํ•จ์ˆ˜(๊ฒ€์ฆ ๋กœ์ง)์ด ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
๋”ฐ๋ผ์„œ import๋ฅผ ํ†ตํ•ด phone.js์™€ index.js๋ฅผ ์—ฐ๊ฒฐํ•ด์•ผํ•œ๋‹ค.

์ตœ์ข…๋ณธ

// phone.js

export function checkPhone(myphone){
    if(myphone.length < 10 || myphone.length > 11){
        console.log("์—๋Ÿฌ ๋ฐœ์ƒ!!! ํ•ธ๋“œํฐ ๋ฒˆํ˜ธ๋ฅผ ์ œ๋Œ€๋กœ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”!!!")
        return false
    } else {
        return true
    }
}

export function getToken(){
    const result = String(Math.floor(Math.random() * 1000000)).padStart(6, "0")
    console.log(result)
    return result
}

export function sendTokenToSMS(myphone, result){
    console.log(myphone + "๋ฒˆํ˜ธ๋กœ ์ธ์ฆ๋ฒˆํ˜ธ " + result + "๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.")
}

// index.js

import express from 'express'
import { checkPhone, getToken, sendTokenToSMS } from "./phone.js"; // export ๊ฐ€์ ธ์˜ค๊ธฐ

const app = express()
app.use(express.json())

// ...์ƒ๋žต

์ด์ œ POSTMAN์œผ๋กœ ๊ฒ€์ฆ์ด ์ž˜๋˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž!

๐Ÿ“Œ Swagger๋ฅผ ํ™œ์šฉํ•œ API-Docs ๋งŒ๋“ค๊ธฐ

Swagger๊ฐ€ ๋ฌด์—‡์ผ๊นŒ?
swagger๋Š” rest api๋ฅผ ์‰ฝ๊ฒŒ ๋ฌธ์„œํ™”ํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋„๊ตฌ์ด๋‹ค!!
Node.js๋กœ ๋งŒ๋“  api๋ฅผ swagger์™€ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์„ค์น˜ํ•ด์•ผ ํ•˜๋Š” npm ๋ชจ๋“ˆ์ด ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

  1. yarn add swagger-ui-express
  2. swagger-jsdoc

ํ•œ๋ฒˆ์— ์„ค์น˜ํ•˜๊ธฐ
yarn add swagger-ui-express swagger-jsdoc

swagger ๋ฌธ์„œ์™€ ๊ด€๋ จ๋œ ํŒŒ์ผ์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ณดํ†ต swagger ํด๋”๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด ์ž‘์—…์„ ์ง„ํ–‰ํ•œ๋‹ค.

์ด์ œ swagger-jsdocnpm์„ ์ฐธ๊ณ ํ•ด๋ณด์ž!!
์ด ํ›„ ๋งŒ๋“ค๊ณ  ์‹ถ์€ swagger์˜ ํ˜•์‹์„ ์ฐพ๋Š”๋‹ค๋ฉด swagger ํด๋” ์•ˆ์— (api์ด๋ฆ„).swagger.jsํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  npm์˜ ๋‚ด์šฉ์„ ๋„ฃ๋Š”๋‹ค.
์ถ”๊ฐ€์ ์œผ๋กœ swagger๋ฅผ ๋งŒ๋“ค๋•Œ, ๋“ค์—ฌ์“ฐ๊ธฐ์— ๋งค์šฐ ๋ฏผ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ญ์ƒ ๋“ค์—ฌ์“ฐ๊ธฐ๋ฅผ ์‹ ๊ฒฝ์จ์•ผ ํ•œ๋‹ค!!!

/**
 * @swagger
 * /boards:
 *   get:
 *     summary: ๊ฒŒ์‹œ๊ธ€ ๊ฐ€์ ธ์˜ค๊ธฐ
 *     tags: [Board]
 *     parameters:
 *          - in: query
 *            name: number
 *            type: int
 *     responses:
 *       200:
 *         description: ์„ฑ๊ณต
 *         content:
 *           application/json:
 *              schema:
 *                  type: array
 *                  items:
 *                      properties:
 *                          number:
 *                              type: int
 *                              example: 3
 *                          writer:
 *                              type: string
 *                              example: ์ฒ ์ˆ˜
 *                          title:
 *                              type: string
 *                              example: ์ œ๋ชฉ์ž…๋‹ˆ๋‹ค~~~
 *                          contents:
 *                              type: string
 *                              example: ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค!!!
 */
>
/**
 * @swagger
 * /boards:
 *   post:
 *     summary: ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋กํ•˜๊ธฐ
 *     tags: [Board]
 *     responses:
 *          200:
 *              description: ์„ฑ๊ณต
 */

์ด์ œ ๋‹ค์Œ์œผ๋กœ ํ•ด์•ผํ•˜๋Š” ๊ฒƒ์œผ api ๋ฌธ์„œ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค.
swagger ํด๋”์— config.js ํŒŒ์ผ์„ ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด ์„ค์ •์„ ๋ถ„๋ฆฌํ•ด์ฃผ์ž

// config.js
>
export const options = {
    definition: {
      openapi: '3.0.0',
      info: {
        title: '๋‚˜๋งŒ์˜ ๋ฏธ๋‹ˆํ”„๋กœ์ ํŠธ API ๋ช…์„ธ์„œ!!',
        version: '1.0.0',
      },
    },
    apis: ['./swagger/*.swagger.js'], // files containing annotations as above
  };

swagger.json ํŒŒ์ผ์„ ํ†ตํ•ด ์ƒ์„ฑ๋œ ์Šค์›จ๊ฑฐ ๋ฌธ์„œ๋ฅผ express์— ์ œ๊ณตํ•˜๋Š” swagger ui express๋ฅผ ํ™œ์šฉํ•ด๋ณด์ž.
์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

// index.js
>
import swaggerUi from 'swagger-ui-express'
import swaggerJSDoc from 'swagger-jsdoc'
import { options } from './swagger/config.js'
>
// ...์ƒ๋žต
>
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerJSDoc(options)));
>
// ...์ƒ๋žต

์ด์ œ ์„ค์ •ํ•œ ์ฃผ์†Œ์ธ (http://localhost:3000/api-docs/) ์ ‘์†ํ•ด๋ณด๋ฉด api-docs๊ฐ€ ์™„์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๐ŸŒˆ ์˜ค๋Š˜ ํ•˜๋ฃจ

๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ์„œ api๋ฅผ ๋ณธ๊ฒฉ์ ์œผ๋กœ ๋‹ค๋ฃจ๊ธฐ ์‹œ์ž‘ํ•œ ํ•˜๋ฃจ์ธ ๊ฒƒ ๊ฐ™๋‹ค. ๋„ˆ๋ฌด๋‚˜ ๋งŽ์€ ๋‚ด์šฉ์„ ํ•™์Šตํ•˜์—ฌ ์•„์ง ์™„๋ฒฝํžˆ ๋‚ด๊ฒƒ์ด ๋œ๊ฒƒ ๊ฐ™์ง„ ์•Š์ง€๋งŒ, ํ•™์Šตํ•˜๋Š” ๊ณผ์ •์—์„œ ์ฆ๊ฒ๊ฒŒ ๋กœ์ง์„ ์ƒ๊ฐํ•˜๊ณ  ๊ณต๋ถ€ํ•œ ๊ฒƒ ๊ฐ™๋‹ค. ๋ฌผ๋ก  ์ด์ œ ์‹œ์ž‘์ด์ง€๋งŒ ํ•˜๋‚˜์”ฉ ์ฑ„์›Œ๋‚˜๊ฐ€๋ฉฐ, ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ์„œ ๊ฟˆ์„ ์ด๋ฃจ๊ณ  ์‹ถ๋‹ค!!
๋ณต์Šต!!๋ณต์Šต!!๋ณต์Šต!! ๋ณต์Šต์ด ์ œ์ผ ์ค‘์š”ํ•˜๋‹ค!!

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