日本語
ミドルウェア
ミドルウェアはリクエストをラップし、レスポンスを返します。ミドルウェア内では、リクエストを変更したり、next を 0 回以上呼び出したりできます。
ミドルウェア内では、next は fetch と同じように動作し、Request を受け取って Promise<Response> を返します。リクエストがネットワークに届く前にほかのミドルウェアを経由するかどうかは、呼び出す側からは分かりません。
ts
import { createClient, type Middleware } from "./api.ts";
const timing: Middleware = async (request, next, { operation }) => {
const start = performance.now();
try {
return await next(request);
} finally {
const name = operation.operationId ?? operation.path;
console.log(name, performance.now() - start);
}
};
const retry: Middleware = async (request, next) => {
for (let attempt = 0; ; attempt++) {
// リクエスト本体は 1 回しか送信できないため、コピーを送信する。
const response = await next(request.clone());
if (response.status < 500 || attempt === 2) return response;
}
};
const api = createClient({ middleware: [timing, retry] });ミドルウェアチェーンの動作
api.GET() のリクエストが、createClient の [timing, retry] と呼び出しごとの [cache] を経由する順序。各ミドルウェアは 1 回だけ呼び出され、await next(request) より前のコードが行きに、後のコードが帰りに実行されます。強調されている経路は、cache が next を呼び出さずに Response を返す場合を示しています。- 最初のミドルウェアが最も外側になります。個別の呼び出しに渡したミドルウェア(
api.GET("/pets", { middleware: [...] }))は、クライアントのミドルウェアの内側で実行されます。 nextはリクエストを次のミドルウェアに渡し、最後のミドルウェアではfetchに渡します。ミドルウェアがnextを呼び出さずにResponseを返すと、リクエストはネットワーク経由で送信されません。この仕組みはキャッシュやモックに役立ちます。fetch自体が発生させるエラーは、nextから発生します。- レスポンス本体の読み取りとデコードは、ミドルウェアチェーンが終了した後に行われます。そのため、ミドルウェアではレスポンスを調整でき、レスポンス本体の読み取り中に発生したエラーは
DecodeErrorも含めてnextから発生しません。
操作の情報
第 3 引数の { operation } には、OpenAPI ドキュメントに記述された操作の情報が格納されています。
| フィールド | 内容 |
|---|---|
method | 呼び出しで使われたとおりの HTTP メソッド |
path | /pets/{petId} などのパステンプレート |
operationId | operationId(ドキュメントに記述があるとき) |
security | 適用されるセキュリティ要件(ドキュメントでの記述順) |
with によるクライアント単位のミドルウェア
api.with(...middleware) は、渡したミドルウェアを元のクライアントのミドルウェアの内側で実行する新しいクライアントを返します。なお、api 自体は変更されません。
ts
const tenant = (id: string): Middleware => (request, next) => {
request.headers.set("x-tenant-id", id);
return next(request);
};
const acme = api.with(tenant("acme"));
await acme.GET("/pets");共有しているクライアントを直接変更する代わりに with を使うと、サーバー上で扱うテナントやユーザーのトークンなど、リクエストごとの状態がほかのリクエストに漏れるのを防げます。