[Node.js] Express 프레임워크로 Rest API 서버 만들기

node.js 와 express를 통해 API 서버를 만들어 기존 레거시 서버와 연동 개발을 진행했던 부분을 기록으로 남기려 합니다.

SpringFramework Server <==> Node.js + express API 서버, 두 서버 사이에 rest api 통신을 위한 서버 개발입니다.

 

DB와 기타 복잡한 것들 보다는 API 기능에 충실한 기본을 만들고 확장해 나가려고 합니다.

 

NPM(Node Package Manager)이 설치되어 있다는 가정하에 프로젝트 폴더 아래에 신규 프로젝트 폴더로 quant_api 폴더를 생성했습니다 .해당 폴더에서 터미널을 실행해 npm init 명령어로 node.js 프로젝트를 생성합니다. 

 

다른 설정은 모두 그대로 두고 엔터키를 연타해서 기본 프로젝트로 생성하면 되는군요

 

PS F:\dev\project\quant_api> npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (quant_api)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to F:\dev\project\quant_api\package.json:

{
  "name": "quant_api",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes)
PS F:\dev\project\quant_api>

 

추가 필요한 모듈들을 설치 진행해줍니다. 

이번 프로젝트에서 사용할 모듈은 ejs, express, nodemon, path 4개의 라이브러리 입니다.

 

nodemon(node monitor)은 노드 애플리케이션 디렉토리를 실시간 감시하면서 변경사항이 있을 경우 자동으로 서버를 재시작해서 불필요한 Server Stop & Start 과정을 생략시켜주는 모듈입니다.  nodemon은 다른 프로젝트에서도 계속적으로 사용할 모듈이므로 글로벌로 설치 진행하고 나머지는 프로젝트 종속으로 설치를 진행해줍니다.

 

ejs 는 Embedded JavaScript Template 으로 html 템플릿으로 view를 구성할 수 있도록 해주는 모듈입니다.

express 는 경량 HTTP 웹 프레임워크로써 불편한 http 모듈의 기능을 강화해 요청과 응답, 미들웨어 사용, 템플릿 엔진등의 기능을 제공해줍니다. 

 

path 모듈은 concat 함수와 같은 용도로 경로 두개를 이어붙여주는 유틸 모듈입니다.

 

nodemon 설치

npm install -g nodemon

 

나머지 모듈 설치

npm install ejs, express, path

 

이렇게 업데이트된 package.json 파일 내용입니다.

 

scripts 아래에 start 태그를 넣어주었는데 npm start 를 통해 서버 실행시 자동으로 nodemon app.js 로 실행될 수 있도록 설정한 부분입니다.

{
  "name": "quant_api",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon app.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ejs": "^3.1.9",
    "express": "^4.18.2",
    "nodemon": "^3.0.1",
    "path": "^0.12.7"
  }
}

 

폴더 구성입니다.

 

app.js 를 메인 파일로 두고 있으며 routes 에 index.js 에 api 를 정의하였고. views 아래에 html 템플릿 파일 구성을 둡니다.

 

 

 

 

 

 

 

 

index.html 파일은 아래처럼 구성되어 있습니다. 서버에 접속 시 보여주는 화면입니다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="/index.css" />
    <title>Home</title>
  </head>
  <body>
    <h1 class="red"><%= title %></h1>
  </body>
</html>

 

 

routes 하위에 index.js 에는 3개의 end point를 정의했습니다.

 

/ : 메인페이지 출력

/hello : Hello, Node World!! 리턴 api

/echo : request로 들어온 데이터를 재구성해서 echo 효과 api

/error : 에러 발생시 흐름 확인을 위한 api

작성된 router 객체를 module.exports 가 참조할 수 있도록 변수를 대입하는 코드를 마지막줄에 넣어줍니다. 

이렇게 해야 app.js에서 use 함수를 통해 라우터 객체를 참조할 수 있게 됩니다.

 

페이지 렌더링은 res.render 함수를 통해 html 파일명을 작성하고 title 변수 값을 대입해 html 내에서 <%= title =%> 치환자를 통해 타이틀 값이 변경되어 렌더링 됩니다.

 

index.ts

var express = require('express');
var router = express.Router();

// 메인 페이지 출력
router.get('/', (req, res, next) => {
    res.render('index', {title: 'Express API Server v1.0'})    
});

// Hello, Node World!!
router.get('/hello', (req, res, next) => {
    res.send("Hello, Node World!!");
});


// Request 로 들어온 데이터를 재구성해서 json 데이터로 리턴
router.post('/echo', (req, res, next) => {        

    const resJson = {
        url: req.path,
        method: req.method,
        header: req.headers,
        body: req.body,
        params: req.params,
        query: req.query
    }

    res.json(resJson);
});

// 에러 발생시 흐름 확인 용도
router.get('/error', (req, res, next) => {
    next(new Error('/error api 호출, 에러 발생'));
});

module.exports = router;

 

 

app.js 파일입니다. 

필요한 모듈을 require() 를 통해 불러오고 indexRouter 모듈도 가져옵니다. 

 

express() 호출로 app 변수에 객체 참조를 걸고 use 함수를 통해 미들웨어 함수들을 등록해줍니다.

 

라우터 설정의 경우 index라우터만 작성해두었고 루뜨 경로로 잡아두었는데 사용자나 회사정보로 분기해서 api를 제공한다면 추가 라우터를 작성해 루뜨 경로를 변경해주면 됩니다.

 

app.use('/user', userRouter); 이런식으로 user 라우터를 정의한 뒤 해당 라우터에 접근하기 위한 루뜨 경로는 user 로 설정할 수 있씁니다.

 

템플릿 엔진 관련 부분을 정의하고 json 과 urlencoded 파서에 대한 부분도 설정해주고 공통에러 처리 미들웨어도 등록해줍니다.

 

템플릿 엔진과 파서를 설정한 뒤 라우터를 설정해주셔야 하며, 그 이후에 공통 에러 처리 미들웨어를 정의하셔야 정상적으로 동작합니다. 순서도 중요하더라구요

var express = require('express');
var path = require('path');
var indexRouter = require('./routes/index');

var app = express();

// 템플릿 엔진 디렉토리 설정
app.set('views', path.join(__dirname, 'views'));
// ejs : embedded javaScript Template
app.engine('html', require('ejs').renderFile);
// view 엔진 설정(html 확장자로 된 파일 접근)
app.set('view engine', 'html');


// 파서 설정
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

// 라우터 설정  
app.use('/', indexRouter);

// 공통 에러 처리기
app.use(function(err, req, res, next) {    
    console.error(err);
    res.status(500).json({statusCode : res.statusCode, errMessage : err.message});
  });

app.listen(3000, () => console.log("API Server Start..."));

 

터미널에서 npm start 를 통해 노드 애플리케이션 서버를 실행해줍니다.

정상적으로 서버가 실행된 화면입니다.

 

http://localhost:3000 으로 접속하게 되면 index.html 페이지가 렌더링 됩니다.

페이지 내에 디자인과 같은걸 해둔게 없어서 title로 넣어둔 Express API Server 텍스트만 출력이 됩니다.

 

 

이제 index.js 에 정의해둔 API 호출 테스트를 진행해봅니다. 

rest api 호출 테스트는 post man 을 통해 진행했으며 로컬에 접속해야 하므로 desktop agent를 사용했습니다.

아래 경로에서 다운로드 할 수 있습니다.

https://www.postman.com/downloads/

 

Download Postman | Get Started for Free

Try Postman for free! Join 25 million developers who rely on Postman, the collaboration platform for API development. Create better APIs—faster.

www.postman.com

 

 

/hello  api 는 get 방식으로 정의되어 있어서 postman 호출 시 호출메소드를 GET 으로 선택해서 호출해야 합니다.

서버 호출 시 Hello, Node World!! 를 반환 받는것이 확인됩니다. 

 

/echo api는 POST 방식으로 정의되어 있어서 post man 에서 GET 방식으로 호출 시 오류를 리턴받게 됩니다. POST로 설정 후 전송 시 정상적인 리턴값을 받게 됩니다.

JSON 데이터를 넘기고 JSON 데이터를 받아올 거라서 package.json 에 있는 데이터를 body에 태워서 api를 콜해봅니다.

 

 

request 데이터를 재구성해서 response 받은 데이터 잘 넘어옵니다.

 

 

 

/error api는 get 방식으로 정의되었으며 호출 시 next함수(콜백함수)에 new Error()를 호출해서 넘깁니다. 이 콜백함수는 app.js에 정의한 에러처리 미들웨어 함수로 넘어와서 처리가 됩니다.

 

console.error(err); 코드를 통해 서버단 콘솔에 에러 로그가 출력이 되는 것을 확인할 수 있습니다.

 

res.status(500).json({statusCode : res.statusCode, errMessage : err.message});

위 코드를 통해 넘겨받은  json 데이터에도 정의 상태코드와 에러메시지가 채워져서 json 데이터로 넘어온 것을 확인할 수 있습니다.

 

 

node.js + express 프레임워크를 통해 간단히 rest api 서버를 만들어보았습니다. 

뼈대를 만들었고 이 뼈대를 점차 확장해 나가는 과정을 남겨보도록 하겠습니다.

 

전체 코드는 아래 링크 통해 받으실 수 있습니다.

https://github.com/eunipapa/quant_api