Typescript

[Tspec] TypeScrip 기반 OpenApi Spec,Swagger 만들기

차노도리 2023. 7. 9. 22:42

Tspec

  • TypeScript 타입과 JSDoc 기반으로 OpenApi를 자동으로 생성하게 해주는 라이브러리

 

 

https://ts-spec.github.io/tspec/

 

Tspec | Tspec

Tspec Type-driven API Documentation Auto-generating REST API document based on TypeScript types

ts-spec.github.io

 

Tspec 사용 방법

1. 의존성 주입

  • npm install tspec
  • yarn install tspec

 

2. 타입 지정하기

  • 주의사항 
    • never 등 특정 타입들 인식 못하는 버그 있음
    • 알리아스로 import 하면 타입 인식 못하고 string으로 나오는 버그 있음

ex) type.ts

/** 회원 종류 KEY */
export type CodeEnumsMemberType =
  | "ANY"
  | "CORPORATION"
  | "FRANCHISE"
  | "NONE"
  | "PERSONAL";

/**
 * 로그인 요청 Reqeust
 */
export interface LoginBffRequest {
  /**
   * 회원 아이디
   *
   * example: gugbab01
   **/
...
}

/**
 * 로그인 요청 Response
 */
export interface LoginBffResponse {
  /**
   * 아이디
   *
   * example: gugbab01
   **/
...
}

...

 

 

3. swagger router 정의하기

import { Tspec } from "tspec";
import {
  LoginBffRequest,
  LoginBffResponse,
  UserInfoResponse,
  UserLeaveRequest,
} from "../type/sampleType";

export type UserApiSpec = Tspec.DefineApiSpec<{
  tags: ["회원"];
  basePath: "/api";
  paths: {
    "/member": {
      get: {
        summary: "로그인 회원정보 조회";
        responses: { 200: UserInfoResponse };
      };
      patch: {
        summary: "회원 탈퇴";
        body: UserLeaveRequest;
        responses: { 200: true | false };
      };
    };
    "/member/login": {
      post: {
        summary: "회원 가입";
        body: LoginBffRequest;
        responses: { 200: LoginBffResponse };
      };
    };
  };
}>;

 

 

4-1OpenApi Spec 확인하기

  • tspec generate : OpenApi Spec json 파일을 생성
    • --specPathGlobs : 읽을 패턴 지정
    • --outputPath : OpenApi Spec 저장 경로 위치
    • --oepnapiTitle: 생성된 문서의 title
"scripts": {
	...
	"tspec": "tspec generate --specPathGlobs ./**/*.ts --outputPath ./gugbab-tspec.json --openapiTitle 'Gugbab Tspec'"
  },

 

4-2 미들 웨어를 통해서 swagger-ui, mock 데이터 설정하기

import express from "express";
import { Tspec, TspecDocsMiddleware } from "tspec";

const server = express();

const options: Tspec.InitTspecServerOptions = {
  specPathGlobs: ["./router/**/*.ts"],
  specVersion: 3,
  openapi: {
    title: "Gugbab Tspec",
  },
  debug: false,
  ignoreErrors: true,
};

const router = express.Router();

router.get("/member", (req, res) => {
  res.status(200).json({
    userName: "국밥",
    memberType: "PERSONAL",
    mobileNumber: "032-1234-1234",
  });
});

router.post("/member/login", (req, res) => {
  res.status(200).json({
    userId: "gugbab",
    userName: "국밥",
    memberType: "PERSONAL",
    mobileNumber: "032-1234-1234",
  });
});
router.patch("/member", (req, res) => {
  res.status(200).json(true);
});

async function initServer() {
  server.use("/api", router);
  server.use("/docs", await TspecDocsMiddleware(options));

  server.listen(9000);
}

initServer();

 

 

결과 화면