エクスプレス、タイプスクリプトとSwagger


私は、それからフロントエンドとバックエンドコードを書いています.NodeJSでWebサーバーを書くのは簡単です、そして、私はnodejsを使用する際にどんな重大な問題も決して見つけませんでした.によるとStack Overflow 2020 survey , NodeJSは最も人気のある技術です.私は好むExpress with NodeJS . それは最も人気のあるノードの一つです.Webアプリケーションフレームワーク.複数のフレームワークがあり、必要に応じてどちらを選択することができます.
作業後TypeScript , それはJSとTSの間の選択の私の好ましい言語になりました.typescriptはJavaScriptのスーパーセットです、すべての有効なJSが有効なタイプスクリプトであることを意味します.JavaScriptを既に知っていれば簡単です.TypeScriptは、第2の最も好きな言語Stack Overflow 2020 survey . JavaScriptコードに静的な型を追加するのに役立ちます.これは、コードの書き込み、維持、デバッグに非常に役立つです.

何を築く
Express APIサーバをExpressとTypesScriptでビルドします.これは、生産JavaScriptコードを生成するbuild コマンド.これは自動的に開発中に任意のコードを変更するサーバーを再起動し、自動でOpenAPIドキュメントを生成するSwagger .

ブートストラッププロジェクト
好みのアプリケーション名を持つディレクトリを作成し、その中に空のノードプロジェクトを設定しましょう.パッケージをカスタマイズすることができます.すべてのデフォルトオプションを-y フラッグトゥinit コマンド.
mkdir express-typescript
cd express-typescript
npm init -y
開発スクリプトとして
npm i -D typescript
追加tsconfig.json プロジェクトディレクトリのルートで.ここで定義outDir AS./build 生成されたJavaScriptファイルを生成します.好みのディレクトリ名を指定できます.必要に応じて設定ファイルをカスタマイズできます.チェックTypeScript Handbook 詳細はtsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "./build",
    "strict": true,
    "esModuleInterop": true
  }
}
ノードの依存性と型定義としてExpressをインストールし、開発依存性として表現します.
npm i -S express
npm i -D @types/express @types/node

サーバコードを書き込む
サーバーを稼働させるために最小限のコードを加えましょう.フォルダを作るsrc ルートフォルダの中.私たちはすべてのタイプスクリプトコードをその中に置くつもりです.それは個人的な選択による.プロジェクトのどこにでもコードを保つことができます.
このコードはExpressサーバを実行し、ポート8000を聞きます.追加する/ping これはJSONレスポンスをGETコールで返信します.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);
});
ビルドコマンドを加えましょう.TypeScriptコードをJavaScriptに移行し、生成されたコードを出力ディレクトリに出力しますtsconfig.json .package.json
"scripts": {
  "build": "tsc",
}
では、ビルドコマンドでJavaScriptコードを構築しましょう.
npm run 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 パッケージへのスクリプト.nosonコマンドを実行するJSON.パッケージにnodemon configを追加します.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 . サーバーに3つのミドルウェアを追加します.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

リファクタ
今までサーバーは1つのファイルです.小さなサーバにとっては大丈夫ですが、1つのファイルであればサーバを拡張することは困難です.そこで、複数のファイルを作成します.
PINリクエストのコントローラを作成しましょうsrc/controllers/ping.ts パス.ここではクラスと呼ばれるクラスを追加しますPingController 方法でgetMessage , プロパティメッセージを文字列として応答インタフェースを定義します.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ドキュメントをSwaggerで追加しましょう.我々は加える必要があるtsoa すべてのAPIに対してOpenAPI仕様のJSONファイルを生成します.我々も必要swagger-ui-express swagger jsonをswagger UIでホストする.
npm i -S tsoa swagger-ui-express
npm i -D @types/swagger-ui-express concurrently
我々は、デコレータのサポートを追加する必要がありますtsconfig.json ファイル.tsconfig.json
{
  "compilerOptions": {
    ...
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}
TSOAの設定ファイルを作成する必要があります.追加tsoa.json ディレクトリのルートで.追加entryFile and outputDirectory で設定します.ここで設定しますpublic 生成されたJSONファイルの出力フォルダとして.tsoa.json
{
  "entryFile": "src/index.ts",
  "noImplicitAdditionalProperties": "throw-on-extras",
  "spec": {
    "outputDirectory": "public",
    "specVersion": 3
  }
}
swaggerドキュメントを生成するために、devとbuildコマンドを更新します.追加tsoa spec swaggerドキュメントを生成します.私たちはswagger コマンドとdevコマンドの前にprebuild and predev それぞれ.追加concurrently devコマンドに対して、nodemonとtsoa specを並列に実行します.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",
    };
  }
}
すべての変更を行って、サーバーを実行した後http://localhost:8000/docs/ APIドキュメントにアクセスします.
このチュートリアルのすべてのソースコードは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