Node.js Swagger example

 

Swagger는 개발자가 REST 웹 서비스를 설계, 빌드, 문서화, 소비하는 일을 도와주는 대형 도구 생태계의 지원을 받는 오픈 소스 소프트웨어 프레임워크이다.

Node.js Example server 에서 사용한 Swagger를 정리해보았다.

send me email if you have any questions.


Install

$ npm i swagger-jsdoc swagger-ui-express --save-dev 

Options

프로젝트 구조와 파일 형식은 다 다르겠지만 개인 프로젝트에서는 최상위 디렉터리에 swagger.js파일을 만들었다.

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

const options = {
    swaggerDefinition: {
        info: {
            title: 'Test API',
            version: '1.0.0',
            description: 'Test API with express',
        },
        host: 'localhost:3001',
        basePath: '/'
    },
    components: {
        res: {
          BadRequest: {
            description: '잘못된 요청.',
          },
          Forbidden: {
            description: '권한이 없음.',
          },
          NotFound: {
            description: '없는 리소스 요청.',
          }
        },
        errorResult: {
          Error: {
            type: 'object',
            properties: {
              errMsg: {
                type: 'string',
                description: 'Error.'
              }
            }
          }
        }
      },
      schemes: ['http', 'https'], // 사용 가능한 통신 방식
      definitions:  // 모델 정의 (User 모델에서 사용되는 속성 정의)
      {
        'User': {
          type: 'object',
          properties: {
            id: {
              type: 'string'
            },
            age: {
              type: 'integer'
            },
            addr: {
              type: 'string'
            }
          }
        }
      },
    apis: ['./routes/**/*.js', './swagger/*']
};

const specs = swaggereJsdoc(options);

module.exports = {
    swaggerUi,
    specs
};

swagger.js

모듈을 불러와 옵션을 설정한 내용이다.

swaggerDefinition는 yaml 형식이나 json 형식을 받는다.
위에서는 json을 사용.

info 객체에 title, version, description 을 설정.

OpenAPI-Specification에 들어가시면 더 자세한 내용을 확인할 수 있다.

apis 는 내가 설정한 api들을 swagger가 찾을 수 있도록 표시해주기 때문에 각자 프로젝트에 맞는 경로 설정한다.

Swagger 적용

App.js에 Swagger를 적용시켜준다.

// Swagger init
const { swaggerUi, specs } = require('./swagger');
// path 설정
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));

여기까지 진행했다면 host:port/api-docs로 swagger에 접근할 수 있다.

Schema 등록

그림1

그림2
Schema를 등록해두면 api문서를 읽는 사람이 DB 테이블구조를 간단히 볼 수 있다.

/**
 * @swagger
 * tags:
 *  name: UserInfo
 * definitions:
 *  UserInfo:
 *      type: object
 *      properties:
 *          Name:
 *              type: string
 *              description: 이름
 *          studentID:
 *              type: int
 *              description: 학번
 *          Password:
 *              type: string
 *              description: 비밀번호
 *          Department:
 *              type: string
 *              description: 학과
 *          Grade:
 *              type: int
 *              description: 학차
 *          PhoneNumber:
 *              type: string
 *              description: 전화번호
 *          Email:
 *              type: string
 *              description: 메일주소
 *          Part:
 *              type: string
 *              description: 분야
 *          Status:
 *              type: string
 *              description: 재적상태
 *          Warning:
 *              type: int
 *              description: 경고
 *          Permission:
 *              type: string
 *              description: 권한
 */

/routes/User.js

routes 파일 상단에 스키마 등록
swagger를 기존 js 파일에 적용하려면 @swagger을 붙여주어야 한다.

API 등록

API를 등록함으로써 API문서를 읽는 사람이 request에 필요한 정보나 response형태, response status code등을 볼 수 있고 요청을 넣어 API테스트도 가능하다.

그림3

그림4

경로설정

  • 파라미터를 넣을 수 있다. /path/{path_parameter_name}
    • query는 아래 parameters에 정의한다.
    • parameters 아래에 in : path로 설정
  • query를 추가할 수도 있다. /path/query=q1 형태
    • parameters 아래 in : query로 설정
  • body형태도 가능하다.
    • parameters 아래 in : body로 설정

그림5
url parameter example

그림6
query example

그림7
body example

메소드 설정

  • 경로 아래 메소드를 get, post, put, delete 등등으로 설정.

그 외 설정

  • tags 는 해당 API의 태그이며 /api-docs 페이지에서 그 태그 별로 분류된다.
  • description 는 해당 API를 설명한다.
  • produces 는 content-type을 명시한다.
/**
 * @swagger
 *  /user/info:
 *    get:
 *      tags: [UserInfo]
 *      summary: User 정보 조회 API
 *      produces:
 *      - application/json
 *      responses:
 *       200:
 *        description: Empty or Data
 *        schema:
 *            type: object
 *            properties:
 *                UserInfo:
 *                    type: object
 *                    properties:
 *                        Name:
 *                            type: string
 *                        studentID:
 *                            type: number
 *                        Department:
 *                            type: string
 *                        Grade:
 *                            type: number
 *                        PhoneNumber:
 *                            type: string
 *                        Email:
 *                            type: string
 *                        Part:
 *                            type: string
 *                        Status:
 *                            type: string
 *                        Warning:
 *                            type: number
 *                        Permission:
 *                            type: string
 *       500:
 *        description: Server Error
 */

GET example

/**
 * @swagger
 *  /user/sign-up:
 *    post:
 *      tags: [UserInfo]
 *      summary: User 회원가입 API
 *      produces:
 *      - application/json
 *      parameters:
 *        - in: "body"
 *          name: "body"
 *          description: "회원가입 정보 입력"
 *          required: true
 *          schema:
 *              type: object
 *              properties:
 *                  Name:
 *                      type: string
 *                  studentID:
 *                      type: number
 *                  Password:
 *                      type: string
 *                  Department:
 *                      type: string
 *                  Grade:
 *                      type: number
 *                  PhoneNumber:
 *                      type: string
 *                  Email:
 *                      type: string
 *                  Part:
 *                      type: string
 *                  Status:
 *                      type: string
 *                  Warning:
 *                      type: number
 *                  Permission:
 *                      type: string
 *      responses:
 *       200:
 *        description: User sign-up success
 *       500:
 *        description: Server Error
 */

POST example

/**
 * @swagger
 *  /user/info:
 *    put:
 *      tags: [UserInfo]
 *      summary: User 정보 수정 API
 *      produces:
 *      - application/json
 *      parameters:
 *        - in: "body"
 *          name: "body"
 *          description: "학번(ID), 학과, 학차, 전화번호, 이메일, 분야, 재적 입력"
 *          required: true
 *          schema:
 *              type: object
 *              properties:
 *                  studentID:
 *                      type: number
 *                  Department:
 *                      type: string
 *                  Grade:
 *                      type: number
 *                  PhoneNumber:
 *                      type: string
 *                  Email:
 *                      type: string
 *                  Part:
 *                      type: string
 *                  Status:
 *                      type: string
 *      responses:
 *       200:
 *        description: Infomation change success
 *       404:
 *        description: NotFound
 *       500:
 *        description: Server Error
 */

PUT example

 /**
 * @swagger
 *  /user/info:
 *    delete:
 *      tags: [UserInfo]
 *      summary: User 삭제 API
 *      produces:
 *      - application/json
 *      parameters:
 *        - in: query
 *          name: "studentID"
 *          description: "ID 입력"
 *          required: true
 *        - in: query
 *          name: "Password"
 *          description: "Password 입력"
 *          required: true
 *      responses:
 *       200:
 *        description: User delete (success or failed)
 *       404:
 *        description: NotFound
 *       500:
 *        description: Server Error
 */

DELETE example