ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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이란 모듈명으로 각각 요청에 따라 컨트롤러를 입력해주면 된다.

    댓글

Designed by Tistory.