Express, TypeScript 및 Swagger를 사용한 REST API 구축

나는 2017년부터 JS를 사용하기 시작했는데, 그때부터 나는 그것으로 전단과 후단 코드를 작성하고 있었다.NodeJS를 사용하여 웹 서버를 작성하는 것은 매우 쉽고, NodeJS를 사용할 때 심각한 성능 문제를 발견하지 못했다.Stack Overflow 2020 survey에 따르면 NodeJS는 가장 유행하는 기술이다.저는 ExpressNodeJS을 더 좋아합니다.그것은 가장 환영받는 노드 중의 하나다.js 웹 응용 프로그램 프레임워크다양한 프레임워크가 있어 필요에 따라 선택할 수 있습니다.
TypeScript을 사용한 후에 이것은 내가 JS와 TS 사이에서 선택한 첫 번째 언어가 되었다. TypeScript는 자바스크립트의 초집합으로 모든 효과적인 JS가 효과적인 TypeScript라는 것을 의미한다.따라서 자바스크립트에 대해 이미 알고 있다면 Typescript를 배우는 것은 매우 쉽다.Stack Overflow 2020 survey의 통계에 따르면 TypeScript는 두 번째로 인기 있는 언어이다.TypeScript는 Javascript 코드에 정적 유형을 추가하는 데 도움을 줍니다.그것은 코드를 작성하고 유지하며 디버깅하는 데 매우 유용하다.

당신은 무엇을 지을 것입니까
Express 및 TypeScript를 사용하여 RESTAPI 서버를 구축합니다.build 명령에서 운영 JavaScript 코드를 생성합니다.개발 과정에서 코드가 변경되면 자동으로 서버를 재부팅하고 Swagger의 OpenAPI 문서를 자동으로 생성합니다.

프로젝트 부트
선택한 프로그램 이름으로 디렉터리를 만들고 빈 노드 항목을 설정합니다.사용자 정의 패키지를 선택할 수 있습니다.json 또는 -y 로고를 init 명령에 전달함으로써 모든 기본 옵션을 수락합니다.
mkdir express-typescript
cd express-typescript
npm init -y
Typescript를 개발 종속성으로 설치
npm i -D typescript
프로젝트 디렉터리의 루트 디렉터리에 tsconfig.json을 추가합니다.여기서 outDir./build으로 정의하여 생성된 JavaScript 파일을 배치합니다.너는 너의 첫 번째 디렉터리 이름을 입력할 수 있다.필요에 따라 구성 파일을 사용자 정의할 수 있습니다.자세한 내용은 TypeScript Handbook을 참조하십시오.tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "./build",
    "strict": true,
    "esModuleInterop": true
  }
}
노드와 개발 의존 관계에 대한 Express as dependency 및 유형 정의를 설치합니다.
npm i -S express
npm i -D @types/express @types/node

서버 코드 작성
서버가 정상적으로 작동하도록 최소한의 코드를 추가합니다.루트 폴더에 폴더 src을 만듭니다.우리는 모든 타자 스크립트 코드를 넣을 것이다.이것은 개인의 선택에 달려 있다.프로젝트의 모든 위치에 코드를 저장할 수 있습니다.
이 코드는express 서버를 실행하고 감청 포트 8000을 실행합니다.GET 호출에서 JSON 응답에 응답하는 /ping 라우트를 추가합니다.src/index.ts
import express, { Application } from "express";

const PORT = process.env.PORT || 8000;

const app: Application = express();

app.get("/ping", async (_req, res) => {
  res.send({
    message: "pong",
  });
});

app.listen(PORT, () => {
  console.log("Server is running on port", PORT);
});
build 명령을 추가합니다.TypeScript 코드를 JavaScript로 변환하고 생성된 코드를 tsconfig.json에 언급된 출력 디렉토리에 넣습니다.package.json
"scripts": {
  "build": "tsc",
}
이제 build 명령을 사용하여 JavaScript 코드를 만듭니다.
npm run build
위 명령을 실행하면 build 폴더에 생성된 JS 코드를 볼 수 있습니다.이제 노드가 생겨서 서버를 실행할 수 있습니다.http://localhost:8000/ping을 방문하여 JSON 응답을 확인할 수 있습니다.
node build/index.js

Server is running on port 8000

개발 설정 추가
서버가 시작되고 실행 중입니다.그러나 코드가 바뀔 때마다 수동으로 서버를 구축하고 실행해야 하기 때문에 개발은 여전히 어렵다.가장 좋은 것은 이 임무를 자동화하는 것이다.이를 위해, 우리는 ts-node을 사용하여 typescript 코드를 직접 실행할 것입니다. 그러면 개발 과정에서 typescript 컴파일러를 실행할 필요가 없습니다.코드가 바뀔 때마다ts노드를 다시 시작하려면 nodemon을 사용합니다. 코드를 감시하고 변경 사항이 있을 때 명령을 다시 실행합니다.
프로젝트에ts 노드nodemon을 개발 의존항으로 추가합니다.
npm i -D ts-node nodemon
패키지에 dev 스크립트를 추가합니다.json, nodemon 명령을 실행합니다.가방에 nodemon 설정을 추가합니다.json.구성을 별도의 파일로 저장할 수 있습니다.가방에 넣는 게 더 좋아요.프로젝트의 루트 디렉터리를 깨끗하게 유지하기 위해서 json입니다.여기에서, 우리는 nodemon을 설정하여 .ts 폴더의 모든 src 파일을 감시하고, 코드가 바뀔 때 ts-node src/index.ts을 실행합니다.package.json
  "scripts": {
    "build": "tsc",
    "dev": "nodemon",
  },

  "nodemonConfig": {
    "watch": [
      "src"
    ],
    "ext": "ts",
    "exec": "ts-node src/index.ts"
  }
dev 명령을 실행하면nodemon이 실행 중인 것을 볼 수 있습니다.서버도 이미 시작되어 실행되고 있습니다.
npm run dev

[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): src/**/*
[nodemon] watching extensions: ts
[nodemon] starting `ts-node src/index.ts`
Server is running on port 8000

중간 제품 추가
middlewares을 추가하여 서버를 확장하겠습니다.우리는 서버에 세 개의 중간부품을 추가할 것이다.express.json은 요청체를 분석하는 데 사용되는 내장 중간부품이고 express.static도 정적 파일을 서비스하는 내장 중간부품이며 morgan은 요청을 기록하는 데 사용된다.이것들을 의존항으로 설치하고, 그것들의 유형을 프로젝트의 개발 의존항으로 정의합니다.
npm i -S morgan
npm i -D @types/morgan
중간부품을 설치한 후, 우리는 코드에서 그것들을 사용할 수 있다.app.use() 기능을 사용하여 서버에 추가할 예정입니다.여기서는 정적 파일을 제공하기 위해 public 폴더를 사용합니다.src/index.ts
import express, { Application } from "express";
import morgan from "morgan";

const PORT = process.env.PORT || 8000;

const app: Application = express();

app.use(express.json());
app.use(morgan("tiny"));
app.use(express.static("public"));
이제 서버를 실행한 후 브라우저에서 http://localhost:8000/ping을 엽니다.우리는 요청이 터미널에 기록된 것을 볼 수 있다.
Server is running on port 8000
GET /ping 304 - - 2.224 ms

재구성
지금까지 서버는 파일일 뿐입니다.소규모 서버는 가능하지만 서버가 파일이라면 확장하기 어렵다.그래서 우리는 여러 개의 파일을 만들 것이다.src/controllers/ping.ts 경로의 ping 요청에 대한 컨트롤러를 만듭니다.여기에 사용 방법 PingControllergetMessage이라는 클래스를 추가했습니다. 속성 메시지가 있는 응답 인터페이스를 문자열로 정의합니다.src/controllers/ping.ts
interface PingResponse {
  message: string;
}

export default class PingController {
  public async getMessage(): Promise<PingResponse> {
    return {
      message: "pong",
    };
  }
}
현재 src/routes/index.ts 파일에 하위 공유기를 만들고 모든 루트를 그곳으로 이동합니다.서버에 이 하위 공유기를 중간부품으로 추가할 것입니다.src/routes/index.ts
import express from "express";
import PingController from "../controllers/ping";

const router = express.Router();

router.get("/ping", async (_req, res) => {
  const controller = new PingController();
  const response = await controller.getMessage();
  return res.send(response);
});

export default router;
src/index.ts
import express, { Application } from "express";
import morgan from "morgan";
import Router from "./routes";

const PORT = process.env.PORT || 8000;

const app: Application = express();

app.use(express.json());
app.use(morgan("tiny"));
app.use(express.static("public"));

app.use(Router);

app.listen(PORT, () => {
  console.log("Server is running on port", PORT);
});

허장성세의 통합
OpenAPI 문서를 대대적으로 추가합니다.모든 API의 OpenAPI 사양을 포함하는 JSON 파일을 생성하려면 tsoa을 추가해야 합니다.Swagger UI가 있는 Swagger JSON을 탑재하려면 swagger-ui-express이 필요합니다.
npm i -S tsoa swagger-ui-express
npm i -D @types/swagger-ui-express concurrently
tsconfig.json 파일에 Decorators 지원을 추가해야 합니다.tsconfig.json
{
  "compilerOptions": {
    ...
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}
tsoa를 위한 프로필을 만들어야 합니다.디렉토리의 루트 디렉토리에 tsoa.json을 추가합니다.구성에 entryFileoutputDirectory을 추가합니다.여기서 public을 생성된 JSON 파일의 출력 폴더로 설정합니다.tsoa.json
{
  "entryFile": "src/index.ts",
  "noImplicitAdditionalProperties": "throw-on-extras",
  "spec": {
    "outputDirectory": "public",
    "specVersion": 3
  }
}
dev 및 build 명령을 업데이트하여 Swagger 문서를 생성합니다.Swagger 문서를 생성하기 위해 tsoa spec을 추가했습니다.우리는 구축 전에 swagger 명령을 실행하고 각각 prebuildpredev을 사용하여 dev 명령을 실행할 것이다.dev 명령에 concurrently을 추가합니다. 이 명령은nodemon과tsoa규범을 병행적으로 실행합니다.개발 과정에서 코드 변경이 있을 때마다 자동으로 Swagger 문서가 업데이트됩니다.package.json
  "scripts": {
    "start": "node build/index.js",
    "predev": "npm run swagger",
    "prebuild": "npm run swagger",
    "build": "tsc",
    "dev": "concurrently \"nodemon\" \"nodemon -x tsoa spec\"",
    "swagger": "tsoa spec",
  },
Swagger UI 를 위해 서버 파일을 업데이트합니다.swagger-ui-express을 추가하여 관리되는 Swagger JSON 파일에 Swagger UI를 제공합니다.src/index.ts
import express, { Application, Request, Response } from "express";
import morgan from "morgan";
import swaggerUi from "swagger-ui-express";

import Router from "./routes";

const PORT = process.env.PORT || 8000;

const app: Application = express();

app.use(express.json());
app.use(morgan("tiny"));
app.use(express.static("public"));

app.use(
  "/docs",
  swaggerUi.serve,
  swaggerUi.setup(undefined, {
    swaggerOptions: {
      url: "/swagger.json",
    },
  })
);

app.use(Router);
이제 컨트롤러를 업데이트하고 API 문서의 경로와 경로를 정의하기 위해 클래스와 방법에 장식기를 추가합니다.tsoa에서는 반환 유형 PingResponse/ping 라우팅의 응답 유형으로 선택합니다.src/controllers/ping.ts
import { Get, Route } from "tsoa";

interface PingResponse {
  message: string;
}

@Route("ping")
export default class PingController {
  @Get("/")
  public async getMessage(): Promise<PingResponse> {
    return {
      message: "pong",
    };
  }
}
모든 변경 사항을 완료하고 서버를 실행한 후 API 설명서에 액세스하려면 http://localhost:8000/docs/을 방문하십시오.
이 강좌의 모든 소스 코드는 GitHub에서 얻을 수 있습니다.

추가 자원
  • Building a Node.js/TypeScript REST API, Part 1: Express.js

  • 다음
  • Building REST API with Express, TypeScript - Part 2: Docker Setup
  • Building REST API with Express, TypeScript - Part 3: PostgreSQL and Typeorm
  • Building REST API with Express, TypeScript - Part 4: Jest and unit testing
  • 좋은 웹페이지 즐겨찾기