Node.js + Swagger, 어렵지 않게 사용하기

2020. 12. 6. 20:31BACKEND/Node

반응형

안녕하세요 !

오늘도 node 서버와 관련된 게시글을 작성하려고 합니다 〰️ 

오늘은 swagger에 사용법에 대해 알아보겠습니다 ~.~

그동안,,, API 명세서 작성하고 수정하고 ,,, 힘드셨죠 🤣

 

****************  INDEX  *****************

 

🌈 Swagger❓ 

⏳  Swagger Settings

🤖 Swagger, 정의하기

 

******************************************** 

 


 

🌈  Swagger

오늘은 swagger에 대해 알아봅시다!

swagger를 정의하기에 앞서, 필요성에 대해 이야기 해볼게요.

 

/*

API 제작이 끝난 후에, 프론트 분에게 완성된 API를 전달합니다.

 

여러분들은 어떻게 전달해주시나요?

github Wiki 나, md 파일, 엑셀, notion 등 많은 방법이 있습니다.

하지만, 모두 공통점은 수기로 작성해야 한다는 점이죠.

 

API를 공유할 때 문제점은 없었나요 ?

수기로 작성할 때에는 꼼꼼한 확인이 필요하죠.

특히 API는 정해진 규칙을 따르기 때문에 오탈자 하나도 큰 영향을 줄 수 있어요.

 

혹은, API를 수정을 할 때에도 API 명세서를 수정하지 않으면 프런트 개발자가 심한....욕을....ㅎㅎ....

*/

 

 

 

이러한 문제점을 해결할 수 있는 방법이 바로 Swagger입니다.

 

The OpenAPI Specification (OAS) defines 
a standard, language-agnostic interface to RESTful APIs which allows both humans and computers
to discover and understand the capabilities of the service
without access to source code, documentation, or through network traffic inspection.
When properly defined, a consumer can understand and interact with the remote service
with a minimal amount of implementation logic.

An OpenAPI definition can then be used by documentation generation tools 
to display the API, code generation tools to generate servers and clients 
in various programming languages, testing tools, and many other use cases.

- swagger.io

 

요약하자면, 사용자는 최소한의 구현 논리로 서비스를 이해하고 상호 작용할 수 있습니다.

그럼, swagger가 어떻게 생겼는지 먼저 확인해볼까요 ?

 

 

 

위와 같이 프로젝트 내에서 정의한 내용들을 보기좋은 UI로 제공합니다.

자, 이제 swagger에 대한 이해가 되었을까요❓ 

이제부터는 node 프로젝트에 적용시켜보겠습니다 〰️ 

 

 

 

⏳   Swagger Settings

크게 먼저 보면, 

npm 모듈을 설치하고, 그 이후에 swagger에 대한 옵션등을 설정을 하겠습니다.

그리곤 path를 설정해 자신의 IP에서 확인할 수 있도록 설정합니다.

 

 

✔️ npm module 설치

자 먼저, npm 모듈을 설치할 거예요.

 

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

 

위와 같이 두 개의 모듈을 설치합니다.

 

swagger는 개발용 모듈이기 때문에 devDependencies에 추가해줘야겠죠❓

그래서 [--save-dev] 옵션을 붙여주었습니다.

 

 

✔️ Options

지금부터는 Basic Structure를 설정해볼게요.

공식 문서에 더 자세히 나와있습니다. 

 

프로젝트 구조와 파일 형식은 다 다르겠지만, 저는 modules라는 폴더에 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:3300',
        basePath: '/'
    },
    apis: ['./routes/*.js', './swagger/*']
};

const specs = swaggereJsdoc(options);

module.exports = {
    swaggerUi,
    specs
};

 

모듈을 불러오고 옵션을 설정한 내용들 뿐입니다.

swaggerDefinition는 yaml 형식이나 json 형식을 받습니다.위는 json을 사용했죠 〰️ 

 

info 객체는 title, version, description 을 설정했습니다.

링크에 들어가시면 더 자세한 내용들을 확인할 수 있습니다 !

 

apis 는 내가 설정한 api들을 swagger가 찾을 수 있도록 표시해줍니다.

"/routes 파일 아래 js 파일 내에 정의 하고 있으며, /swagger 폴더 아래 swagger 설정을 정의하고 있다"를 명시해준거죠. 

 

이제 설정을 했으니, 적용을 시켜보겠습니다.

 

 

✔️ app.js, 라우팅 설정

 

먼저, swagger.js 를 불러옵니다.

 

const { swaggerUi, specs } = require('./modules/swagger');

 

그리곤, /api-docs 라는 path로 등록시켜줍니다.

 

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));

 

이 부분은 모든 path를 정의하기 전 (express에서는 indexRouter 윗 부분) 에 정의하는 게 좋겠죠?

 

여기까지 했다면, 설정은 끝났습니다 ❗️

여기까지 실행을 해보면 /api-docs 에 아래와 같이 뜨는 것을 확인할 수 있습니다 !

 

 

 

 

 

🤖  Swagger, 정의하기

자 이젠 생성한 api를 리스트에 등록해볼게요 !

 

✔️  API 등록

/**
 * @swagger
 *  /product:
 *    get:
 *      tags:
 *      - product
 *      description: 모든 제품 조회
 *      produces:
 *      - application/json
 *      parameters:
 *        - in: query
 *          name: category
 *          required: false
 *          schema:
 *            type: integer
 *            description: 카테고리
 *      responses:
 *       200:
 *        description: 제품 조회 성공
 */
router.get('/', getList);

 

swagger를 기존 js 파일에 적용하려면 @swagger을 반드시 붙여주셔야 합니다 !

그 아래에는 /product가 있는데요.

경로를 나타냅니다.

 

경로를 설정하는 데에는 몇 가지 방법을 확인할 수 있는데요.

 

 

📌  경로 설정

1. 아주 기본적으로 /path 만을 적을 수 있습니다.

2. 파라미터를 넣을 수 있습니다. /path/{path_parameter_name} 

query는 아래 parameters에 정의를 해주어야 합니다.

parameters 아래에 in : path로 설정하면 됩니다

3. query를 추가할 수도 있습니다. /path/query=q1 이 형태는 어떻게 표시할까요?

parameters 아래 보면 in : query 를 확인할 수 있습니다 !

 

📌  메소드

그 아래에는 메소드를 get, post, put, delete 등등 을 설정합니다.

 

 

📌 그 밖의 통신 규칙과 설명들

그 아래에 다양한 설정들을 볼 수 있습니다.

 

tags 는 해당 API의 태그인데요. /api-docs 페이지에서 그 태그 별로 리스팅해줍니다.

description 는 해당 API를 설명하고

produces 는 content-type을 명시합니다.

parameters, requestBody, reposnses

등이 있습니다. 내부 정의 내용은 비슷하니 설명은 생략하겠습니다!

링크 걸어두었으니, 필요할 때마다 찾아보세요 !

 

 

 

✔️  컴포넌트 정의

이번엔, 컴포넌트를 정의를 해보겠습니다.

 

# /swagger/product.yml

components:
  schemas:
    Product:
      properties:
        id:
          type: integer
          description: 제품 고유 번호
        title:
          type: string
          description: 제품 이름
        main_image:
          type: string
          description: 제품 메인 이미지
        discount:
          type: integer
          description: 할인 내역

 

참고로, yaml(yml)은 JSON과 XML과 같이 데이터 직렬화 양식이지만, 

들여쓰기만을 이용하는 나열하는 아주아주 간단한 표기법입니다.

 

이젠 components를 정의해볼게요.

path 정의와는 다르게, components로 시작합니다.

이렇게 정의해두고 api의 결과 객체를 설명해줄 수 있습니다.

위의 파일을 적고 나서 가장 중요한건, api 설정에 추가해주어야 한다는 점입니다.

 

 

/**
 * @swagger
 *  /product:
 *    get:
 *      // ... 
 *      responses:
 *       200:
 *        description: 제품 조회 성공
          // 아래 schema 추가
 *        schema:
 *          $ref: '#/components/schemas/Product'
 */
 router.get('/', getList);

 

schema: $ref를 추가해줍니다.

 

 

 

보이시나요?

맨 아래 Example Value에 정의 했던 id, title, main_image, discount 가 출력되었습니다.

한 번 정의해두면 여러번 적지않아도 내용을 전달할 수 있겠죠 ?

 

 

위에는 Model을 누른 상태입니다.

 

위와 비슷하게 definitions이 있는데, 둘 다 model을 정의합니다.

 

 

definition

조금 다른 것을 보았나요?

자세한 설명은 생략하고 이만 마무리 하겠습니다 〰️ 

반응형

Backend Software Engineer

Gyeongsun Park