快速开始
适用于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 时尝试刷新 1 次(/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 → 强制缓存 + 重新验证
- 其他情况 → 不存储
- 通过headersProvider注入请求特定的Cookie / Authorization
- 发生401时,如果有onServer401则执行(通常是redirect())
Next.js集成示例:项目rxjsHttpService/commonService的完整代码
下面的rxjsHttpService.ts是后续生成器示例中commonServiceFile所指的项目公共HTTP适配器。该库生成的文件不是项目直接管理的,而是核心客户端 + 会话认证 + CSR缓存 + SSR缓存助手集中导出。以下是完整代码。
rxjsHttpService.ts
tsAPI参考(核心)
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客户端外,还提供了一个Node脚本,用于从OpenAPI/Swagger JSON生成类型/服务代码。该脚本是可选功能。
一般的@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 和自动生成服务一起使用的项目集成示例。上面的核心用法和选择功能可以仅通过 typed-rx-http 使用,下面的流程是在使用 Swagger 基础服务自动生成的项目中额外应用的。
1. 在后端编写 REST 端点
后端代码按常规编写。在此示例中,使用路径变量接收名称,使用查询参数接收消息 Mono并返回响应。
TypedRxHttpExampleRouter.java
java2. 在 Swagger 中生成前端服务
接收后端的 swagger.json生成类型和服务文件。此操作可以在运行开发服务器时调用一次,或通过 watch 脚本连接。
generateSwagger.cjs
js3. 通过生成的函数发送请求
可以在下面更改 前端代码和 后端代码。 结果点击将打开右侧的执行界面。更改值后,点击请求按钮。