概要
TypeScript用RxJSベースのタイプセーフHTTPクライアントとオプションのNext.js/RSocketアダプター
@byeolnaerim/typed-rx-httpはOpenAPIスタイルのPathsタイプを注入し、URL、HTTPメソッド、path/queryパラメータとリクエストボディをタイプで検査しながらリクエストし、結果をRxJS Observableで返すHTTPクライアントです。
私がこのライブラリで求めていたのは、壮大な HTTP 抽象化ではありませんでした。バックエンドで作成した URL とリクエスト/レスポンス DTO をフロントで再度作成せず、生成された関数をインポートして直接呼び出すことでした。
Core基本使用方法
基本フローはOpenAPIスタイルのPathsタイプを準備し、必要に応じてHeaderStoreを作成した後、createHttpClient<Paths>()でクライアントを生成し、callApi<R>()を呼び出すことです。自動サービス生成器やWebFluxバックエンドはこのフローの必須条件ではありません。
リクエストタイプはPathsで決定され、レスポンスタイプはcallApi<R>()のRを呼び出し元が選択します。特定のResponseWrapperも強制されません。NDJSON、CSRキャッシュ、セッション認証、Next.jsとRSocket機能は必要な場合にのみ追加します。
起源の物語
私はフロントで Next.js と TypeScript を使用し、バックエンドでは Java と WebFlux を使用しています。この組み合わせでプロジェクトを作成していると、同じ内容を両方で繰り返し書くことが非常に多くなりました。
バックエンドではエンティティとリクエスト/レスポンス DTO を作成し、エンドポイントを記述します。しかし、フロントでそのエンドポイントを呼び出すには URL を再度タイピングし、バックエンド DTO とほぼ同じ型やインターフェースを再度作成しなければなりませんでした。正直に言うと、バックエンドで私が作成したものをフロントで再度作成するのと変わりませんでした。
このような繰り返しはコードの量を増やすだけでなく、一方のフィールドや URL が変更されたときに他方を見落とす可能性も高めました。したがって、バックエンドの REST API 仕様をフロント HTTP クライアントコードとして予測可能に生成する必要性を強く感じました。
その過程で実際のプロジェクトである nplauction.com にバックエンド用reactive-mongo-dslとwebflux-fe-dev-assistantのプロトタイプを、フロントには typed-rx-http のプロトタイプをまず適用しました。typed-rx-http は最初から別のアイデアで始まったというより、webflux-fe-dev-assistant を作成する中でフロントに必要なペアを一緒に作成していく中で副次的に生まれたライブラリに近いです。
Swagger自動生成プロジェクトでの使用方法
Swaggerサービスの自動生成を使用するプロジェクトでは、画面コードから createHttpClientや URL を毎回作成することはありません。プロジェクトに commonService.tsというプロジェクト所有の共通HTTPアダプターを一度作成し、OpenAPIで生成されたサービス関数のみをインポートして使用します。commonService.tsはライブラリが生成するファイル名ではなく、プロジェクトが定めるファイル名であり、始めに/HTTP Clientドキュメントで全コードを確認できます。
const response = await firstValueFrom(
workplacesSearch({ params: { keyword: "kim" } }),
);上記のコードにはURL文字列や手動で作成したレスポンスインターフェースはありません。URL、HTTPメソッド、パラメータ型とレスポンスタイプは生成されたサービスに含まれます。一度の応答は firstValueFromで受け取り、作業の進行状況のように複数の値が続くリクエストはsubscribeで受け取ることができます。
どこで最も適合するか
バックエンドとフロントが分離されており、バックエンドで有効なswagger.jsonを提供できる場合、TypeScriptフロントエンドでの繰り返し作業を減らすことができます。Java WebFluxファンクショナルエンドポイントを使用する場合、webflux-fe-dev-assistantを組み合わせてドキュメント生成からサービス生成まで接続できます。
typed-rx-http CoreはWebFluxに依存しません。バックエンドの実装に関係なくOpenAPI仕様と互換性のあるTypeScript paths typeがある場合、文字列URLとリクエストタイプを毎回手動で記述する手間を減らすことができます。RSocketクライアントは/rsocketエントリーポイントで直接使用でき、route/request/responseサービスの自動生成が必要なプロジェクトでのみAsyncAPIジェネレーターを追加で使用できます。