快速開始
TypeScript 用的基於 RxJS 的類型安全 HTTP 客戶端 + (可選)Next.js/RSocket 適配器。
核心特點
- 通過從 Swagger/OpenAPI / AsyncAPI 派生的模式/自定義合約等獲得的 OpenAPI 風格的 Paths 類型(慣例上稱為 paths)來注入路由(請求)類型的穩定性。
- 所有 API 返回 RxJS Observable
- 核心是框架獨立的(不依賴於 Next.js)
- Next.js 專用功能分離為 @byeolnaerim/typed-rx-http/next 入口點 → 只有在導入 /next 時才需要 Next.js
- RSocket 專用功能分離為 @byeolnaerim/typed-rx-http/rsocket 入口點 → 只有在導入 /rsocket 時才需要 RSocket 套件
安裝
npm
入口點
Core (框架獨立)
Next.js 適配器(可選)
在不使用 Next.js 的專案中,請勿導入 /next。
RSocket 適配器(可選)
僅在使用 RSocket 的專案中安裝 peer 套件。
在不使用 RSocket 的專案中,請勿導入 /rsocket。
核心用法
1) 準備 Paths 類型(通常是 OpenAPI paths)
createHttpClient<Paths>() 的 Paths 表示“請求規範(路由)”的類型。文檔中慣例上稱為 paths,但不一定需要是 OpenAPI/Swagger,也不一定需要名稱為 paths。
不過核心內部使用 OpenApiPathsLike 約束,因此,Paths 必須類似於 OpenAPI paths 的形式。
- 最上層鍵:URL 路徑字符串(例如:"/users/{id}")
- 下層鍵:HTTP 方法(get/post/put/delete/patch …)
- 每個方法內存在 parameters.query/path/header/cookie、requestBody、responses 等字段(或 never)
核心主要參考上述結構中的以下字段來構建 ServiceArguments 的類型。
- url: keyof Paths
- method: keyof Paths[url]
- queryString: parameters.query
- pathVariable: parameters.path
- body: requestBody
例如:openapi-typescript 的輸出通常如下所示(部分簡化)。
2) 創建 HeaderStore
HeaderStore 是一個簡單的內存存儲,用於管理 CSR 的基本標頭。
3) 創建 HTTP 客戶端
- headerStore 是可選的,但建議在 CSR 中使用基本標頭/會話認證時包含它。
- headersProvider 用於需要每次請求計算標頭的情況,如 SSR/多租戶。
4) API 調用(類型安全)
請求類型(url/method/pathVariable/queryString/body)由用戶注入到 createHttpClient<Paths>() 的類型(慣例上為 OpenAPI paths)決定。響應類型由調用者在 callApi<R>() 中選擇的泛型 R 決定(核心不會自動推斷 responses)。
響應包裝(ResponseWrapper)— 可選
此庫不強制響應包裝。可以根據 API 自行選擇泛型響應形式。
包裝的響應
未包裝的響應
流式傳輸(NDJSON)
當服務器返回 NDJSON(每行一個 JSON)時,使用 callApiStream。如果沒有 Accept 標頭,則默認設置為 application/x-ndjson。
CSR 緩存(客戶端緩存)
createCsrCache<CacheName>() 提供的功能:
callApiCsrCache(callApiFn, serviceArgs, cacheOptions)- removeCsrCache(cacheName) — 支持類型緩存名 + 字符串
基於會話的認證插件(可選)
createSessionAuth 將會話認證邏輯從核心中分離,作為選項附加或移除。
操作:
- 將 Authorization 保持在 headerStore 中
- 使用 ensureToken$() 同步令牌(/api/auth/token)
- 當發生 401 時,嘗試刷新一次(/api/auth/token/refresh),然後重試原請求
- 刷新失敗時,登出(/api/auth/logout)並傳遞錯誤
- 登錄狀態變更由 onLoginChange 回調在外部處理
如果只需要令牌同步而不需要刷新/重試:
錯誤處理
如果不是 2xx,則拋出 HttpResponseError(包括 status、response、args、data)。
舊版兼容:如果錯誤主體為 { resultType: ... } 形式,則直接拋出該對象。
Next.js 適配器(/next)
redirectToUnauthorizedOnServer401
redirectToUnauthorizedOnServer401 是在 Next.js(App Router)SSR 環境中發生 401 時執行重定向的基本實現(便捷函數)。
操作規則(固定):
- 重定向目標:/unauthorized
- queryString:redirect_uri=<當前頁面> + logout=true
- 當前頁面從 x-page-url 標頭中讀取(如果不存在則為 /)
也就是說,只有當上述路徑/查詢規則與項目匹配時,才可以直接使用。如果路徑不同或查詢規則不同,則可以像下面這樣直接實現 onServer401 並注入。
callApiSsrCache
Next 的 next/cache(unstable_cache) 基礎 SSR 快取助手。
- GET + cacheTime > 0 → 強制快取 + 重新驗證
- 其他 → no-store
- 透過 headersProvider 注入每個請求的 Cookie / Authorization
- 當發生 401 時,如果有 onServer401 則執行(通常是 redirect())
Next.js 整合範例:專案 rxjsHttpService/commonService 全部代碼
以下 rxjsHttpService.ts 是後續 generator 範例的 commonServiceFile 所指的專案共用 HTTP adapter。這不是庫生成的文件,而是專案直接管理,並將 core client + session auth + CSR cache + SSR cache helper 一併匯出。以下是全部代碼。
rxjsHttpService.ts
tsAPI 參考 (core)
createHttpClient<Paths>(options)
返回:
callApi<R>(args): Observable<R>callApiStream<RChunk>(args): Observable<RChunk>uploadFile({ file, url, ifNoneMatch?, headers? }): Observable<Response>createSSEObservable<R>(args): Observable<R>
選項:
baseUrl: stringheaderStore?: HeaderStoreheadersProvider?: () => Record<string, string> | Promise<Record<string, string>>- dropAuthWhenCacheControl?: boolean (預設值: true)
onServer401?: () => void | Promise<void>
createHeaderStore(initial?)
get(), set(), merge(), remove(), clear()
createCsrCache<CacheName>()
callApiCsrCache(callApiFn, serviceArgs, cacheForService)- removeCsrCache(cacheName) (類型 + 字串)
createSessionAuth(options)
withSessionAuth(), withEnsureToken()ensureToken$(), refreshToken$(), logout$()
運行時需求
- fetch / Response API 使用 (rxjs/fetch)
- 串流 (NDJSON) 需要 ReadableStream + TextDecoder
- SSE 需要 EventSource
大多數最新瀏覽器和 Next.js 運行時都內建支援。在自訂 Node 運行時中可能需要 polyfill。
自動 Node 腳本:OpenAPI/Swagger 代碼生成(選擇性)
此套件除了運行時 HTTP 客戶端外,還提供一個從 OpenAPI/Swagger JSON 生成類型/服務代碼的 Node 腳本。此腳本為選擇性功能。
一般的 @byeolnaerim/typed-rx-http, /next, /rsocket 使用者無需執行此腳本,也不需要安裝 openapi-typescript。
依賴隔離
OpenAPI 類型生成需要 openapi-typescript CLI。但此套件不會將 openapi-typescript 放入一般依賴中。
@byeolnaerim/typed-rx-http 庫本身使用 devDependencies.typescript 的 TypeScript 6.0.3。typed-rx-http, /next, /rsocket 入口點和庫構建保持此 TypeScript 6.0.3 標準。
不過 openapi-typescript 可能仍然需要特定的 TypeScript 5.x 版本,因此 OpenAPI 自動 Node 腳本僅在單獨的 npx 臨時執行環境中與 openapi-typescript 和 [email protected] 一起執行。此臨時執行環境不會更改庫的 devDependencies.typescript 6.0.3,也不會使用用戶專案中安裝的 typescript 或 openapi-typescript 版本。
預設值是在自動腳本執行時僅生成並執行以下命令。
因此使用方法本身不會改變。用戶仍然可以像以前一樣調用自動 Node 腳本,並且在 OpenAPI 類型生成階段僅使用隔離的 TypeScript 5.9.3 環境。不使用自動腳本的用戶不會受到 openapi-typescript 或 TypeScript 5.9.3 的任何束縛。
如有需要,可以直接使用 openApiTypescriptCommand 鎖定命令。
或者僅更改組成基本命令的套件版本。
生成的檔案
預設會生成以下檔案。
apiUnionArrays.ts 不僅生成 OpenAPI schema enum,還生成 query、path、header、cookie 參數的 enum 作為常數陣列。也處理陣列 query 參數的 items.enum。
EventStream 監控
HTTP 單次請求
從本地檔案生成
現有專案整合範例:WebFlux + Swagger 自動生成
從這裡開始是後端 Swagger 與自動生成服務一起使用的專案整合範例。上面的 Core 使用方法和選擇功能可以僅使用 typed-rx-http 本身,而下面的流程則是在使用 Swagger 基礎的服務自動生成的專案中額外應用。
1. 在後端撰寫 REST 端點
後端代碼像平常一樣撰寫。在這個例子中,使用路徑變數接收名稱,使用查詢參數接收消息 Mono並作為回應。
TypedRxHttpExampleRouter.java
java2. 在 Swagger 中生成前端服務
接收後端的 swagger.json生成類型和服務檔案。這個操作可以在啟動開發伺服器時呼叫一次,或連接到監視腳本。
generateSwagger.cjs
js3. 使用生成的函數發送請求
可以在下面 前端代碼和 後端代碼進行更改。 結果按下後會在右側打開執行畫面。更改值後,請按請求按鈕。