-
koa ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฏธ๋ค์จ์ด์ ๋ฐฐ์ด๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค. ์กฐ๊ธ ์ ์ฝ๋์์ app.useํจ์๋ฅผ ์ฌ์ฉํ์ต๋๋ค. ์ด ํจ์๋ ๋ฏธ๋ค์จ์ด ํจ์๋ฅผ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ฑ๋กํฉ๋๋ค.
-
๋ฏธ๋ค์จ์ด ํจ์๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค.
(ctx, next) => {}
-
koa์ ๋ฏธ๋ค์จ์ด ํจ์๋ ๋ ๊ฐ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์ต๋๋ค. ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ ์กฐ๊ธ ์ ์๋ ์ฌ์ฉํ ctx๋ผ๋ ๊ฐ์ด๊ณ , ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ next ์ ๋๋ค.
-
ctx๋ context์ ์ค์๋ง๋ก ์น ์์ฒญ๊ณผ ์๋ต์ ๊ดํ ์ ๋ณด๋ฅผ ์ง๋๊ณ ์์ต๋๋ค. next๋ ํ์ฌ ์ฒ๋ฆฌ ์ค์ธ ๋ฏธ๋ค์จ์ด์ ๋ค์ ๋ฏธ๋ค์จ์ด๋ฅผ ํธ์ถํ๋ ํจ์์ ๋๋ค. ๋ฏธ๋ค์จ์ด๋ฅผ ๋ฑ๋กํ๊ณ next ํจ์๋ฅผ ํธ์ถํ์ง ์์ผ๋ฉด ๊ทธ ๋ค์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฒ๋ฆฌํ์ง ์์ต๋๋ค.
-
๋ง์ฝ ๋ฏธ๋ค์จ์ด์์ next๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด ctx => {}์ ๊ฐ์ ํํ๋ก ํ๋ผ๋ฏธํฐ์ next๋ฅผ ์ค์ ํ์ง ์์๋ ๊ด์ฐฎ์ต๋๋ค. ์ฃผ๋ก ๋ค์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฒ๋ฆฌํ ํ์๊ฐ ์๋ ๋ผ์ฐํธ ๋ฏธ๋ค์จ์ด๋ฅผ ๋์ค์ ์ค์ ํ ๊ฒฝ์ฐ ์ด๋ฌํ ๊ตฌ์กฐ๋ก next๋ฅผ ์๋ตํ์ฌ ๋ฏธ๋ค์จ์ด๋ฅผ ์์ฑํฉ๋๋ค.
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx, next) => {
console.log(ctx.url);
console.log(1);
if (ctx.query.authorized !== '1') {
ctx.status = 401; // unauthorized
return;
}
await next();
console.log("END");
});
app.use((ctx, next) => {
console.log(2);
next();
});
app.use(ctx => {
ctx.body = 'hello world';
});
app.listen(4000, () => {
console.log("Listening on port 4000");
});
`
``
* KOA ์์๋ณด๊ธฐ ๋ก์ง 2
```javascript
const koa = require('koa');
const Router = require('koa-router');
const app = new koa();
const router = new Router();
// ๋ผ์ฐํฐ ์ค์ ํ๊ธฐ
router.get('/', ctx => {
ctx.body = 'ํ';
})
router.get('/about/:name', ctx => {
const {name} = ctx.params;
// name์ ์กด์ฌ ์ ๋ฌด์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
ctx.body = name ? `${name}์ ์๊ฐ` : '์๊ฐ';
});
router.get('/posts', ctx => {
const {id} = ctx.query;
// id์ ์กด์ฌ ์ ๋ฌด์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
ctx.body = id? `ํฌ์คํธ #${id}` : 'ํฌ์คํธ ์์ด๋๊ฐ ์์ต๋๋ค.';
});
// app ์ธ์คํด์ค์ ๋ผ์ฐํฐ ์ ์ฉ
app.use(router.routes()).use(router.allowedMethods());
app.listen(4000, () => {
console.log('listening on port 4000');
});
-
์น ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค๋ ค๋ฉด ๋ฐ์ดํฐ ๋ฒ ์ด์ค์ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๊ณ ์ฝ์ด ์์ผ ํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ์น ๋ธ๋ผ์ฐ์ ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ง์ ์ ์ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ค๋ฉด ๋ณด์์ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค. ๊ทธ๋์ REST API๋ฅผ ๋ง๋ค์ด์ ์ฌ์ฉํฉ๋๋ค.
-
ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์์ ์ด ๋ฐ์ดํฐ๋ฅผ ์กฐํ ์์ฑ ์ญ์ ์ ๋ฐ์ดํธ ํ๊ณ ์ถ๋ค๊ณ ์์ฒญํ๋ฉด, ์๋ฒ๋ ํ์ํ ๋ก์ง์ ๋ฐ๋ผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ์ฌ ์์ ์ ์ฒ๋ฆฌํฉ๋๋ค.
-
REST API๋ ์์ฒญ ์ข ๋ฅ์ ๋ฐ๋ผ ๋ค๋ฅธ HTTP ๋ฉ์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค. HTTP ๋ฉ์๋๋ ์ฌ๋ฌ ์ข ๋ฅ๊ฐ ์์ผ๋ฉฐ ์ฃผ๋ก ์ฌ์ฉํ๋ ๋ฉ์๋๋ GET, POST, PUT, DELETE, PATCH์ ๋๋ค.
-
์๋ฒ๋ฅผ ๊ฐ๋ฐํ ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์น ์๋น์ค์์ ์ฌ์ฉ๋๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ , ํจ์จ์ ์ผ๋ก ์กฐํํ๊ฑฐ๋ ์์ ํ ์ ์์ต๋๋ค. ๊ธฐ์กด์๋ mysql, oracleDB, postgreSQL ๊ฐ์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์์ฃผ ์ฌ์ฉํ์ต๋๋ค.
-
๊ทธ๋ฐ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์๋ ๋ช ๊ฐ์ง ํ๊ณ๊ฐ ์์ต๋๋ค.
-
์ฒซ๋ฒ์งธ๋ ๋ฐ์ดํฐ ์คํค๋ง๊ฐ ๊ณ ์ ์ ์ด๋ผ๋ ๊ฒ์ ๋๋ค. ์ฌ๊ธฐ์ ์คํค๋ง๋ ๋ฐ์ดํฐ ๋ฒ ์ด์ค์ ์ด๋ค ํ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์์ง์ ๋ํ ์ ๋ณด๋ฅผ ๊ฐ๋ฆฌํต๋๋ค. ์๋ฅผ ๋ค์ด ํ์ ์ ๋ณด ์คํค๋ง๋ผ๋ฉด ๊ณ์ ๋ช , ์ด๋ฉ์ผ, ์ด๋ฆ ๋ฑ์ด ๋๊ฒ ์ง์. ์๋ก ๋ฑ๋กํ๋ ๋ฐ์ดํฐ ํ์์ด ๊ธฐ์กด์ ์๋ ๋ฐ์ดํฐ๋ค๊ณผ ๋ค๋ฅด๋ค๋ฉด? ๊ธฐ์กด ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ์์ ํด์ผ ์ ๋ฐ์ดํฐ๋ฅผ ๋ฑ๋กํ ์ ์์ต๋๋ค. ๊ทธ๋์ ๋ฐ์ดํฐ ์์ด ๋ง์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์คํค๋ง๋ฅผ ๋ณ๊ฒฝํ๋ ์์ ์ด ๋งค์ฐ ๋ฒ๊ฑฐ๋ก์์ง ์ ์์ต๋๋ค.
-
๋๋ฒ์งธ๋ ํ์ฅ์ฑ์ ๋๋ค. RDBMS๋ ์ ์ฅํ๊ณ ์ฒ๋ฆฌํด์ผ ํ ๋ฐ์ดํฐ ์์ด ๋์ด๋๋ฉด ์ฌ๋ฌ ์ปดํจํฐ์ ๋ถ์ฐ์ํค๋ ๊ฒ์ด ์๋๋ผ, ํด๋น ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ์ ์ฑ๋ฅ์ ์ ๊ทธ๋ ์ด๋ํ๋ ๋ฐฉ์์ผ๋ก ํ์ฅํด์ฃผ์ด์ผ ํ์ต๋๋ค.
-
๋ชฝ๊ณ ๋๋น๋ ์ด๋ฐ ํ๊ณ๋ฅผ ๊ทน๋ณตํ ๋ฌธ์ ์งํฅ์ nosql ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋๋ค. ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฑ๋กํ๋ ๋ฐ์ดํฐ๋ค์ ์ ๋์ ์ธ ์คํค๋ง๋ฅผ ์ง๋ ์ ์์ต๋๋ค. ์ข ๋ฅ๊ฐ ๊ฐ์ ๋ฐ์ดํฐ๋ผ๊ณ ํ๋๋ผ๋, ์๋ก ๋ฑ๋กํด์ผํ ๋ฐ์ดํฐ ํ์์ด ๋ฐ๋๋ค๊ณ ํ๋๋ผ๋ ๊ธฐ์กด ๋ฐ์ดํฐ๊น์ง ์์ ํ ํ์๋ ์์ต๋๋ค. ์๋ฒ์ ๋ฐ์ดํฐ ์์ด ๋์ด๋๋ ํ ์ปดํจํฐ์์๋ง ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์๋๋ผ ์ฌ๋ฌ ์ปดํจํฐ๋ก ๋ถ์ฐํ์ฌ ์ฒ๋ฆฌํ ์ ์๋๋ก ํ์ฅํ๊ธฐ ์ฝ๊ฒ ๋์ด์์ต๋๋ค.
-
moongoose๋ node.js ํ๊ฒฝ์์ ์ฌ์ฉํ๋ ๋ชฝ๊ณ ๋๋น ๊ธฐ๋ฐ ODM ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ๋๋ค. ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฌธ์๋ค์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด์ฒ๋ผ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋๋ค.
- dotenv๋ ํ๊ฒฝ ๋ณ์๋ค์ ํ์ผ์ ๋ฃ๊ณ ์ฌ์ฉํ ์ ์๊ฒ ํ๋ ๊ฐ๋ฐ ๋๊ตฌ์ ๋๋ค. moongoose๋ฅผ ์ฌ์ฉํ์ฌ ๋ชฝ๊ณ ๋๋น์ ์ ์ํ ๊ฒฝ์ฐ, ์๋ฒ์ ์ฃผ์๋ ๊ณ์ ๋ฐ ๋น๋ฐ๋ฒํธ๊ฐ ํ์ํ ๊ฒฝ์ฐ๋ ์์ต๋๋ค. ์ด๋ ๊ฒ ๋ฏผ๊ฐํ๊ฑฐ๋ ํ๊ฒฝ๋ณ๋ก ๋ฌ๋ผ์ง ์ ์๋ ๊ฐ์ ์ฝ๋ ์์ ์ง์ ์์ฑํ์ง ์๊ณ , ํ๊ฒฝ๋ณ์๋ก ์ค์ ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
let postId = 1; // id์ ์ด๊ธฐ๊ฐ์
๋๋ค.
// posts ๋ฐฐ์ด ์ด๊ธฐ ๋ฐ์ดํฐ
const posts = [
{
id : 1,
title : '์ ๋ชฉ',
'body' : '๋ด์ฉ',
},
];
// ํฌ์คํธ ์์ฑํ๊ธฐ
export const write = ctx => {
// REST API์ Request Body๋ ctx.request.body์์ ์กฐํํ ์ ์์ต๋๋ค.
const { title, body } = ctx.request.body;
postId += 1; // ๊ธฐ์กด postId ๊ฐ์ 1์ ๋ํฉ๋๋ค.
const post = {
id : postId,
title : body
};
posts.push(post);
ctx.body = post;
};
// ํฌ์คํธ ๋ชฉ๋ก ์กฐํ
export const list = ctx => {
ctx.body = posts;
}
// ํน์ ํฌ์คํธ ์กฐํ
export const read = ctx => {
const { id } = ctx.params;
// ์ฃผ์ด์ง id ๊ฐ์ผ๋ก ํฌ์คํธ๋ฅผ ์ฐพ์ต๋๋ค.
// ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ ์จ ๊ฐ์ ๋ฌธ์์ด ํ์์ด๋ฏ๋ก ํ๋ผ๋ฏธํฐ๋ฅผ ์ซ์๋ก ๋ณํํ๊ฑฐ๋
// ๋น๊ตํ p.id ๊ฐ์ ๋ฌธ์์ด๋ก ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
const post = posts.find(p => p.id.toString() === id);
// ํฌ์คํธ๊ฐ ์์ผ๋ฉด ์ค๋ฅ๋ฅผ ๋ฐํํฉ๋๋ค.
if (!post) {
ctx.status = 404;
ctx.body = {
message : 'ํฌ์คํธ๊ฐ ์กด์ฌํ์ง ์์ต๋๋ค.',
};
return;
}
ctx.body = post;
};
// ํน์ ํฌ์คํธ ์ ๊ฑฐ
export const remove = ctx => {
const {id} = ctx.params;
// ํด๋น id๋ฅผ ๊ฐ์ง post๊ฐ ๋ช ๋ฒ์งธ์ธ์ง ํ์ธํฉ๋๋ค.
const index = posts.findIndex(p => p.id.toString() === id);
// ํฌ์คํธ๊ฐ ์์ผ๋ฉด ์ค๋ฅ๋ฅผ ๋ฐํํฉ๋๋ค.
if (index === -1) {
ctx.status = 404;
ctx.body = {
message : 'ํฌ์คํธ๊ฐ ์กด์ฌํ์ง ์์ต๋๋ค.',
};
return;
};
// index๋ฒ ์จฐ ์์ดํ
์ ์ ๊ฑฐํฉ๋๋ค.
posts.splice(index,1);
ctx.status = 204; // No content
};
// ํฌ์คํธ ์์
export const replace = ctx => {
// PUT ๋ฉ์๋๋ ์ ์ฒด ํฌ์คํธ ์ ๋ณด๋ฅผ ์
๋ ฅํ์ฌ ๋ฐ์ดํฐ๋ฅผ ํต์งธ๋ก ๊ต์ฒดํ ๊ฒฝ์ฐ ์ฌ์ฉํฉ๋๋ค.
const {id} = ctx.params;
// ํด๋น id๋ฅผ ๊ฐ์ง post๊ฐ ๋ช ๋ฒ์งธ์ธ์ง ํ์ธํฉ๋๋ค.
const index = posts.findIndex(p => p.id.toString() === id);
// ํฌ์คํธ๊ฐ ์์ผ๋ฉด ์ค๋ฅ๋ฅผ ๋ฐํํฉ๋๋ค.
if (index === -1) {
ctx.status = 404;
ctx.body = {
message : 'ํฌ์คํธ๊ฐ ์กด์ฌํ์ง ์์ต๋๋ค.',
};
return;
};
// ์ ์ฒด ๊ฐ์ฒด๋ฅผ ๋ฎ์ด ์์๋๋ค.
// ๋ฐ๋ผ์ id๋ฅผ ์ ์ธํ ๊ธฐ์กด ์ ๋ณด๋ฅผ ๋ ๋ฆฌ๊ณ , ๊ฐ์ฒด๋ฅผ ์๋ก ๋ง๋ญ๋๋ค.
posts[index] = {
id,
...ctx.request.body,
};
ctx.body = posts[index];
};
// ํฌ์คํธ ์์ (ํน์ ํ๋ ๋ณ๊ฒฝ)
export const update = ctx => {
// PATCH ๋ฉ์๋๋ ์ฃผ์ด์ง ํ๋๋ง ๊ต์ฒดํฉ๋๋ค.
const {id} = ctx.params;
// ํด๋น id๋ฅผ ๊ฐ์ง post๊ฐ ๋ช ๋ฒ์งธ์ธ์ง ํ์ธํฉ๋๋ค.
const index = posts.findIndex(p => p.id.toString() === id);
// ํฌ์คํธ๊ฐ ์์ผ๋ฉด ์ค๋ฅ๋ฅผ ๋ฐํํฉ๋๋ค.
if (index === -1) {
ctx.status = 404;
ctx.body = {
message : 'ํฌ์คํธ๊ฐ ์กด์ฌํ์ง ์์ต๋๋ค.',
};
return;
};
// ์ ์ฒด ๊ฐ์ฒด๋ฅผ ๋ฎ์ด ์์๋๋ค.
// ๋ฐ๋ผ์ id๋ฅผ ์ ์ธํ ๊ธฐ์กด ์ ๋ณด๋ฅผ ๋ ๋ฆฌ๊ณ , ๊ฐ์ฒด๋ฅผ ์๋ก ๋ง๋ญ๋๋ค.
posts[index] = {
...posts[index],
...ctx.request.body,
};
ctx.body = posts[index];
}
- mongoose์๋ ์คํค๋ง์ ๋ชจ๋ธ์ด๋ผ๋ ๊ฐ๋ ์ด ์กด์ฌํ๋๋ฐ, ์ด ๋์ ํผ๋ํ๊ธฐ ์ฝ์ต๋๋ค. ์คํค๋ง๋ ์ปฌ๋ ์ ์ ๋ค์ด๊ฐ๋ ๋ฌธ์ ๋ด๋ถ์ ๊ฐ ํ๋๊ฐ ์ด๋ค ํ์์ผ๋ก ๋์ด ์๋์ง ์ ์ํ๋ ๊ฐ์ฒด์ ๋๋ค. ์ด์ ๋ฌ๋ฆฌ ๋ชจ๋ธ์ ์คํค๋ง๋ฅผ ์ฌ์ฉํ์ฌ ๋ง๋๋ ์ธ์คํด์ค๋ก, ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ค์ ์์ ์ ์ฒ๋ฆฌํ ์ ์๋ ํจ์๋ค์ ์ง๋๊ณ ์๋ ๊ฐ์ฒด์ ๋๋ค.
- ๋ชจ๋ธ์ ๋ง๋๋ ค๋ฉด ์ฌ์ ์ ์คํค๋ง๋ฅผ ๋ง๋ค์ด ์ฃผ์ด์ผ ํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๋ธ๋ก๊ทธ ํฌ์คํธ์ ๋ํ ์คํค๋ง๋ฅผ ์ค๋นํ ํ ๋ฐ, ์ด๋ค ๋ฐ์ดํฐ๊ฐ ํ์ํ ์ง ์๊ฐํด๋ด ์๋ค.
์ ๋ชฉ, ๋ด์ฉ, ํ๊ทธ, ์์ฑ์ผ
- ํฌ์คํธ ํ๋์ ์ด๋ ๊ฒ ์ด ๋ค ๊ฐ์ง ์ ๋ณด๊ฐ ํ์ํฉ๋๋ค. ๊ฐ ์ ๋ณด์ ๋ํ ํ๋ ์ด๋ฆ๊ณผ ๋ฐ์ดํฐ ํ์ ์ ์ค์ ํ์ฌ ์คํค๋ง๋ฅผ ๋ง๋ญ๋๋ค.