0.4.0 • Published 1 year ago

node-msa-openapi-tatum v0.4.0

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

NODE-MSA-OPENAPI-TATUM

개요

  • NodeJS 서버로 이루어진 MSA 환경에서 계층적으로 생성되는 OpenAPI 문서들을 통합하고 이를 사용자에게 제공하기 위한 모듈

모듈 구성

ApiScanner

  • 해당 서버의 API 구성을 OpenAPI를 명세를 이용하여 스캔

ApiIntegrator

  • 해당 서버 이하의 마이크로서비스들에 대한 API 문서 통합을 설정한 디렉터리에서 수행

ApiFileAgent

  • Api 파일 관련 I/O 수행

Decorator

  • 기존 nestjs/swagger의 ApiSecurity 데코레이터의 비효율을 해결
    // user.controller.ts
    @Controller('user')
    export class UserController {
      @ApiSecurity('securityCategory',["requirement"])
      @UseGuards(MyGuard)
      @Get(':id')
      getUser(@Param('id') userId: string) {
        return this.userService(userId);
      }
    }
  • 사용 가드의 바인딩과 해당 가드의 정보가 각각 관리되는 구조 (ApiSecurity 데코레이터에 리터럴 형식으로 입력)
  • 이를 위해 NestJS 가드 클래스에 데코레이터를 하나 추가하면, 이후 해당 가드를 컨트롤러에 바인딩할 때 자동으로 가드의 정보가 OpenApi 문서에 추가

ConfigParser

  • 설정 파일을 읽어온 뒤 검증 후 반환

사용

의존성 추가

npm i node-msa-openapi-tatum

Write Config file (.js|.json)

  • config.js

    module.exports = {
      outDir: string; // openAPI 문서를 내보낼 상대 경로 입력 ex "./doc"
      microservices: {
        [microserviceName: string]: { // 서비스들의 이름 ex "gateway", "user"
          appModuleName: string; // NestJS 인스턴스 생성을 위한 루트 모듈 클래스명 ex "AppModule"
          appModulePath: string; // 프로젝트 루트 경로를 기준으로 해당 서비스의 tsc 빌드된 루트 모듈의 상대 경로 ex "./dist/microservice/user/src/app.module"
          globalPrefix: string; // 해당 서비스에 설정된 전역 Api prefix ex. "api"
          isGateway: boolean; // 해당 서비스의 게이트웨이 여부
          openApi: {
            title: string; // openAPI 문서에 명시할 title
            description: string; // openAPI 문서에 명시할 description
            version: string; // openAPI 문서에 명시할 version
            tags: TagObject[]; // openAPI 문서에 명시할 tags
          };
        };
      };
    };
  • config.json

    {
      "outDir": string; // openAPI 문서를 내보낼 상대 경로 입력 ex "./doc"
      "microservices": {
        [microserviceName: string]: { // 서비스들의 이름 ex "gateway", "user"
          "appModuleName": string; // NestJS 인스턴스 생성을 위한 루트 모듈 클래스명 ex "AppModule"
          "appModulePath": string; // 프로젝트 루트 경로를 기준으로 해당 서비스의 tsc 빌드된 루트 모듈의 상대 경로 ex "./dist/microservice/user/src/app.module"
          "globalPrefix": string; // 해당 서비스에 설정된 전역 Api prefix ex. "api"
          "isGateway": boolean; // 해당 서비스의 게이트웨이 여부
          "openApi": {
            "title": string; // openAPI 문서에 명시할 title
            "description": string; // openAPI 문서에 명시할 description
            "version": string; // openAPI 문서에 명시할 version
            "tags": TagObject[]; // openAPI 문서에 명시할 tags
          };
        };
      };
    };

Using GuardDecorator

  • user.guard.ts

    import { CanActivate, ExecutionContext } from '@nestjs/common';
    import { ApiDecoratorForGuard } from 'node-msa-openapi-tatum';
    import { Observable } from 'rxjs';
    
    @ApiDecoratorForGuard('security 종류(ex.bearer)', ['이게 필요해요.'])
    export class TestGuard implements CanActivate {
      canActivate(
        context: ExecutionContext,
      ): boolean | Promise<boolean> | Observable<boolean> {
        return true;
      }
    }
    
    @ApiDecoratorForGuard('test', ['accessToken', 'refreshToken'])
    export class TestGuard2 implements CanActivate {
      canActivate(
        context: ExecutionContext,
      ): boolean | Promise<boolean> | Observable<boolean> {
        return true;
      }
    }
  • user.controller.ts

    import { Body, Controller, Get, Param, Post } from '@nestjs/common';
    import axios from 'axios';
    import { UseGuardsForOpenApi } from 'node-msa-openapi-tatum';
    import { TestGuard, TestGuard2 } from 'src/app.guard';
    import { CreateUserDto } from './dto/createUserDto';
    
    @Controller('user')
    export class UserController {
      // @ApiSecurity('security 종류(ex.bearer)', ['이게 필요해요.'])
      // @ApiSecurity('test', ['testtest'])
      // @UseGuards(TestGuard,TestGuard2)
      // 원래는 위와 같이 비효율적인 구조로 데코레이터를 추가해야 했으나 해당 패키지에서는 아래 하나의 데코레이터로 위 로직 추가 가능
      @UseGuardsForOpenApi(TestGuard, TestGuard2)
      @Get(':id')
      async getUserInfo(@Param('id') userId: string) {
        const result = await axios
          .get<{ id: string; email: string }>(
            `http://user_service:3001/user/${userId}`,
          )
          .then((res) => res.data)
          .catch(() => ({ id: '실패', email: '실패' }));
        return result;
      }
    }

빌드 시 API 문서 생성

// tsc 실행 후 서버 로직 진입점이 dist/src/main.js에 존재할 경우
npx tatum-openapi scan .[config].js

생성된 OpenAPI 문서 통합

// tsc 실행 후 서버 로직 진입점이 dist/src/main.js에 존재할 경우
npx tatum-openapi integrate .[config].js

License

MIT

0.4.0

1 year ago

0.3.4

1 year ago

0.3.3

1 year ago

0.3.2

1 year ago

0.3.1

1 year ago

0.3.0

1 year ago

0.2.6

1 year ago

0.2.5

1 year ago

0.2.4

1 year ago

0.2.3

1 year ago

0.2.1

1 year ago

0.2.0

1 year ago

0.1.6

1 year ago

0.1.5

1 year ago

0.1.4

1 year ago

0.1.3

1 year ago

0.1.2

1 year ago

0.1.1

1 year ago

0.1.0

1 year ago

0.0.15

1 year ago

0.0.14

1 year ago

0.0.13

1 year ago

0.0.12

1 year ago

0.0.11

1 year ago

0.0.10

1 year ago

0.0.9

1 year ago

0.0.8

1 year ago

0.0.7

1 year ago

0.0.6

1 year ago

0.0.5

1 year ago

0.0.4

1 year ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago