• Home
  • About
    • lahuman photo

      lahuman

      열심히 사는 아저씨

    • Learn More
    • Facebook
    • LinkedIn
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

Nodejs에서 Swagger 사용하기

29 Mar 2019

Reading time ~3 minutes

Nodejs에서 Swagger 사용하기

nodejs로 만들어진 API를 활용할 수 있도록 문서를 제공해야 하는데, 따로 문서를 만들기 보다는 Swagger를 이용하여 처리 하였다. 얼마전 진행했던 개인 프로젝트의 AuthServer에 적용해보았다.

먼저 npm을 이용해서 swagger를 설치 한다.

npm install --save swagger-ui-express
npm install --save swagger-jsdoc

app.js 파일에서 다음과 같이 설정을 추가 한다.

const swaggerJSDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');



// Swagger definition
// You can set every attribute except paths and swagger
// https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md
const swaggerDefinition = {
  info: { // API informations (required)
    title: 'Auth Service', // Title (required)
    version: '1.0.0', // Version (required)
    description: 'Auth API' // Description (optional)
  },
  host: 'localhost:3000', // Host (optional)
  basePath: '/' // Base path (optional)
};

// Options for the swagger docs
const options = {
  // Import swaggerDefinitions
  swaggerDefinition,
  // Path to the API docs
  apis: ['./routes/index.js', './users/index.js', './roles/index.js']
};

// Initialize swagger-jsdoc -> returns validated swagger spec in json format
const swaggerSpec = swaggerJSDoc(options);

const app = express();
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));

routes/index.js에 swagger 작성을 진행하며, 모델 정보를 가지고 있는 부분과 paths를 가진 부분으로 나누어서 작성하면 된다.

다음은 실제 소스 샘플 이다.


/**
 * @swagger
 * tags:
 *   name: Auth
 *   description: 로그인 처리
 * definitions:
 *   Auth_request:
 *     type: object
 *     required:
 *       - user_id
 *       - password
 *     properties:
 *       user_id:
 *         type: string
 *         description: 아이디
 *       password:
 *         type: string
 *         description: 비밀번호
 *   Auth_response:
 *     type: object
 *     required:
 *       - status
 *     properties:
 *       status:
 *         type: string
 *         description: 로그인 성공 여부- error, success
 *       token:
 *         type: object
 *         description: 계정 정보
 *   Response_error:
 *     type: object
 *     required:
 *       - status
 *     properties:
 *       message:
 *         type: string
 *         description: 오류 사유
 *       status:
 *         type: integer
 *         description: response code
 */

/**
 * @swagger
 *  paths:
 *    /login:
 *      post:
 *        tags:
 *        - "Auth"
 *        summary: "Login process"
 *        description: ""
 *        consumes:
 *        - "application/json"
 *        produces:
 *        - "application/json"
 *        parameters:
 *        - in: "body"
 *          name: "body"
 *          description: "로그인 계정 정보와 서비스 정보를 전달"
 *          required: true
 *          schema:
 *            $ref: "#/definitions/Auth_request"
 *        responses:
 *          200:
 *            description: "로그인 결과"
 *            schema:
 *              $ref: "#/definitions/Auth_response"
 *          400:
 *            description: "잘못된 데이터"
 *            schema:
 *              $ref: "#/definitions/Response_error"
 *          500:
 *            description: "로그인 오류 & 실패"
 *            schema:
 *              $ref: "#/definitions/Response_error"
 */
router.post('/login', (req, res, next) => {
  const loginInfo = req.body;
  if (!Object.prototype.hasOwnProperty.call(loginInfo, 'user_id')
    || !Object.prototype.hasOwnProperty.call(loginInfo, 'password')) {
    res.statusCode(400).json({ status: 'error', message: 'Invalid Prameter' });
  }
  else {
    models.LoginHistorys.count({ where: { user_id: loginInfo.user_id, login_success: 'N', created_at: { [models.Sequelize.Op.gt]: moment().subtract(20, 'minutes').toDate() } } }).then((c) => {
      if (c > 5) {
        res.statusCode(500).json({ status: 'error', message: 'Login failed several times. Please try again in 10 minutes.' });
      }
      else {
        models.Users.findOne({
          where: { user_id: loginInfo.user_id, password: loginInfo.password },
          include: [models.Roles]
        }).then((u) => {
          if (u) {
            const userInfo = {
              user_id: u.user_id,
              desc: u.description,
              role: u.Roles.map(r => r.role_name)
            };
            const token = jwt.sign(userInfo, secretKey, {
              expiresIn: '5m' // 유효 시간은 5분
            });
            res.json({ status: 'success', token });
            loginInfo.login_success = 'Y';
          }
          else {
            res.json({ status: 'error', message: 'check ID or PW' });
            loginInfo.login_success = 'N';
          }
          models.LoginHistorys.create(loginInfo);
        });
      }
    });
  }
});

이렇게 하고 서버를 실행하면 이쁜 테스트 화면을 확인 할 수 있다.

더 자세한 내용은 swagger의 문서를 참고 하면 된다.

근데 어렵다.. 쉽지 않다…

참조 링크

  • Express에 Swagger 붙이기
  • swagger
  • Writing OpenAPI (fka Swagger) Specification tutorial


nodeswagger Share Tweet +1