Node.js 를 배워보자

Swagger UI Express: API 문서화의 새로운 지평을 열다

_Blue_Sky_ 2024. 12. 2. 00:35
728x90
728x90

 

API 개발은 현대 웹 애플리케이션 개발에서 필수적인 요소입니다. 복잡해지는 API를 효과적으로 관리하고, 개발팀 간의 협업을 원활하게 하기 위해 API 문서화는 매우 중요합니다. Swagger UI는 이러한 필요성을 해결하기 위해 등장한 강력한 도구입니다. 특히, Express.js와 결합하여 사용하면 더욱 효율적인 API 개발 환경을 구축할 수 있습니다.

Swagger UI란 무엇인가?

Swagger UI는 OpenAPI Specification(OAS)을 기반으로 RESTful API를 인터랙티브하게 문서화하고 시각화하는 도구입니다. OAS는 API에 대한 정보를 JSON 또는 YAML 형식으로 정의하는 표준이며, Swagger UI는 이러한 정의를 바탕으로 사용자 친화적인 인터페이스를 제공합니다. 개발자는 Swagger UI를 통해 API의 기능, 요청/응답 예시, 에러 코드 등을 직접 확인하고 테스트할 수 있으며, 이를 통해 API 개발 과정에서 발생할 수 있는 오류를 줄이고 개발 생산성을 향상시킬 수 있습니다.

728x90

Swagger UI Express의 역할

Swagger UI Express는 Express.js 애플리케이션에 Swagger UI를 쉽게 통합할 수 있도록 도와주는 미들웨어입니다. 이를 통해 개발자는 별도의 설정 없이 간단하게 API 문서를 생성하고 관리할 수 있습니다.

Swagger UI Express 사용 방법

  1. 설치:
    npm install swagger-ui-express swagger-jsdoc
    
  2. Swagger 정의 파일 생성:
     
    const swaggerJsdoc = require('swagger-jsdoc');
    const swaggerUi = require('swagger-ui-express');
    
    const options = {
        definition: {
            openapi: '3.0.0',
            info: {
                title: 'My API',
                version: '1.0.0',
            },   
        },
        apis: ['./routes/*.js'], // routes 폴더 아래의 모든 js 파일에서 스웨거 주석 추출
    };
    
    const specs = swaggerJsdoc(options);
     

     

  3. Express 애플리케이션에 추가:
     
    const app = express();
    
    app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));
    
     
     
  4. API 라우트에 Swagger 주석 추가:
     
    
    const express = require('express');
    const swaggerJsdoc = require('swagger-jsdoc');
    const swaggerUi = require('swagger-ui-express');
    
    const app = express();
    const port = 3000;
    
    /**
     * @swagger
     * components:
     *    schemas: 
     *     User:
     *       description: 사용자 데이터를 나타내는 스키마
     *       type: object
     *       required:
     *         - id
     *         - name
     *       properties:
     *         id:
     *           type: integer
     *           description: 사용자의 고유 식별자
     *         name:
     *           type: string
     *           description: 사용자의 이름
     *         email:
     *           type: string
     *           description: 사용자의 이메일 주소
     *       example:
     *         id: 1
     *         name: 이홍석
     *         email: ihongsoeg@example.com
     */
    const users = [
        { id: 1, name: '이홍석', email: 'ihongsoeg@example.com' },
        { id: 2, name: '김철수', email: 'cheolsu@example.com' },
        { id: 3, name: '박영희', email: 'younghee@example.com' }
    ];
    
    
    /**
     * @swagger
     * /users:
     *   get:
     *     summary: 사용자 목록 조회
     *     description: 모든 사용자의 목록을 반환합니다.
     *     responses:
     *       200:
     *         description: 성공
     *         content:
     *           application/json:
     *             schema:
     *               type: array
     *               items:
     *                 $ref: '#/components/schemas/User'
     */
    app.get('/users', (req, res) => {
        res.json(users);
    });
    
    /**
     * @swagger
     * /users/{id}:
     *   get:
     *     summary: 특정 사용자 조회
     *     description: 특정 ID를 가진 사용자의 정보를 반환합니다.
     *     parameters:
     *       - in: path
     *         name: id
     *         required: true
     *         description: 사용자의 고유 식별자
     *         schema:
     *           type: integer
     *     responses:
     *       200:
     *         description: 성공
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/User'
     *       404:
     *         description: 사용자를 찾을 수 없음
     */
    app.get('/users/:id', (req, res) => {
        const user = users.find(user => user.id === parseInt(req.params.id));
        if (user) {
            res.json(user);
        } else {
            res.status(404).json({ message: 'User not found' });
        }
    });
    
    /**
     * @swagger
     * /users:
     *   post:
     *     summary: 사용자 생성
     *     description: 새로운 사용자를 생성합니다.
     *     requestBody:
     *       required: true
     *       content:
     *         application/json:
     *           schema:
     *             $ref: '#/components/schemas/User'
     *     responses:
     *       201:
     *         description: 생성됨
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/User'
     */
    app.post('/users', (req, res) => {
        const newUser = req.body;
        users.push(newUser);
        res.status(201).json(newUser);
    });
    
    /**
     * @swagger
     * /users/{id}:
     *   put:
     *     summary: 사용자 정보 수정
     *     description: 특정 ID를 가진 사용자의 정보를 수정합니다.
     *     parameters:
     *       - in: path
     *         name: id
     *         required: true
     *         description: 사용자의 고유 식별자
     *         schema:
     *           type: integer
     *     requestBody:
     *       required: true
     *       content:
     *         application/json:
     *           schema:
     *             $ref: '#/components/schemas/User'
     *     responses:
     *       200:
     *         description: 성공
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/User'
     *       404:
     *         description: 사용자를 찾을 수 없음
     */
    app.put('/users/:id', (req, res) => {
        const userIndex = users.findIndex(user => user.id === parseInt(req.params.id));
        if (userIndex !== -1) {
            users[userIndex] = { ...users[userIndex], ...req.body };
            res.json(users[userIndex]);
        } else {
            res.status(404).json({ message: 'User not found' });
        }
    });
    
    /**
     * @swagger
     * components:
     *   schemas:
     *     User:
     *       type: object
     *       required:
     *         - id
     *         - name
     *       properties:
     *         id:
     *           type: integer
     *           description: 사용자의 고유 식별자
     *         name:
     *           type: string
     *           description: 사용자의 이름
     */
    
    const options = {
        definition: {
            openapi: '3.0.0',
            info: {
                title: 'User API',
                version: '1.0.0',
                description: '사용자 관리 API',
            },
        },
        apis: ['./ex_node1.js'],
    };
    
    const specs = swaggerJsdoc(options);
    app.use('/docs', swaggerUi.serve, swaggerUi.setup(specs));
    
     
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    // 서버 실행
    const PORT = 3000;
    const server = app.listen(PORT, () => {
      console.log(`Server is running on http://localhost:${PORT}`);
      console.log('Press Enter to stop the server.');
    });
    
    // Enter 키 입력 시 서버 종료
    process.stdin.setEncoding('utf-8');
    process.stdin.on('data', (input) => {
      if (input.trim() === '') { // Enter 키만 눌렀을 때
        console.log('Shutting down the server...');
        process.exit(0); // 프로그램 종료 .....
        server.close(() => {
          console.log('Server closed. Exiting program.');
          process.exit(0); // 프로그램 종료
        });
      }
    });
     
     
     
728x90

Swagger UI의 주요 기능

  • 인터랙티브 API 문서: 직접 API를 호출하고 결과를 확인할 수 있습니다.
  • 시각화: API의 구조와 데이터 모델을 시각적으로 보여줍니다.
  • 자동 생성: 코드 주석을 기반으로 API 문서를 자동 생성합니다.
  • 커스터마이징: 다양한 옵션을 통해 문서의 레이아웃과 기능을 커스터마이징할 수 있습니다.
  • OAuth 2.0 지원: OAuth 2.0 인증을 위한 기능을 제공합니다.

 

Swagger UI의 장점

  • 개발 생산성 향상: API 문서 작성 시간을 단축하고, 개발팀 간의 소통을 원활하게 합니다.
  • API 품질 향상: API 설계 단계에서부터 문제점을 발견하고 수정할 수 있습니다.
  • 문서 관리 용이: API 변경 시 문서를 자동으로 업데이트할 수 있습니다.
  • 외부 협업: API를 사용하는 다른 개발자들에게 명확한 정보를 제공합니다.

결론

Swagger UI Express는 API 개발 과정에서 필수적인 도구입니다. 간단한 설정으로 API 문서를 자동 생성하고 시각화하여 개발 생산성을 향상시킬 수 있습니다. 또한, OpenAPI Specification을 준수하여 표준화된 API 문서를 제공함으로써 다른 시스템과의 연동을 용이하게 합니다. 만약 여러분이 RESTful API를 개발하고 있다면, Swagger UI Express를 적극적으로 활용하여 API 개발의 효율성을 높여보시기 바랍니다.

728x90
728x90