[MEMO APP] Back-end/ REST API-Register (2)
๐จ๐ป 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 ์ ๋ณด๋ ํ์ธ์ด ๋ถ๊ฐ๋ฅํด์)
ํ์ง๋ง ์๋์ ๋ณด๋๊ฒ์ฒ๋ผ 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์ ์ ์ฅํ๋ ์์ค๋ฅผ ์์ฑํ ๊ป๋ฐ์. ์ด๋ป๊ฒ ํฌ์คํ ์ ์์ฑํ๋ค๋ณด๋ ๋๋ฌด ๊ธธ์ด์ง ๊ด๊ณ๋ก ๋ค์ ํฌ์คํ ์์ ๋ง์ ์งํ์ ํ๋๋ก ํ๊ฒ ์ต๋๋ค. : )