-
1장 koa사용해서 웹서버 만들어보기백엔드기초 다져보기 2022. 7. 4. 21:58
koa란? Node.js에서 가장 인기있던 웹 프레임워크인 Express.js개발팀이 만든 웹 프레임워크로 Express보다 Koa는 가볍고 async / await 기능을 편하게 사용할 수 있다.
이제, koa를 설치해보자.
웹 서버프로젝트를 위한 디렉토리를 만들고, 해당 디렉토리에서 yarn init을 통해 패키지 정보를 생성하고, koa를 설치해준다.
$ mkdir heurm-server $ cd heurm-server $ yarn init $ yarn add koa
먼저, 서버를 여는 방법을 알아보면,
src폴더에 index.js파일을 만들어서
const Koa = require('koa'); const app = new Koa(); app.use(ctx => { ctx.body = 'Hello Koa'; }); app.listen(4000, () => { console.log('heurm server is listening to port 4000'); });
위처럼 작성해준다. Koa 애플리케이션은 미들웨어의 배열로 구성되어 있는데, app.use 함수를 사용해서 미들웨어를 어플리케이션에 등록해준다. 여기서 ctx => {...}가 하나의 미들웨어가 되며, 두가지 파라미터를 받는데, ctx 와 next를 받는다.
ctx는 웹요청, 응답에 대한 정보를 지니며, next는 다음 미들웨어를 실행시키는 함수다.
만약, next를 안쓰면 그 부분에서 요청처리를 완료하고 응답을 한다.
그리고,
app.use((ctx, next) => { console.log(1); const started = new Date(); next().then(() => { console.log(new Date() - started + 'ms'); }); });
이처럼 next()를 실행하면 프로미스를 반환해 작업이 끝나면 할 작업들을 정할 수 있다.
이는 async / await로 가능하다. koa에선 별도 작업없이 사용가능하다.
app.use(async (ctx, next) => { console.log(1); const started = new Date(); await next(); console.log(new Date() - started + 'ms'); });
여기서 서버코드를 변경할 때마다, 재시작하는건 귀찮으므로 nodemon을 이용해보면 된다.
$ npm install -g nodemon
nodemon을 설치해주고, 서버실행 시 코드에 변경이 있을때마다 자동 재시작을 하게 한다.
$ nodemon --watch src/ src/index.js
위는 package.json에 npm srcipts에 추가해도 명령어를 단축시킬 수 있다.
"scripts":{ "start": "node src", "start:dev": "nodemon --watch src/ src/index.js" }
위를 써서, 서버 실행 할 땐, yarn start, 개발모드를 킬 땐, yarn start:dev를 사용하면 된다.
이제, koa-router을 사용해보자.
내장되어있는게 아니니 설치를 먼저 해주자.
$ yarn add koa-router
라우터의 기본적인 사용법을 먼저 알아보자.
const Koa = require('koa'); const Router = require('koa-router'); const app = new Koa(); const router = new Router(); router.get('/', (ctx, next) => { ctx.body = '홈'; }); app.use(router.routes()); app.use(router.allowedMethods()); app.listen(4000, () => { console.log('heurm server is listening to port 4000'); });
먼저, Router 인스턴스를 생성해서 router변수에 넣었고, / 경로로 오면 홈을 응답하게 설정했다.
이제, http://localhost:4000/에 들어가면 홈이라는 텍스트를 보여준다.
라우터를 설정할 때, 경로에 파라미터를 다양하게 이용할 수 있는데,
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 = '포스트 아이디가 없습니다.'; } });
첫번째 처럼, :파라미터명을 url에 붙이면 :파라미터명 자리에 아무거나 쓴 뒤 ctx.params를 쓰면 이 안으로 값이 들어온다.
그리고, 두번째 처럼, 주소뒤에 그냥 ?변수=값을 입력하면 ctx.request.query에 파싱된다. 그래서 변수의 값을 저장할 수 있다.
프로젝트가 많아지다보면 라우터가 많아지는데, 그럴땐 라우트를 모듈화 할 수 있다.
src폴더에 api폴더에 index.js를 만들어서
const Router = require('koa-router'); const api = new Router(); api.get('/books', (ctx, next) => { ctx.body = 'GET ' + ctx.request.path; }); module.exports = api;
Router 인스턴스를 api에 담고, ctx.request.path를 이용해 /books경로에 들어가면 경로를 보여주게 한다.
그 다음, 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'); });
api인스턴스를 './api'폴더에서 받아와서, use함수를 이용해 /api주소의 하위에 api.routes() 즉, api라우트를 설정해준다.
그러면, /api/books에 들어가면 위의 ctx.request.path가 나오게 된다.
마지막으로, 여러가지 메소드가 있는데,
- GET: 데이터를 가져올 때 사용합니다.
- POST: 데이터를 등록 할 때 사용됩니다. 혹은, 인증작업을 거칠때도 사용됩니다.
- DELETE: 데이터를 지울 때 사용됩니다.
- PUT: 데이터를 교체 할 때 사용됩니다.
- PATCH: 데이터의 특정 필드를 수정 할 때 사용됩니다.
위의 메소드를 사용해 요청을 준비할 수 있다.
위의 메소드를 각각 라우터로 처리할 때, 각 라우트에 해당하는 핸들러를 따로 작성하는게 좋은데,
src폴더에 api폴더에 books폴더를 만들어서 books.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'; };
각각 컨트롤러를 만들고, exports.변수명 = ....으로 내보낸 코드는
const 모듈명 = require('파일명'); 모듈명.변수명
위처럼 사용할 수 있다.
이제, scr폴더에 api폴더에 books폴더에 index.js에서
const Router = require('koa-router'); const books = new Router(); const booksCtrl = require('./books.controller'); books.get('/', booksCtrl.list); books.post('/', booksCtrl.create); books.delete('/', booksCtrl.delete); books.put('/', booksCtrl.replace); books.patch('/', booksCtrl.update); module.exports = books;
위처럼 booksCtrl이란 모듈명으로 각각 요청에 따라 컨트롤러를 입력해주면 된다.