Quick Start
Type-safe HTTP client based on RxJS for TypeScript + (optional) Next.js/RSocket adapter.
Core Features
- Inject OpenAPI-style Paths types (conventionally paths) obtained from Swagger/OpenAPI / AsyncAPI derived schemas / custom contracts to ensure route (request) type safety.
- All APIs return RxJS Observables.
- Core is framework-independent (no dependency on Next.js).
- Next.js specific features are separated into the @byeolnaerim/typed-rx-http/next entry point → Next.js is only needed when importing /next.
- RSocket specific features are separated into the @byeolnaerim/typed-rx-http/rsocket entry point → RSocket package is only needed when importing /rsocket.
Installation
npm
Entry Point
Core (framework-independent)
Next.js Adapter (optional)
Do not import /next in projects that do not use Next.js.
RSocket Adapter (optional)
Only install peer packages in projects that use RSocket.
Do not import /rsocket in projects that do not use RSocket.
Core Usage
1) Prepare Paths type (usually OpenAPI paths).
The Paths in createHttpClient<Paths>() represents the "request specification (route)" type. It is conventionally referred to as paths in the documentation, but it does not necessarily have to be OpenAPI/Swagger or named paths.
However, since the core internally uses the OpenApiPathsLike constraint, Paths should resemble OpenAPI paths as shown below.
- Top-level key: URL path string (e.g., "/users/{id}")
- Sub-key: HTTP method (get/post/put/delete/patch …)
- Each method contains fields such as parameters.query/path/header/cookie, requestBody, responses (or never).
The core primarily references the fields below to construct the type of ServiceArguments.
- url: keyof Paths
- method: keyof Paths[url]
- queryString: parameters.query
- pathVariable: parameters.path
- body: requestBody
Example: The output of openapi-typescript usually follows the format below (some abbreviations).
2) Create HeaderStore
HeaderStore is a simple in-memory store for managing default headers in CSR.
3) Create HTTP client
- headerStore is optional, but it is recommended to include it if you want to use default headers/session authentication in CSR.
- headersProvider is used when header calculation is needed for each request, such as in SSR/multi-tenant scenarios.
4) API call (type safe)
The request type (url/method/pathVariable/queryString/body) is determined by the type injected into createHttpClient<Paths>() (conventionally OpenAPI paths). The response type is selected by the caller as a generic R in callApi<R>() (the core does not automatically infer from responses).
Response Wrapping (ResponseWrapper) — optional
This library does not enforce response wrapping. You can choose the response format generically for each API.
Wrapped response
Unwrapped response
Streaming (NDJSON)
Use callApiStream when the server sends NDJSON (one JSON per line). If there is no Accept header, application/x-ndjson is set as the default.
CSR Cache (Client Cache)
Features provided by createCsrCache<CacheName>():
callApiCsrCache(callApiFn, serviceArgs, cacheOptions)- removeCsrCache(cacheName) — supports both type cache names and strings.
Session-based authentication plugin (optional)
createSessionAuth separates session authentication logic from the core, allowing it to be attached or detached as an option.
Operation:
- Maintain Authorization in headerStore
- Synchronize token with ensureToken$() (/api/auth/token)
- On 401, attempt refresh once (/api/auth/token/refresh) and retry the original request.
- On refresh failure, logout (/api/auth/logout) and pass the error.
- Changes in login status are handled externally via the onLoginChange callback.
If only token synchronization is needed without refresh/retry:
Error handling
Throws HttpResponseError if not 2xx (includes status, response, args, data).
Legacy compatibility: If the error body is in the form { resultType: ... }, that object is thrown as is.
Next.js adapter (/next)
redirectToUnauthorizedOnServer401
redirectToUnauthorizedOnServer401 is the default implementation (utility function) for performing a redirect when a 401 occurs in a Next.js (App Router) SSR environment.
Operation Rules (Fixed):
- Redirect target: /unauthorized
- queryString: redirect_uri=<current page> + logout=true
- The current page is read from the x-page-url header (or / if not present)
In other words, use the above path/query rules as is only when they match your project. If the path is different or the query rules are different, you can implement onServer401 directly as shown below.
callApiSsrCache
Next's next/cache (unstable_cache) based SSR cache helper.
- GET + cacheTime > 0 → force-cache + revalidate
- Otherwise → no-store
- Inject per-request Cookie / Authorization with headersProvider
- If onServer401 exists when a 401 occurs, it will be executed (usually redirect()).
Next.js integration example: Full code of project rxjsHttpService/commonService.
The rxjsHttpService.ts below is the common HTTP adapter for the project referred to by the commonServiceFile in the subsequent generator example. It is managed directly by the project, not generated by the library, and exports core client + session auth + CSR cache + SSR cache helper in one place. Below is the full code.
rxjsHttpService.ts
tsAPI Reference (core)
createHttpClient<Paths>(options)
Returns:
callApi<R>(args): Observable<R>callApiStream<RChunk>(args): Observable<RChunk>uploadFile({ file, url, ifNoneMatch?, headers? }): Observable<Response>createSSEObservable<R>(args): Observable<R>
Options:
baseUrl: stringheaderStore?: HeaderStoreheadersProvider?: () => Record<string, string> | Promise<Record<string, string>>- dropAuthWhenCacheControl?: boolean (default: true)
onServer401?: () => void | Promise<void>
createHeaderStore(initial?)
get(), set(), merge(), remove(), clear()
createCsrCache<CacheName>()
callApiCsrCache(callApiFn, serviceArgs, cacheForService)- removeCsrCache(cacheName) (type + string)
createSessionAuth(options)
withSessionAuth(), withEnsureToken()ensureToken$(), refreshToken$(), logout$()
Runtime Requirements
- Use fetch / Response API (rxjs/fetch)
- Streaming (NDJSON) requires ReadableStream + TextDecoder.
- SSE requires EventSource.
Most modern browsers and the Next.js runtime provide this by default. Custom Node runtimes may require polyfills.
Auto Node Script: OpenAPI/Swagger code generation (optional)
This package provides a Node script that generates type/service code from OpenAPI/Swagger JSON, separate from the runtime HTTP client. This script is optional.
General users of @byeolnaerim/typed-rx-http, /next, /rsocket do not need to run this script and do not need to install openapi-typescript.
Dependency Isolation
The openapi-typescript CLI is required for OpenAPI type generation. However, this package does not include openapi-typescript in the regular dependencies.
The @byeolnaerim/typed-rx-http library itself uses TypeScript 6.0.3 in devDependencies.typescript. The typed-rx-http, /next, and /rsocket entry points and library builds maintain this TypeScript 6.0.3 standard.
However, openapi-typescript may still require a specific TypeScript 5.x version, so the OpenAPI auto node script runs openapi-typescript and [email protected] in a separate npx temporary execution environment. This temporary execution environment does not change the library's devDependencies.typescript 6.0.3 and does not use the typescript or openapi-typescript versions installed in the user's project.
The default is to generate and execute the command below only at the time of auto script execution.
Therefore, the usage itself does not change. You can call the auto node script as before, and only a separate TypeScript 5.9.3 environment is used during the OpenAPI type generation phase. Users who do not use the auto script are not tied to openapi-typescript or TypeScript 5.9.3 at all.
If needed, you can directly fix the command with openApiTypescriptCommand.
Alternatively, you can change only the package version that configures the default command.
Generated Files
The default configuration generates the files below.
apiUnionArrays.ts generates constant arrays for OpenAPI schema enums as well as query, path, header, and cookie parameter enums. It also processes the items.enum of array query parameters.
EventStream Monitoring
Single HTTP Request
Generated from Local Files
Existing Project Integration Example: WebFlux + Swagger Auto Generation
From here on, it is an integration example of a project using both backend Swagger and auto-generated services. The core usage and optional features above can be used solely with typed-rx-http, and the flow below is additionally applied in projects that use Swagger-based service auto generation.
1. Write a REST endpoint in the backend.
Write the backend code as usual. In this example, it receives a name as a path variable and a message as a query parameter. Monoand responds.
TypedRxHttpExampleRouter.java
java2. Generate front services from Swagger.
Receive the backend's swagger.jsonto generate type and service files. This can be called once when running the development server or connected via a watch script.
generateSwagger.cjs
js3. Send requests using the generated functions.
You can try changing Front codeand Backend codebelow. ResultClicking will open the execution screen on the right. Change the values and press the request button.