{
"singleQuote": true,
"semi": true,
"useTabs": false,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 80
}
{
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": ["eslint:recommended", "prettier"],
"globals": {
"Atomics": "readOnly",
"ShareArrayBuffer": "readOnly"
},
"parserOptions": {
"ecmaVersion": 12
},
"rules": {}
}
{
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": ["eslint:recommended", "prettier"],
"globals": {
"Atomics": "readOnly",
"ShareArrayBuffer": "readOnly"
},
"parserOptions": {
"ecmaVersion": 12
},
"rules": {
"no-unsued-vars": "warn,
"no-console": "off"
}
}
const Koa = require('koa');
const app=new Koa();
//ctx는 요청과 응답에 관한 정보를 담음.
//next는 현재 처리 중인 미들웨어의 다음 미들웨어를 호출하는 함수
app.use(async (ctx, next)=>{
console.log(ctx.url);
console.log(1);
if(ctx.query.authorized!=='1'){
ctx.status=401;
return ;
}
await next();
})
app.use((ctx, next)=>{
console.log(2);
next();
});
app.use(ctx=>{
ctx.body='hello world';
})
app.listen(4000, ()=>{
console.log('Listening to port 4000');
})
tip. ctx 객체(미들웨어 함수의 첫 번째 인자)의 생김새
{
request: {
method: 'GET',
url: '/favicon.ico',
header: {
host: 'localhost:4000',
connection: 'keep-alive',
pragma: 'no-cache',
'cache-control': 'no-cache',
'sec-ch-ua': '"Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"',
'sec-ch-ua-mobile': '?0',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36',
accept: 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
'sec-fetch-site': 'same-origin',
'sec-fetch-mode': 'no-cors',
'sec-fetch-dest': 'image',
referer: 'http://localhost:4000/',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7'
}
},
response: {
status: 404,
message: 'Not Found',
header: [Object: null prototype] {}
},
app: { subdomainOffset: 2, proxy: false, env: 'development' },
originalUrl: '/favicon.ico',
req: '<original node req>',
res: '<original node res>',
socket: '<original node socket>'
}
{
"method": "DELETE",
"path": "/api/posts/3",
"params": {
"id": "3"
}
}
{
"name": "blog-backend",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"eslint-config-prettier": "^8.3.0",
"koa": "^2.13.1"
},
"devDependencies": {
"eslint": "^7.32.0",
"nodemon": "^2.0.12"
},
"scripts": {
"start": "node src",
"start:dev": "nodemon --watch src/src/index.js"
}
}
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', ctx=>{
ctx.body='소개';
})
// app 인스턴스에 라우터 적용
app.use(router.routes()).use(router.allowedMethods());
app.listen(4000, ()=>{
console.log('Listening to port 4000');
})
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;
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 to port 4000');
})
const Router = require('koa-router');
const api = new Router ();
api.get('/test', ctx=>{
ctx.body='test 성공 '
});
//라우터를 내보낸다.
module.exports=api;
const Koa = require('koa');
const Router = require('koa-router');
const api= require('./api');
const app = new Koa();
const router = new Router();
//라우터 설정
router.use('/api', api.routes());
// app 인스턴스에 라우터 적용
app.use(router.routes()).use(router.allowedMethods());
app.listen(4000, ()=>{
console.log('Listening to port 4000');
})
목저: request Body에 json 형식으로 데이터를 넣어주면 이를 파싱하여 서버에서 사용 가능하게 함
콘솔
yarn add koa-bodyparser
const Koa = require('koa');
const Router = require('koa-router');
const bodyParser= require('koa-bodyparser');
const api= require('./api');
const app = new Koa();
const router = new Router();
//라우터 설정
router.use('/api', api.routes());
// 라우터 적용 전에 bodyParser 적용
app.use(bodyParser());
// app 인스턴스에 라우터 적용
app.use(router.routes()).use(router.allowedMethods());
app.listen(4000, ()=>{
console.log('Listening to port 4000');
})
let postId = 1;
//posts 배열 초기 데이터
const posts = [
{
id: 1,
title: '제목',
body: '내용'
}
]
/* 포스트 작성
POST /api/posts
{title, body}
*/
exports.write = ctx=>{
const {title, body}=ctx.request.body;
postId+=1;
const post = {id: postId, title, body};
posts.push(post);
ctx.body=post ;
}
/*
포스트 목록 조회
GET/api/posts
*/
exports.list=ctx=>{
ctx.body= posts;
}
/*
특정 포스트 조회
GET/api/posts/:id
*/
exports.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;
}
/*
특정 포스트 제거
DELETE/ api/posts/:id
*/
exports.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;
}
posts.splice(index, 1);
ctx.status=204;
}
/* 포스트 수정 (교체 )
PUT/ api/posts/:id
{title, body}
*/
exports.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];
};
/* 포스트 수정(특정 필드 변경 )
PATCH/ api/posts/:id
{title, body}
*/
exports.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 ;
}
//기존 값에 정보를 덮어 씌웁니다.
posts[index]={
...posts[index],
...ctx.request.body,
}
ctx.body = posts[index]
}
다음과 같이 사용할 수 있다.
const 모듈이름 = require('파일이름');
모듈이름.이름();
src/api/posts/index.js
const Router = require('koa-router');
const postsCtrl = require('./posts.ctrl')
const post = new Router () ;
const printInfo = ctx=>{
ctx.body ={
method: ctx.method,
path: ctx.path,
params: ctx.params
}
};
posts.get('/', postsCtrl.list);
posts.post('/', postsCtrl.write );
posts.get('/:id', postsCtrl.read);
posts.delete('/:id', postsCtrl.remove);
posts.put('/:id', postsCtrl.replace);
posts.patch('/:id', postsCtrl.update);
module.exports=posts;