이번 시간에는 Koa를 사용해서 서버를 자동으로 실행해주는 Nodemon
요청이 들어왔을 때, 경로에 따라 다른 작업을 할 수 있게해주는
koa-router 를 배워보도록 하겠습니다.
1.Nodemon 사용하기
서버 코드를 변경할 때마다 재시작 해야 하는데 이런 번거로움을
Nodemon이 해결해줍니다.
먼저, Nodemon 라이브러리를 설치해줍니다.
yarn global add nodemon
설치후 다음 명령어를 통해 서버를 실행하면 코드가 바뀔때마다 자동으로
재시작 해줍니다.
$ nodemon --watch src/ src/index.js
위 방법이 안돼면 아래 방법 처럼 해봅니다.
$ npx nodemon src/index.js
위 명령어를 해석하자면, src/ 디렉토리에서 코드변화가 감지되면 재시작을 하도록 설정하고
src/index.js를 실행시켜주는 역할을 합니다.
개발 할때마다 이러한 명령어를 작성하는데 버거로울 수 있기 때문에 이 명령어를
scripts 안에 추가해주겠습니다.
packages.json - 하단
"scripts": {
"start": "node src",
"start:dev": "nodemon --watch src/ src/index.js"
},
이제 서버를 실행시 yarn start를 하고, 개발모드로 사용하려면 yarn start:dev를 입력하면
됩니다.
2. koa-router 사용하기
koa-router는 koa에 내장된 것이 아니라 모듈을 따로 설치해야 합니다.
yarn add koa-router
기본 사용법
이제 koa-router의 기본 사용법을 알아볼 것인데
그전에, 전 강의에서 작성했던 미들웨어는 제거해줍니다.
// 3. koa-router 사용하기
router.get('/', (ctx, next) => {
ctx.body = '메인 페이지';
});
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(4000, () => {
console.log("heurm servier is listening to port 4000");
})
Router 인스턴스를 새로 생성한 뒤 해당 값에 router를 넣었고
/ 경로로 들어오면 메인페이지 이라는 내용을 응답하도록
라우터 설정을 해주었습니다.
이제 http://localhost:4000/ 로 들어가면 메인 페이지라는
텍스트가 뜰 것입니다.
여러개의 라우트, 라우트 파라미터
여러개의 라우트를 설정하는 방법과, 라우트 파라미터를 읽어오는 방법을
알아보도록 하겠습니다.
다음 코드를 입력해주세요.
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
router.get('/', (ctx, next) => {
ctx.body = '메인 페이지';
});
router.get('/about', (ctx, next) => {
ctx.body = '소개 페이지';
})
router.get('/about/:name', (ctx, next) => {
const { name } = ctx.params; // 라우트 경로에 : 파라미터 명으로 정의된 값이 ctx.params안에 설정
ctx.body = name + "의 소개 페이지 입니다."
})
router.get('/post', (ctx, next) => {
const {id} = ctx.request.query; // 주소 뒤에 ?id=10 형식으로 작성된 쿼리는 ctx.request.query를 이용
if (id) {
ctx.body = "포스트 #" + id;
} else {
ctx.body = "해당 포스트가 없습니다."
}
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(4000, () => {
console.log("heurm servier is listening to port 4000");
})
다음 라우트를 설정해주었습니다.
- /
- /about
- /about/:name
- /post
3번째 /about/:name 부분의 경우 값이 동적으로 들어갈 수 있도록
뒤에 name 이라는 파라미터를 넣어주었고
4번째 /post 경우엔 ?id=5 이런식에 쿼리 파라미터가
들어갈 수 있도록 해주었습니다.
다음 주소들을 하나하나 들어가서 제대로 작동 되는지 확인해보세요
- http://localhost:4000/
- http://localhost:4000/about
- http://localhost:4000/about/me
- http://localhost:4000/post
- http://localhost:4000/post?id=10
라우트 모듈화
프로젝트에는 여러가지의 라우트를 만들게 될 것인데, 각 라우트들을 지금
index.js 에서 다 작성하면 꽤 코드가 길어질 것 입니다.
그렇다면 유지보수도 어렵게 될 것이고
그 것을 보안하기 위해서 라우터를 다른 파일에 작성해서
불러오는 방법을 알아보겠습니다.
먼저 라우트들을 저장할 디렉토리부터 만들어 줍니다.
src/api/ 디렉토리를 만들고
이 내부에 index.js 파일을 생성합니다.
const Router = require('koa-router');
const api = new Router();
api.get('/talks', (ctx, next) => {
ctx.body = 'GET ' + ctx.request.path;
});
module.exports = api;
talks 라는 API를 준비했습니다. 우리가 이번에 백엔드 서버 작업을 본격적으로
시작하기 앞서 우리는 예제로 talks에 관련된 REST API를 만들어보고
작동방식을 이해하고 난 다음 프로젝트 API를 만들어보도록 하겟습니다.
이제, 이렇게 모듈로 만든 라우트를 서버 엔트리 파일 (src/index.js)
에 불러와 사용해보도록 하겠습니다.
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
const api = require('./api');
router.use('/api', api.routes()); // api 라우트를 /api 하위 라우트로 설정
app.use(router.routes()).use(router.allowedMethods());
app.listen(4000, () => {
console.log('heurm server is listening to port 4000');
})
이제. http://localhost:4000/api/talks 경로로 들어가 봅니다.
잘 나타납니다.
우리가 앞으로 api를 여러 종류로 만들텐데, 각 종류들마다 파일을 분리하도록 해보겠습니다.
api 디렉토리안에 talks라는 디렉토리를 만들고, 그 안에 index.js를 생성해줍니다.
const Router = require('koa-router');
const talks = new Router();
talks.get('/', (ctx, next) => {
ctx.body = 'GET ' + ctx.request.path;
})
module.exports = talks;
그 다음 api/index.js 파일에 /talks 경로에 방금 만든 라우트를 연결해 줍니다.
const Router = require('koa-router');
const api = new Router();
const talks = require('./talks');
api.use('/talks', talks.routes());
module.exports = api;
여러 메소드 사용하기
REST API 에서는, 요청의 종류에 따라서 다른 HTTP 메소드를 가집니다.
HTTP 메소드는 여러 종류가 있는데 그 중 주로 사용하는 것들은 다음과 같습니다.
- GET : 데이터를 가져올 때 사용
- POST : 데이터를 등록 할 때 사용. 혹은 인증작업을 거칠 시
- DELETE : 데이터를 삭제할 때 사용
- PUT : 데이터를 교체할 때 사용
- PATCH : 데이터를 특정 필드를 수정할 때 사용
라우터에서 각각의 메소드에 대한 요청을 준비할 때
.get, .post , . delete , .put, .patch 를 사용하면 됩니다.
그럼 한번 사용해 보겠습니다.
src/talks/index.js 로 가서
const Router = require('koa-router');
const talks = new Router();
const handler = (ctx, next) => {
ctx.body = `${ctx.request.method} ${ctx.request.path}`;
};
talks.get('/', handler);
talks.post('/', handler);
talks.delete('/', handler);
talks.put('/', handler);
module.exports = talks;
이제 Postman 같은 HTTP 클라이언트 도구를 사용해 우리가 준비한, get / post / delete / put / patch
메소드 들을 각각 테스트 해봅니다.
방금 작성했던 코드처럼, 각 메소드들을 처리하는 함수를 따로 분리시켜
작성할 수 있습니다.
라우터를 작성할 때 각 라우트에 해당하는 핸들러를 따로 작성하는 것이 좋습니다.
그 이유는 그렇게 해야 라우트들이 한눈에 보이기 때문입니다.
이제, 각 라우트에 대한 핸들러를 talks 디렉토리에 talks.controller.js 파일로
분리시켜보겠습니다.
exports.list = (ctx) => {
ctx.body = 'listed';
};
exports.create = (ctx) => {
ctx.body = 'created';
}
exports.delete = (ctx) => {
ctx.body = "deleted";
}
exports.replace = (ctx) => {
ctx.body = 'replaced';
}
exports.update = (ctx) => {
ctx.body = "updated";
}
이렇게 exporst.변수명 = ... 으로 내보내기 한 코드는
파일을 불러올 때 다음과 같이 사용할 수 있습니다.
const 모듈명 = require('파일명');
모듈명.변수명
코드를 내보낼때에는, 일반 변수값을 내보낼 수 있고, 함수를 내보낼 수 있습니다.
그럼, 방금 작성한 코드에 맞춰 talks 인덱스 파일을 업데이트 해줍니다.
const Router = require('koa-router');
const talks = new Router();
const talksCtrl = require('./talks.controller');
talks.get('/', talksCtrl.list);
talks.post('/', talksCtrl.create);
talks.delete('/', talksCtrl.delete);
talks.put('/', talksCtrl.replace);
talks.patch('/', talksCtrl.update);
module.exports = talks;
이제 각 API들이 잘 작동되는지 테스트 해봅니다.
Node.js에서 코드가 복잡해질 것 같을 떄, 이렇게 모듈화 해서 파일을 분리시키는 것도
좋은 방식입니다. 그렇게 할 수록 유지보수가 편해지겠죠?
참고 자료
'백엔드 > Koa' 카테고리의 다른 글
[Koa] Koa를 사용한 웹 서버 만들기 - 1.프로젝트 생성 및 ESLint 설정 및 Koa 기본 사용법 (0) | 2023.01.03 |
---|---|
[Koa] Koa를 사용한 웹서버 만들기 - Koa란? (0) | 2022.04.11 |