Node.js

nodeJS(typescript)에 swagger 적용하기

tmkimm 2022. 11. 4. 16:47

이전 글에서는 swagger 소개와 장점, 적용 방법에 대해 정리했었고 이번 글에서는 실제 프로젝트에 적용한 사례에 대해 정리해보겠습니다.

이전 글을 안 읽은 분이라면 읽고 오시는 것을 추천드립니다! 👇

이전글) swagger로 API 문서 자동화하기(nodeJS)

기술 스택 : Node.JS(Express), Typescript, MongoDB
예제 : github

 

Swagger yaml 구조

Swagger  Editor를 보면 전체적인 구조를 확인할 수 있습니다.

json 같은 다른 데이터 포맷을 사용할 수 있지만 간결함을 위해 yaml 포맷을 사용했습니다.

💡 yaml이란?
데이터 표현 양식으로 다른 양식에 비해 사람이 이해하기 쉬운 형태를 가지고 있습니다.
yaml은 들여 쓰기를 정확히 맞춰야 하며 key: value 형태로 데이터를 정의합니다.
배열로 여러 데이터를 표현할 때 - 기호를 사용합니다.

 

사진을 통해 전체적인 구조를 보면 경로(paths)는 /pet이고 PUT 요청입니다.

tags는 API를 묶어주는 역할이며 별도로 정의해야 합니다.

tags:
  - name: pet
    description: Everything about your Pets
    externalDocs:
      description: Find out more
      url: http://swagger.io

PUT 요청에 대해 summary와 description을 작성하고 이후에 requestBody와 responses에 대해 정의합니다.

json, xml 등 content type 별로 작성할 수 있고 schema로 components를 지정하고 있습니다.

 

component를 생성하지 않고 바로 사용하려면 type을 object로 지정하고 properties를 입력하면 됩니다.

   *      requestBody:
   *        content:
   *          application/json:
   *            schema:
   *              type: object
   *              properties:
   *                postId:
   *                  type: string
   *                  description : '글 Id'
   *                  example: '610f3dac02f039c2d9d550d6'
   *                content:
   *                  type: string
   *                  description : '댓글 내용'
   *                  example: '댓글'

각 properties는 type, description, example를 가질 수 있고 type이 array인 경우 이렇게 사용하면 됩니다.

   *                  userLists:
   *                    type: array
   *                    description: 사용자 리스트
   *                    items:
   *                      type: string

사실 항목이 직관적이라 Swagger  Editor만 봐도 바로 문서를 작성할 수 있습니다.

 

 

컴포넌트

component를 지정해서 반복되는 코드를 줄일 수 있고 수정 사항이 생길 경우 한 번에 변경할 수 있습니다.

components > schemas에 component 명을 지정하고 schema를 작성합니다.

example을 작성하면 아래 사진처럼 문서를 확인할때 Example value가 표시됩니다.

컴포넌트를 사용할때는 $ref를 사용하여 schema를 지정합니다.

   *      responses:
   *        200:
   *          description: successful operation
   *          content:
   *            application/json:
   *              schema:
   *                type: array
   *                items:
   *                  $ref: '#/components/schemas/Comment'

 

 

이전 글에서 설명한 것처럼 데이터뿐만 아니라 status도 컴포넌트화 할 수 있습니다.

401(UnauthorizedError) 에러가 발생하는 경우를 schema로 정의해놓은 후

 /**
 * @swagger
 *  components:
 *    securitySchemes:
 *      bearerAuth:
 *        type: http
 *        scheme: bearer
 *        bearerFormat: JWT
 *    responses:
 *      UnauthorizedError:
 *        description: Access token is missing or invalid
 */

responses에서 사용하면 됩니다.

   *        401:
   *          $ref: '#/components/responses/UnauthorizedError'

 

 

 

세팅

javascript 기준 초기 세팅은 이전 글을 확인해주시기 바랍니다.

 

Javascript에서 Typescript로 변경하기 위해 모듈을 추가 설치합니다.

npm i @types/swagger-jsdoc @types/swagger-ui-express @types/yamljs

 

swagger 설정 파일에서 apis를 **/*. ts로 변경합니다.

 const options = {
  swaggerDefinition: {
    openapi: '3.0.3',
    info: {
      title: 'API Docs.',
      version: '1.0.0',
      description: 'API 문서입니다.',
    },
    servers: [
      {
        url: 'http://127.0.0.1:5000/api',
      },
    ],
  },
  apis: ['**/*.ts'],
};
export default options;

 

yaml 구조는 동일하므로 이렇게만 세팅해주시면 됩니다.

추가로 API 문서 보안을 위해 ID와 비밀번호를 설정해줍니다.

 

express-basic-auth 모듈 설치 후

npm install express-basic-auth

ID와 비빌번호는 .env에 저장하고 원하는 path에 대해 암호를 설정합니다.

  app.use(
    ['/api-docs'],
    expressBasicAuth({
      challenge: true,
      users: {
        [process.env.AdminId]: process.env.AdminPassword,
      },
    }),
  );

이렇게 설정하면 설정한 path에 접근할 때 ID와 비밀번호를 입력받게 됩니다.

 


Conclusion

swagger를 적용하고 나니 개발, API 문서 작성, 테스트를 한 번에 할 수 있게 되어 너무 편합니다.

API 문서 작성에 불편함을 느끼셨던 경험이 있다면 swagger 적용을 추천드립니다.

 

코드와 문서 작성을 한번에 할 수 있는 점은 좋지만 코드가 길어지게 된다는 단점이 있습니다.

주석을 접어놓으면 상관이 없긴 한데 검색이 되면 자동으로 펼쳐지게 되네요😢

어떻게 개선하면 좋을지 고민해봐야겠습니다.

 

참고 글

NestJs swagger문서 보안
Node.js (TS) 프로젝트에 swagger 적용하기 (Feat. 파일 분리)