๐Ÿ“ฒ Back-end for Project

๊น€์ฒ ์ค€ยท2022๋…„ 3์›” 3์ผ
0

Back-end

๋ชฉ๋ก ๋ณด๊ธฐ
1/3

๋ฐฑ์—”๋“œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

ํ”„๋กœ์ ํŠธ๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์กดํ•˜๊ณ  ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ๋“ค๊ณผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ €์žฅํ•  ๊ณต๊ฐ„์ด ํ•„์š”ํ•˜๋‹ค.

๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์กดํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” localStorage ,sessionStorage, cookie๋“ฑ์ด ์žˆ์ง€๋งŒ
์‹ค๋ฌด์—์„œ ํ•ต์‹ฌ ๋ฐ์ดํ„ฐ ๋“ฑ์„ ์ €์žฅํ•  ๋•Œ์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๊ณผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์„œ๋ฒ„๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
๋ฐ์ดํ„ฐ๋ฅผ ๋ฌด์ž‘์ • ์„œ๋ฒ„์— ๋‹ด์ง€ ์•Š๊ณ  ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๊ทœ์น™์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฌ๋‹ค.

์ด๋Ÿฌํ•œ ์—ญํ• ์„ ํ•˜๋Š” ๊ฒƒ์ด ์„œ๋ฒ„ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐ ๋ฐฑ์—”๋“œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ผ๊ณ  ํ•œ๋‹ค.

Node.js์™€ Koa

Node.js : ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ตฌ๋™ํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ ์„œ๋ฒ„๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ฃผ๋กœ ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค.
Koa : ์›น ํ”„๋ ˆ์ž„์›Œํฌ
์„œ๋ฒ„๋ฅผ ๋”์šฑ ํŽธ๋ฆฌํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณด์กฐํ•ด์ฃผ๋Š” ์—ญํ• 

์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์–ธ์–ด๋กœ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ javascript๋กœ๋„ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

๋ฐฉ๋ฒ•์€ Node.js๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

Node.js์—์„œ ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ•  ๋•Œ ๋ณดํ†ต Express,Hapi,Koa๋ผ๋Š” ์›น ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
๊ทธ ์ค‘์—์„œ Koa๋ผ๋Š” ์›น ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ๋‹ค.

Koa๋Š” ๋ฏธ๋“ค์›จ์–ด ๊ธฐ๋Šฅ๋งŒ ๊ฐ–์ถ”๊ณ  ์žˆ์œผ๋ฉฐ ๋‚˜๋จธ์ง€๋Š” ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ ์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

๋˜ํ•œ, Koa๋Š” async/await ๋ฌธ๋ฒ•์„ ์ง€์›ํ•˜๊ณ  ์žˆ์–ด ๋น„๋™๊ธฐ ์ž‘์—…์„ ๋” ํŽธํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์„ค๊ณ„

1. ๋งŒ๋“ค๊ณ ์ž ํ•˜๋Š” ํ”„๋กœ์ ํŠธ์— front-end์™€ back-end ํด๋”๋ฅผ ๊ตฌ๋ถ„์ง€์–ด ๋งŒ๋“ค์–ด ๋†“๋Š”๋‹ค.

2. npm init -y
package.json์˜ ๊ฐ’๋“ค์„ defalut๋กœ ์„ค์ •ํ•œ package.jsonํŒŒ์ผ ์ƒ์„ฑ

3. ์›น ํ”„๋ ˆ์ž„์›Œํฌ ์„ค์น˜ (npm install koa)

ESLint์™€ prettier ์„ค์ •(ํ•„์ˆ˜ ์•„๋‹˜)

ESLint : ์ฝ”๋“œ ๋ฌธ๋ฒ• ๊ฒ€์‚ฌ
prettier : ์ฝ”๋“œ๋ฅผ ๋” ๊น”๋”ํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ต์Šคํ…์…˜

ESLint ์„ค์ •

  • npm add eslint --save -dev
    ๋ฐฐํฌํ•  ๋•Œ๋Š” ํฌํ•จ๋˜์ง€์•Š๊ณ  ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“ˆ

  • npm init @eslint/config
    eslint ๊ธฐ๋ณธ ์„ค์ •์„ ์œ„ํ•œ ๋ช…๋ น์–ด
    ์ด์ „์—๋Š” npm run eslint --init์ด์˜€์ง€๋งŒ ๋ช…๋ น์–ด๊ฐ€ ๋ฐ”๋€œ.

๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด .eslintrc.jsonํŒŒ์ผ์ด ์ƒ์„ฑ๋  ๊ฒƒ์ด๋‹ค.

Prettier ์„ค์ •

  • ๋””๋ ‰ํ„ฐ๋ฆฌ์— .prettierrc ํŒŒ์ผ์„ ๋งŒ๋“ ๋‹ค.

  • npm add eslint-congif-prettier
    prettier์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ์ฝ”๋“œ ์Šคํƒ€์ผ์€ ESLint์—์„œ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋„๋ก eslint-congif-prettier๋ฅผ ์„ค์น˜ํ•˜์—ฌ ๊ด€๋ฆฌ

4. ์„œ๋ฒ„ ๋„์šฐ๊ธฐ
๋””๋ ‰ํ„ฐ๋ฆฌ์— src๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  index.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ ๋’ค ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค.

const Koa = require("koa")

const app = new Koa()

app.use(ctx => {
	ctx.body = "hello world"
})

app.listen(4000,() => {
	console.log("Listening to port 4000")
})
  • app = new Koa()

์„ค์น˜ํ•œ koa ๋ชจ๋“ˆ์„ ๋ถˆ๋Ÿฌ์™€ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•ด ๋ณ€์ˆ˜์— ํ• ๋‹นํ•˜๋ฉด ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉํ•ด ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • app.listen(port,callback)

app.listen()์€ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.
์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ๋Š” ์„œ๋ฒ„์˜ ํฌํŠธ๋ฒˆํ˜ธ๋ฅผ ์„ค์ •ํ•˜๊ณ  ๋‘๋ฒˆ ์งธ ์ธ์ž๋กœ๋Š” ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘๋˜๋ฉด ์‹คํ–‰๋  ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•ด์ค€๋‹ค.

  • app.use(ctx , next)

app.use๋Š” ๋ฏธ๋“ค์›จ์–ด ํ•จ์ˆ˜๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋“ฑ๋กํ•ด์ค€๋‹ค.
app.use()๋Š” this๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ฒด์ด๋‹์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๋ฏธ๋“ค์›จ์–ด ํ•จ์ˆ˜(middle ware function)
๋ฏธ๋“ค์›จ์–ด ํ•จ์ˆ˜๋Š” req(์š”์ฒญ) ๊ฐ์ฒด, res(์‘๋‹ต) ๊ฐ์ฒด, ๊ทธ๋ฆฌ๊ณ  ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์š”์ฒญ-์‘๋‹ต ์‚ฌ์ดํด ๋„์ค‘ ๊ทธ ๋‹ค์Œ์˜ ๋ฏธ๋“ค์›จ์–ด ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์—‘์„ธ์Šค ๊ถŒํ•œ์„ ๊ฐ–๋Š” ํ•จ์ˆ˜์ด๋‹ค.
๋ฏธ๋“ค์›จ์–ด๋ž€ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์š”์ฒญ์ด ์˜ค๊ณ  ๊ทธ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ์‘๋‹ตํ•˜๋ ค๋Š” ์ค‘๊ฐ„(๋ฏธ๋“ค)์— ๋ชฉ์ ์— ๋งž๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š”, ๋งํ•˜์ž๋ฉด ๊ฑฐ์ณ๊ฐ€๋Š” ํ•จ์ˆ˜๋“ค์ด๋ผ๊ณ  ๋ณด๋ฉด ๋˜๊ฒ ๋‹ค.
reference : middle ware function

์ฒซ ๋ฒˆ์งธ ์ธ์ž ctx๋Š” context์˜ ์ค„์ž„๋ง๋กœ ์›น ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ง€๋‹ˆ๊ณ  ์žˆ๋‹ค.

๋‘ ๋ฒˆ์งธ ์ธ์ž next๋Š” ํ˜„์žฌ ์ฒ˜๋ฆฌ ์ค‘์ธ ๋ฏธ๋“ค์›จ์–ด์˜ ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

๋ฏธ๋“ค์›จ์–ด๋ฅผ ๋“ฑ๋กํ•˜๊ณ  next ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด , ๊ทธ ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

next()๋Š” promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๋‹ค์Œ์— ์ฒ˜๋ฆฌํ•ด์•ผํ•  ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ๋๋‚˜์•ผ ์™„๋ฃŒ๋œ๋‹ค.

  • async/await
    Koa๋Š” async/await๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

5. nodemon ์‚ฌ์šฉ

์„œ๋ฒ„์— ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„๋ฅผ ์žฌ์‹œ์ž‘ํ•ด์•ผํ•œ๋‹ค.
(node index.js)

์ด๋ฅผ ๋ณด์™„ํ•˜๊ธฐ์œ„ํ•ด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„์— ๋ฐ˜์˜๋  ์ˆ˜ ์žˆ๋„๋ก nodemon ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ž.

  • npm install nodemon --save-dev

๊ทธ๋ฆฌ๊ณ  ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ด์•ผ nodemon์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก package.json์˜ script ๋ช…๋ น์–ด์— ๋“ฑ๋กํ•ด๋‘์ž.

"scripts" : {
	"start" : "node src",
    "start:dev" : "nodemon --watch src/ src/index.js"
}

npm run start:dev ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜์—ฌ nodemon์„ ์‹คํ–‰ํ•œ๋‹ค.

6. koa-router

  • npm i koa-router

๋‹ค๋ฅธ ์ฃผ์†Œ์— ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ฒŒ ํ•˜๋Š” koa ๋ผ์šฐํŒ… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.


const Koa = require("koa")
const Router = require("koa-router")

const app = new Koa()
const router = new Router()

router.get("/",ctx => {
	ctx.body = "Home"
})

router.get("/about", ctx => {
	ctx.body = "About"
})

app.use(router.routes()).use(router.allowedMethods()) //app.use chaining

app.listen(4000,() => {
	console.log("Listening to port 4000")
})
  • new Router() / router.get...
    koa-router ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ถˆ๋Ÿฌ์™€ router ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ์„ค์ •ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ๋กœ๋ณ„ ์ž‘์—…์„ ํ•ด์ค€๋‹ค.

  • app.use(router.routes()).use(router.allowedMethods())
    ์„œ๋ฒ„์— router๋ฅผ ๋“ฑ๋กํ•ด์ค€๋‹ค.

  • ๋ผ์šฐํŠธ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ์ฟผ๋ฆฌ
    ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ์ฟผ๋ฆฌ๋ฅผ ์กฐํšŒํ•  ๋•Œ์—๋Š” ctx๋กœ ์กฐํšŒ๋ฅผ ํ•œ๋‹ค.


router.get("/about/:name", ctx => {  
  const {name} = ctx.params	
})

router.get("/about" , ctx => {
	const {id} = ctx.query
})

7. REST API

ํด๋ผ์ด์–ธํŠธ์ธก์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ์œ„ํ•ด์„œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ”๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์„œ๋ฒ„๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•ด์•ผํ•œ๋‹ค.

์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ ๋ฉ”์„œ๋“œ์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜์—ฌ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•ด์ค€๋‹ค.

์ด ๋•Œ ์š”์ฒญ ๋ฉ”์„œ๋“œ๋ฅผ Rest API๋ผ๊ณ  ํ•œ๋‹ค.

REST API๋Š” GET,POST,DELETE,PUT,PATCH ๋“ฑ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค.
์ด ๋ฉ”์„œ๋“œ๋“ค์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์˜ ์กฐํšŒ,์ถ”๊ฐ€,์‚ญ์ œ,์ˆ˜์ • ๋“ฑ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์œ„ ๋ฉ”์„œ๋“œ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ํ•˜๋ฉด ์„œ๋ฒ„์—์„œ๋Š” ํ•ด๋‹น ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๊ฒฝ์šฐ ๊ฐ ์š”์ฒญ๋ฉ”์„œ๋“œ์— ๋”ฐ๋ผ ์ž‘์—…์„ ์„ค์ •ํ•ด์ค€๋‹ค.

NEXT

๋‹ค์Œ์œผ๋กœ ๋งŒ๋“  ์„œ๋ฒ„์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ REST API๋กœ ์ ‘๊ทผํ•˜์—ฌ ์ž‘์—…ํ•˜๋Š” ๊ฒƒ์„ ๊ณ„์† ํ•ด๋ณด์ž.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” mongoDB๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค.

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