간단한 Node.js API Server 만들기 #2

김대현·2020년 1월 11일
0

Node.js API Server

목록 보기
2/2
post-thumbnail

간단한 Node.js API Server 만들기 #2

2. API 설계 및 기능 구현

1편에서도 언급했듯이 다음과 같은 API가 필요하다

1. 특정 Directory를 스캔하여 해당 Directory의 Hierachy를 Json형태로 반환
2. 해당 Hierachy에 맞게 경로값을 인자로 보내주면 그 경로에 있는 pdf파일 다운로드

/api/directory

//app.js
const manualRouter = require('./routes/manualRoutes');
const app = express();
app.use('/api', manualRouter);

기본적인 app 설정. manualRouter의 기본 baseUrl은 '/api'로 설정했다.

//routes/manualRoutes.js
const express = require('express');
const router = express.Router();
const manualController = require('../controllers/manualController');
const checkToken = require('../auth/checkToken');

router.get('/download', checkToken.check, manualController.downloadAPI);
router.get('/directory', checkToken.check, manualController.scanDirectoryAPI);

module.exports = router;

Router에서는 해당 Request 요청이 정상적인지 체크(Access token)하는 로직을
미들웨어에 넣고 정상적이라면 Controller 함수를 호출 가능하게 한다.

//controllers/manualController.js
const fs = require('fs');
const directory = require('../models/Directory');
const ROOTPATH = 'directoryName';

function scanDirectoryAPI(req, res) {
    if (fs.existsSync(ROOTPATH)) {
        var dirObject = directory.scan();
        const PdfTotalCount = dirObject.PdfTotalCount;
        const DirectoryTree = dirObject.JsonTree;

        res.status(200).json({ PdfTotalCount, DirectoryTree });
    } else {
        console.log("There are no files in that path");
        res.status(404).end();
    }
}
module.exports = { downloadAPI, scanDirectoryAPI }

Controller에서는 Directory라는 Model의 정보가 접근 가능하며 request에 대한 response를 담당한다.

//models/Directory.js
const dirTree = require('directory-tree');
const ROOTPATH = 'directoryName';

function scan() {
    var PdfTotalCount = 0;
    const JsonTree = dirTree(ROOTPATH, { extensions: /\.(pdf)$/, normalizePath: true },
        //Each File
        (item, PATH, stats) => {
            item['path'] = splitPath(item['path']);
            if (item['extension'] === '.pdf') { PdfTotalCount++; }
        },
        //Each Directory
        (item, PATH, stats) => { item['path'] = splitPath(item['path']); }
    );
    const dirObject = { JsonTree, PdfTotalCount };
    return dirObject;
}

function splitPath(originPath) {
    return originPath.substr(ROOTPATH.length + 1, originPath.length) || '/';
}

module.exports = { scan }

Model에서는 실제로 해당 디렉토리에 대한 Hierachy 정보를 JSON 형태로 가공한다.
사용 Module은 NPM에서 가져온 'directory-tree' 라이브러리다.

https://www.npmjs.com/package/directory-tree

이렇게 디렉토리 정보를 JSON 형태로 응답하는 첫번째 API에 대한 구현이 끝났다.

API 단위 TEST

API 테스트를 위해 Supertest라는 모듈을 사용하였다.
supertest는 node.js에서 통합 테스트로 사용되는 라이브러리이며 mocha, should와 함께
TDD 필수 라이브러리라고 할 수 있다.

image.png

npm install mocha -D
npm install supertest -D
//manual.spec.js

const app = require('../app');
const request = require('supertest');

describe('GET /api/download는', () => {
    it('다운로드한 파일을 리턴한다.', (done) => {
        request(app)
            .get('/api/download?path=A/engineA/engineA.pdf')
            .expect('Content-Type', 'application/pdf')
            .expect(200)
            .end((err, res) => {
                if (err) {
                    done(err);
                } else {
                    done();
                }
            });
    });
    it('파일이 없을때 404를 반환한다. ', (done) => {
        request(app)
            .get('/api/download?path=B/uiB/uiB.pdf')
            .expect(404)
            .end((err, res) => {
                if (err) {
                    done(err);
                } else {
                    done();
                }
            });
    });    
});

describe('GET /api/directory은', () => {
    it('json을 리턴한다.', (done) => {
        request(app)
            .get('/api/directory')
            .expect('Content-Type', /json/)
            .expect(200)
            .end((err, res) => {
                if (err) {
                    done(err);
                } else {
                    done();
                    console.log(res.body);
                }
            });
    });
});

app 모듈을 가져온 후 api 테스트를 진행한다. 실제로 HTTP Request 요청을 보낼 수 있으며
어떤 결과 값이 나와야 하는지 .expect() 명세를 통해 해당 함수를 체크할 수 있다.
주로 response에 대한 status code값이나 body값을 비교하여 체크한다.

npm run mocha ./manual.spec.js

image.png

마무리

간단한 API 구현과 함께 Test Module을 도입하였다.
다음 포스팅은 프로젝트 패키징과 Auth관련 내용을 적을 예정이다.

profile
FrontEnd Developer with React, TypeScript

0개의 댓글