Gorilla-Kim/Project

[MEMO APP] Back-end/ REST API-Register (2)

Kim_gorilla 2020. 3. 18. 12:50

 

๐Ÿ‘จ‍๐Ÿ’ป REST API (2)

์ €๋ฒˆ์‹œ๊ฐ„์— ์šฐ๋ฆฌ๋Š” ์‚ฌ์ „์— ๋งŒ๋“ค์–ด๋‘์—ˆ๋˜ ๋ชฝ๊ณ DB์˜ ๋ชจ๋ธ๋“ค์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ REST API์˜ Controller๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

(์ •ํ™•ํžˆ๋Š” ํ‹€๋งŒ ๋งŒ๋“ค์—ˆ์ฃ )

 

์˜ค๋Š˜์€ ๊ทธ๋•Œ ๋งŒ๋“  ๋‘๊ฐœ์˜ ํ•จ์ˆ˜๋“ค์— ๋‚ด์šฉ์„ ์ฑ„์›Œ๋„ฃ์–ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ LocalRegister Controller

ํšŒ์›๊ฐ€์ž…์ ˆ์ฐจ์ด๋‹ˆ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์š”์ฒญ๋œ ํ˜น์€ ๋ณด๋‚ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ „์†ก๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ป๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

 

์•„๋งˆ express ์‚ฌ์šฉํ•˜์…จ๋˜ ๋ถ„๋“ค์ด๋ผ๋ฉด, ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ req, res ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ์„œ req๋ฅผ ํ†ตํ•ด ๊บผ๋‚ด์˜ฌ ์ˆ˜ ์žˆ์—ˆ์„๊ฒ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Koa์—์„œ๋Š” ctx ํ•˜๋‚˜๋งŒ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๊ณ ์žˆ์–ด์š”.

 

์‚ฌ์‹ค ctx ๊ฐ์ฒด์•ˆ์— req, res ๋‘˜๋‹ค ๋“ค์–ด์žˆ์Šต๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ๋Š” request, response๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋“ค์–ด์žˆ์Šต๋‹ˆ๋‹ค.

 

const { body } = ctx.request; ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋ฉด request ์ •๋ณด์—์„œ body์•ˆ์˜ ๋‚ด์šฉ์„ ์ถ”์ถœํ•ด ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

 

ํ•œ๋ฒˆ ์ด body์˜ ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•ด๋ณด๊ณ ์‹ถ์€๋ฐ... ์‚ฌ์‹ค ์ง€๊ธˆ ๋‹น์žฅ์€ ํ™•์ธ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. 

์ด์œ ์ฆ‰์Šจ, ์šฐ๋ฆฌ๊ฐ€ ์„œ๋ฒ„๋กœ ์–ด๋– ํ•œ ๋ฐ์ดํ„ฐ๋„ post ๋ฐฉ์‹์œผ๋กœ ๋ณด๋‚ผ ๋ฐฉ๋ฒ•์ด ์—†๊ณ , ๋˜ ์•„์ง body๋ฅผ ์ฝ์–ด์ค„ ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•ด ์ฃผ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

 

๋ชจ๋“ˆ์€ ๋‚˜์ค‘์— ์šฐ๋ฆฌ๊ฐ€ ์„ค์น˜ํ•ด Back๋‹จ์—์„œ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, post๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋Š” ์ž‘์—…์€ Client๋‹จ ์ฆ‰ Front์—์„œ ํ•ด์ค˜์•ผ ํ•˜๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋ž˜๋„ ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์„ธ์š”, ์„ธ์ƒ์—” ์ •๋ง ํŽธํ•œ ๋„๊ตฌ๋“ค์ด ๋งŽ์ด ์žˆ์œผ๋‹ˆ๊นŒ์š”!

PostMan์ด๋ผ๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ๋ฐ›์•„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด๋ณด๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

PostMan ์„ค์น˜์— ๋Œ€ํ•œ๊ฒƒ์€ ์ด๋ฒˆ์— ํฌ์ŠคํŒ…ํ•˜์ง„ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.
(์‹œ๊ฐ„์ด ๋œ๋‹ค๋ฉด ๋”ฐ๋กœ ํฌ์ŠคํŒ…ํ•ด๋“œ๋ฆด๊ฒŒ์š” ^^)

 

ํฌ์ŠคํŠธ๋งจ์„ ์ด์šฉํ•˜๋ฉด POST๋ฐฉ์‹์œผ๋กœ http://localhost:4000/api/v1.0/auth/register/local ๊ฒฝ๋กœ๋กœ ์ ‘์†ํ–ˆ์„๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ›„ postman์œผ๋กœ ์žฌ ์š”์ฒญํ•ด๋ณด๋ฉด ctx.request ๊ฐ์ฒด์˜ ์ •๋ณด๋„ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

(์•„์ง Body ์ •๋ณด๋Š” ํ™•์ธ์ด ๋ถˆ๊ฐ€๋Šฅํ•ด์š”)

auth.ctrl.js
auth/index.js

 

ํ•˜์ง€๋งŒ ์•„๋ž˜์— ๋ณด๋Š”๊ฒƒ์ฒ˜๋Ÿผ undefined ๋ผ๊ณ  ๋œจ๋Š”๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์–ด์š”

์šฐ๋ฆฌ๊ฐ€ ์•„์ง ์•„๋ฌด ๋ฐ์ดํ„ฐ๋„ ๋ณด๋‚ด์ฃผ์ง€ ์•Š์•„์„œ ์ด๋ ‡๊ฒŒ ๋‚˜์˜ค๋Š”๊ฑด๋ฐ, ํ•œ๋ฒˆ ๋ฐ์ดํ„ฐ๋„ ๋‹ด์•„์„œ ๋ณด๋‚ด์ฃผ๋„๋ก ํ•ด๋ณผ๊ป€๋ฐ์š” ๊ทธ์ „์— GET๊ณผ POST ๋ฐฉ์‹์˜ ์ฐจ์ด๋ฅผ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

GET์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ• ๋•Œ ํ—ค๋”๋ผ๋Š” ์˜์—ญ์— ๋‹ด์•„์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด์ฃผ๊ณ  POST๋Š” ๋ฐ”๋””๋ผ๋Š” ์˜์—ญ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„์„œ ๋ณด๋‚ด์ค๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฐ”๋””๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์‰ฝ๊ฒŒ ์ฝ์–ด์˜ฌ์ˆ˜ ์—†๋Š”๋ฐ์š”, ์ด๋ฅผ ์ฝ์–ด์˜ค๊ธฐ ์œ„ํ•ด์„œ๋Š” parser๋ผ๋Š” ๋ชจ๋“ˆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. 

 

๊ทธ๋ž˜์„œ koa-bodyparser ๋ฅผ ์„ค์น˜ํ•ด ์ค„๊ฒŒ์š” yarn add koa-bodyparser ํ•ด์ฃผ์„ธ์š”.

๊ทธ๋ฆฌ๊ณ  ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์šฐ๋ฆฌ์˜ ์•ฑ์— ์ถ”๊ฐ€ํ•ด์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค. 

(src/index.js๋กœ ์ด๋™ํ•ด์„œ ์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.)

์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๊ฒŒ ๋˜๋ฉด ์šฐ๋ฆฌ๊ฐ€ post๋กœ ๋ณด๋‚ธ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ๋ฆฌ ์•ฑ์—์„œ ์ฝ์–ด์˜ฌ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ•œ๋ฒˆ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‹ค์‹œ auth.ctrl.js ๋กœ ์ด๋™ํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•ด์ฃผ์„ธ์š”.

๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ postman์œผ๋กœ ๋Œ์•„์™€ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์šฐ๋ฆฌ๊ฐ€ ๋ณด๋‚ธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์„œ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฐ์‹์œผ๋กœ ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ›์•„์™€ ์ €์žฅ์„ ํ• ๊ป๋‹ˆ๋‹ค. 

 

์ž ๊ทธ๋Ÿผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ ๋ฐ์ดํ„ฐ๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ํ˜•์‹์— ๋งž๊ฒŒ ์™€์•ผ ์ •ํ™•ํ•œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๊ฐ€ ์ด๋ฃจ์–ด์งˆ๊ป๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ joi๋ผ๋Š” ๋ชจ๋“ˆ์„ ์ด์šฉํ•ด ์ผ์ข…์˜ ํ˜•์‹ ๊ฒ€์ฆ์ ˆ์ฐจ๋ฅผ ์ง„ํ–‰ํ•ด ๋ณด๋„๋ก ํ• ๊ฒŒ์š”!

(https://www.npmjs.com/package/joi)

 

์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•ด joi๋„ ์„ค์น˜ํ•ด ์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค. yarn add joi

๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ์ด์šฉํ•ด์„œ ์šฐ๋ฆฌ๊ฐ€ ๋ณด๋‚ด์ค„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ฆํ•ด ๋ณผ๊ฒŒ์š”.

์šฐ๋ฆฌ๊ฐ€ ๋ณด๋‚ด์ค„ ๋ฐ์ดํ„ฐ๋Š” ํšŒ์›๊ฐ€์ž…์ž„์œผ๋กœ, ์ด 3๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. (displayName, email, password)

 

์ด๋“ค์„ ๊ฒ€์ฆํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์•„์š”.

const Joi = require('joi');

// local register function
exports.localRegister = async (ctx) => {
  const { body } = ctx.request;

  const schema = Joi.object({
    displayName: Joi.string().regex(/^[a-zA-Z0-9ใ„ฑ-ํžฃ]{3,12}$/).required(),
    email: Joi.string().email().required(),
    password: Joi.string().min(6).max(30),
  });
};

// local login function
exports.localLogin = async (ctx) => {

};

Displayname์€ ํ•œ๊ธ€ ์˜์–ด ๋‘˜๋‹ค ๊ฐ€๋Šฅํ•˜๊ณ  ์ตœ์†Œ3์ž์—์„œ 12์ž๊นŒ์ง€ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ–ˆ๊ณ , ์ด๋ฉ”์ผ์€ ์ด๋ฉ”์ผํ˜•์‹๋งŒ ๊ทธ๋ฆฌ๊ณ  ํŒจ์Šค์›Œ๋“œ๋Š” 6~30์ž ์‚ฌ์ด๋งŒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

(pw๋ฅผ ์•”ํ˜ธํ™”ํ•ด์„œ ์ €์žฅํ•ด์•ผํ•˜์ง€๋งŒ ์ด๋Š” ๋‚˜์ค‘์— ์ž‘์—…ํ•ด์ฃผ๋„๋ก ํ• ๊ฒŒ์š”)

 

์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐ›์•„์˜จ body ์ •๋ณด๊ฐ€ schema ๊ธฐ์ค€์— ๋งž๋Š”์ง€ ๊ฒ€์ฆ์„ ์ง„ํ–‰ํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ  ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  schema ์•„๋ž˜์— ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.

const result = Joi.validate(body, schema);
console.log(result);

๊ทธ๋ฆฌ๊ณ  ์„œ๋ฒ„๋ฅผ ์‹คํ–‰์‹œํ‚จํ›„ ์•„๋ž˜์™€๊ฐ™์ด ํ˜•์‹์— ๋งž์ง€์•Š๊ฒŒ ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ˜•์‹์— ๋งž์ง€์•Š๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด์ฃผ๋ฉด ์•„๋ž˜์™€๊ฐ™์ด ERROR๊ฐ€ ์ถœ๋ ฅ์ด๋˜์–ด์ง‘๋‹ˆ๋‹ค.

์ด์ œ ๊ฐ„๋‹จํ•˜๊ฒŒ if๋ฌธ์„ ์ด์šฉํ•ด์„œ result์— error๋ฅผ ํ†ตํ•ด ์—๋Ÿฌ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ด ์ฃผ๋ฉด ๋ ๊ฑฐ๊ฐ™์Šต๋‹ˆ๋‹ค. 

๋‹ค์Œ์˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋”ฐ๋ผ ์ž…๋ ฅํ•ด๋ณผ๊ฒŒ์š”.

// local register function
exports.localRegister = async (ctx) => {
  const { body } = ctx.request;

  const schema = Joi.object({
    displayName: Joi.string().regex(/^[a-zA-Z0-9ใ„ฑ-ํžฃ]{3,12}$/).required(),
    email: Joi.string().email().required(),
    password: Joi.string().min(6).max(30),
  });
  const result = Joi.validate(body, schema);

  // Schema error
  if (result.error) {
    ctx.status = 400;
    ctx.body = 'Schema error';
    // eslint-disable-next-line no-useless-return
    return;
  }
};

๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

๊ฒฐ๊ณผ๋กœ ์•„๋ž˜์˜ ์‚ฌ์ง„์˜ ํ•˜๋‹จ์ฒ˜๋Ÿผ Schema error ๋ผ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ง€์ •ํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜์˜ค๋Š”๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜•์‹์— ๋งž์ถฐ ๋ณด๋‚ด์ฃผ๊ฒŒ ๋œ๋‹ค๋ฉด body ์•ˆ์—๋Š” displayName, email, password ์ •๋ณด๊ฐ€ ๋“ค์–ด์žˆ์„๊ฒ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด const { displayName, email, password } = body๋ฅผ ํ†ตํ•ด ์ถ”์ถœ์ด ๊ฐ€๋Šฅํ•ด์งˆ๊ป๋‹ˆ๋‹ค.

ํ•œ๋ฒˆ ์•„๋ž˜์˜ ์†Œ์Šค๋กœ ์ˆ˜์ •ํ•ด์„œ ํ™•์ธ์„ ํ•ด๋ณด์ฃ .

// local register function
exports.localRegister = async (ctx) => {
  const { body } = ctx.request;

  const schema = Joi.object({
    displayName: Joi.string().regex(/^[a-zA-Z0-9ใ„ฑ-ํžฃ]{3,12}$/).required(),
    email: Joi.string().email().required(),
    password: Joi.string().min(6).max(30),
  });
  const result = Joi.validate(body, schema);

  // Schema error
  if (result.error) {
    ctx.status = 400;
    ctx.body = 'Schema error';
    // eslint-disable-next-line no-useless-return
    return;
  }
  const { displayName, email, password } = body;
  console.log(displayName, email, password);
};

๊ทธ๋ฆฌ๊ณ  ํฌ์ŠคํŠธ๋งจ์— ๊ฐ€์„œ ์•„๋ž˜์˜ ๋‚ด์šฉ์„ ๋‹ด์•„ ๋ณด๋‚ธํ›„ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

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

์ด์ œ Front์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํ˜•์‹์— ๋งž๊ฒŒ ๋ณด๋‚ด์ฃผ๋ฉด ํŠน์ • ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ด์กŒ์Šต๋‹ˆ๋‹ค.

 

์ด์ œ ์ด ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  DB์— ์ €์žฅํ•˜๋Š” ์†Œ์Šค๋ฅผ ์ž‘์„ฑํ• ๊ป€๋ฐ์š”. ์–ด๋–ป๊ฒŒ ํฌ์ŠคํŒ…์„ ์ž‘์„ฑํ•˜๋‹ค๋ณด๋‹ˆ ๋„ˆ๋ฌด ๊ธธ์–ด์ง„ ๊ด€๊ณ„๋กœ ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ๋งˆ์ € ์ง„ํ–‰์„ ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. : )