ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 간단하게 알아보고 사용해보는 swagger!
    swagger 2019. 12. 27. 14:11

    또 다시 신규 프로젝트 하나가 진행될 것 같다.

     

    뭔가 일정이 굉장히 타이트한데 기획부터 디자인까지 완료가 되지 않아서 할 수 있는 작업이 없는 상태다.

    그냥 TS 환경으로 프로젝트 생성하고 기본 구성을 끝내놓고 추가적으로 최근에 관심있었던 swagger를 적용해보았다.

     

    swagger란 대략 API 문서를 코드 내에서 주석기능을 이용해 YAML 또는 JSON 형식으로 작성하고, 서버의 라우트를 통해 접속하여 문서 페이지로 확인 하는 기능을 제공하는 프레임워크다.

     

     

    https://swagger.io/

     

    The Best APIs are Built with Swagger Tools | Swagger

    API Development for Everyone Simplify API development for users, teams, and enterprises with the Swagger open source and professional toolset. Find out how Swagger can help you.

    swagger.io

     

    단순 API 정보만을 제공하는 것 뿐 아니라 흔히 웹 개발자들이 사용하는 HTTP 통신 툴 (ARC, Postman)과 같이 단순히 데이터를 입력하고 버튼을 클릭하는 것으로 실제 통신을 보내고 응답을 받을 수 있는 기능까지 포함되어 있다.

     

     

    적용 방법은 간단하면서 찾아서 적용하기 까다로웠다.

    직접 적용해보면서 다음과 같은 단점들을 느꼈다.

     

    • Node.js용 swagger 패키지 / express용 swagger 패키지가 따로 있다는 점
    • 웹 페이지를 통해 문서를 보기 위해선 따로 UI 관련된 패키지를 설정해야한다는 점
    • swagger 버전에 따른 주석 정의가 달라진다는 점
    • 공식 문서가 쉽게 적응이 안된다는 점

     

    즉, 하나의 패키지만 받아서 설정하여 적용하는게 아닌 여러 패키지를 모아서 짜집기를 해야하는 형태다.

     

    웹 페이지로 제공하는 UI 화면은 아래와 같다.

     

     

    이 화면을 또 커스터마이징을 할 수 있는 것 같던데, 일단 복잡한건 다 제쳐두고 핵심 기능을 사용하는 데 집중했다.

     

     

    컬러별로 접혀있는 항목을 클릭하면 아래와 같이 펼쳐진다.

    필요한 파라미터 형태나 응답 형태를 파악할 수 있다.

     

     

    파라미터 항목의 try it out 버튼을 클릭하면 요청을 보낼 수가 있다.

    요청을 보내면 요청 정보와 서버로부터 응답을 받을 수 있다.

     

     

    적용 방법을 알아보자.

     

    1. 설치

    swagger를 사용하기 위해선 npm 패키지를 설치해야한다.

    • swagger-jsdoc: JavaScript 주석형태로 API 내용으로 작성하면 이를 파싱하여 문서로 만드는 역할
    • swagger-ui-express: Express 프레임워크를 통해 문서 UI를 라우터로 접속하여 볼 수 있게 해주는 역할

    해당 패키지들은 개발할 때에만 사용하는 패키지므로 devDependencies로 설치해주자.

    TS 환경의 프로젝트라면 @types/swagger-jsdoc, @types/swagger-ui-express도 함께 설치해주어야 한다.

     

     

    2. 환경 구성

    패키지 설치가 완료되면 다음은 환경을 구성해야한다.

    import path from 'path';
    import { SwaggerDefinition, Options } from 'swagger-jsdoc';
    
    const swaggerDefinition: SwaggerDefinition = {
        // swagger 정보
        info: {
            title: 'swagger 테스트',
            version: '1.0.0',
            description: 'swagger 적용 테스트 사이트입니다.'
        },
        // 기본 루트 경로
        basePath: '/',
        // 모든 API에 대한 공통 정의
        components: {
            res: {
                Forbidden: { description: '권한이 없습니다.' }
                NotFound: { description: '존재하지 않는 정보입니다.' }
            }
        },
        // 사용 가능한 통신 방식
        schemes: ['http'],
        // DB 모델 정의
        definitions: {
            Board: {
                type: 'object', 
                properties: {
                    id: { type: 'number' }, 
                    title: { type: 'string' }, 
                    content: { type: 'string' }
                }
            }
        }
    };
    
    export default {
        swaggerDefinition,
        // 라우트 경로 (API 위치)
        apis: [path.join(__dirname + '/../src/**/*.ts')]
    } as Options;
    

     

    swagger에 대한 정의 설정과 옵션 설정이다.

    해당 부분은 공식 문서를 통해 알아보자.

     

    여기서 definitions에 정의하는 DB 모델 정보나, components에 작성하는 정의들은 모든 API들에 '공통'으로 적용할 수 있는 내용들이다.

    각각의 API 문서 정의에서 $ref로 접근하여 사용할 수 있다.

     

    위에서 작성한 내용들은 express에 미들웨어로써 적용해야한다.

    import express from 'express';
    
    import swaggerJSDoc from 'swagger-jsdoc';
    import swaggerUI from 'swagger-ui-express';
    import swaggerOptions from './swagger.def';
    
    export default () => {
        const app: express.Express = express();
        
        // swagger 라우트 구성
        app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(swaggerJSDoc(swaggerOptions)));
        
        return app;
    }

    swagger는 express로 실행되는 서버에 기생하여 구성이 된다.

    따라서 "http://express로 띄운 서버 주소/api-docs"를 통해 접속할 수 있다.

     

     

     

    3. API 문서 작성

    API 내용은 라우터 파일에서 각각의 라우트에 작성한다.

     

    모델은 swagger definintion에서 공통으로 정의할 수 있지만, 라우트에서도 라우트 내에서만 사용하기 위해 모델을 정의할 수 있다.

     

    주석은 YAML 형식으로 작성하기 때문에 들여쓰기 (Tab 또는 Indent)로 뎁스를 들어가며 작성한다.

     

    API 문서를 작성하기 위해서는 항상 맨 위에 @swagger를 선언한다.

     

    • tags.name: 동일한 라우트 내에서 공통으로 사용하는 항목의 별칭이다.
    • definitions: 공통적으로 사용할 모델을 정의한다.
    • definitions.faq: 모델의 이름을 정의한다.
    • definitions.faq.type: 모델의 타입을 지정한다.
    • definitions.faq.properties: 모델의 속성들을 정의한다.

     

    위의 내용을 작성하면 아래와 같이 문서가 작성된다.

     

     

    이제 상세보기를 요청하는 라우트를 만들고 API 문서를 작성해보자.

     

    ...굉장히 길다.

     

    일단 각각 쪼개서 확인해보자.

     

    1. 타이틀 정보

     

    • /api/~~~~: API URL 주소를 명시한다. 가장 먼저 명시해줘야 한다.
    • get: API의 HTTP 통신 타입을 명시한다. POST면 post, DELETE면 delete, PATCH면 patch로 작성한다.
    • tags: 라우터 내에 공통으로 정의한 모델 정보를 사용하겠다고 선언한다. []배열 타입으로 작성하며, 이 안에 tags.name을 작성하여 사용하겠다고 명시한다.
    • summary: API에 대한 한 줄 설명을 명시한다.

     

    위의 내용으로 작성하면 아래와 같은 API 정보가 생성된다.

    [get:] [/api/faq/read/{id}:] [summary] 형태로 이해하자.

     

     

    2. 파라미터 정보

     

    • parameters: 파라미터를 정의하겠다고 명시한다.
    • - in: 파라미터 정보의 형식을 정의한다. 
      • query: 쿼리스트링임을 의미한다. [http://url.com?param1=something]
      • path: 경로 변수임을 의미한다. [http://url.com/{param1}/{param2}]
      • body: 바디 데이터임을 의미한다. 바디 데이터인 것임을 정의할 때에는 schema로 상세 프로퍼티들을 정의해야한다.
    • type: 파라미터의 타입을 명시한다.
    • required: 필수 요소임을 명시한다.
    • default: 기본값을 API 문서에 명시한다.
    • name: 파라미터의 이름을 작성한다.
    • description: 파라미터에 대한 설명을 작성한다.

     

     

    위의 내용을 기반으로 아래와 같이 API 문서가 만들어진다.

    [Try it out] 버튼을 누르면 요청을 보낼 수 있다.

     

     

    3. 응답 정보

     

    • responses: 응답에 대한 정의 내용을 명시한다.
    • 400, 404, 200: 응답 코드에 대해 명시한다.
    • description: 설명을 작성한다.
    • schema: 응답 객체를 정의한다
    • schema.type: 응답 객체의 타입을 명시한다.
    • schema.properties: 응답 객체의 속성을 정의한다.
    • example: 예제를 작성한다.

     

    위의 내용을 기반으로 아래와 같이 API 문서가 만들어진다.

     

     

    대충 사용방법은 이렇고, 필요에 따라 공식 문서에서 찾아가며 사용해보고 있다.

     

     

    장점

    • 주석의 포맷 형식을 맞추지 않거나 오타, 흐름에 맞지 않는 명시들을 할 경우 화면에 표현이 되지 않거나 작동을 하지 않는다.
    • 만약 작성한 내용에 문제가 있으면 콘솔 로그로 문제가 있는 위치를 지적하고 원인을 설명해준다.
    • 따로 API 문서를 작성할 필요성이 없어진다. (코드 내에 주석으로 작성하니까)
    • API 문서를 작성하는 것 만으로 더 많은 결과를 얻을 수 있다. (통신 테스트를 진행할 수 있는 기능 등)
    • swagger는 다양한 언어 플랫폼에 적용할 수 있는 것 같다. Java 진영에도 적용이 가능하다.

     

    단점

    • 하나의 라우트의 API 내용을 작성하기 위해서 매우 긴 주석을 작성해야 한다.
    • 문서를 만들고 작성하는 것과 다르게 swagger 문법을 배워야 한다.

    'swagger' 카테고리의 다른 글

    SpringBoot에 Swagger 끼얹기  (0) 2020.02.13
Designed by Tistory.