Bắt đầu nhanh
HTTP client kiểu an toàn với RxJS cho TypeScript + (tùy chọn) Next.js/RSocket adapter.
Đặc điểm chính
- Tiêm loại Paths kiểu OpenAPI (theo quy ước là paths) từ các schema phát sinh Swagger/OpenAPI / AsyncAPI / hợp đồng tùy chỉnh để đảm bảo tính ổn định của loại route (yêu cầu).
- Tất cả API trả về RxJS Observable.
- core độc lập với framework (không phụ thuộc vào Next.js).
- Chức năng riêng cho Next.js được tách ra thành điểm vào @byeolnaerim/typed-rx-http/next → chỉ cần Next.js khi import /next.
- Chức năng riêng cho RSocket được tách ra thành điểm vào @byeolnaerim/typed-rx-http/rsocket → chỉ cần RSocket package khi import /rsocket.
Cài đặt
npm
Điểm vào.
Core (không phụ thuộc framework)
Next.js adapter (tùy chọn).
Trong các dự án không sử dụng Next.js, không import /next.
RSocket adapter (tùy chọn).
Chỉ cài đặt peer package trong các dự án sử dụng RSocket.
Trong các dự án không sử dụng RSocket, không import /rsocket.
Cách sử dụng Core.
1) Chuẩn bị loại Paths (thường là OpenAPI paths).
Paths trong createHttpClient<Paths>() biểu thị loại "spec yêu cầu (route)". Trong tài liệu, thường được gọi là paths, nhưng không nhất thiết phải là OpenAPI/Swagger hay tên là paths.
Tuy nhiên, core sử dụng ràng buộc OpenApiPathsLike bên trong, vì vậy Paths phải có hình thức tương tự như OpenAPI paths như dưới đây.
- Khóa cấp cao nhất: chuỗi đường dẫn URL (ví dụ: "/users/{id}").
- Khóa cấp dưới: phương thức HTTP (get/post/put/delete/patch …).
- Mỗi phương thức có các trường như parameters.query/path/header/cookie, requestBody, responses (hoặc never).
Core chủ yếu tham chiếu các trường trên để cấu thành loại ServiceArguments.
- url: keyof Paths.
- method: keyof Paths[url].
- queryString: parameters.query.
- pathVariable: parameters.path.
- body: requestBody.
Ví dụ: đầu ra openapi-typescript thường có quy cách như dưới đây (một số được rút gọn).
2) Tạo HeaderStore
HeaderStore là một kho nhớ đơn giản để quản lý header cơ bản trong CSR.
3) Tạo HTTP client
- headerStore là tùy chọn, nhưng nếu muốn sử dụng header cơ bản/xác thực phiên trong CSR, nên thêm vào.
- headersProvider được sử dụng khi cần tính toán header cho mỗi yêu cầu như SSR/multi-tenant.
4) Gọi API (an toàn kiểu)
Loại yêu cầu (url/phương thức/pathVariable/queryString/body) được xác định từ kiểu mà người dùng đã tiêm vào createHttpClient<Paths>() (theo quy ước là OpenAPI paths). Loại phản hồi được chọn bởi người gọi trong callApi<R>() với R là kiểu tổng quát (core không tự động suy diễn từ responses).
Bọc phản hồi (ResponseWrapper) — tùy chọn
Thư viện này không bắt buộc bọc phản hồi. Bạn có thể chọn hình thức phản hồi theo kiểu tổng quát cho từng API.
Phản hồi đã bọc
Phản hồi không bọc
Streaming (NDJSON)
Khi máy chủ trả về NDJSON (mỗi dòng là một JSON), sử dụng callApiStream. Nếu không có header Accept, mặc định sẽ được thiết lập là application/x-ndjson.
Bộ nhớ đệm CSR (bộ nhớ đệm phía khách)
Chức năng được cung cấp bởi createCsrCache<CacheName>():
callApiCsrCache(callApiFn, serviceArgs, cacheOptions)- removeCsrCache(cacheName) — hỗ trợ tên bộ nhớ đệm kiểu + chuỗi.
Plugin xác thực dựa trên phiên (tùy chọn)
createSessionAuth tách logic xác thực phiên ra khỏi core và cho phép thêm hoặc xóa tùy chọn.
Hoạt động:
- Giữ Authorization trong headerStore
- Đồng bộ token bằng ensureToken$() (/api/auth/token)
- Khi xảy ra 401, thử làm mới một lần (/api/auth/token/refresh) rồi thử lại yêu cầu gốc.
- Khi làm mới thất bại, đăng xuất (/api/auth/logout) và truyền lỗi.
- Thay đổi trạng thái đăng nhập được xử lý bên ngoài qua callback onLoginChange.
Nếu chỉ cần đồng bộ token mà không cần làm mới/thử lại:
Xử lý lỗi
Nếu không phải 2xx, sẽ ném ra HttpResponseError (bao gồm status, response, args, data).
Tương thích với legacy: nếu body lỗi có dạng { resultType: ... }, sẽ ném đối tượng đó.
Adapter Next.js (/next)
redirectToUnauthorizedOnServer401
redirectToUnauthorizedOnServer401 là triển khai mặc định (hàm tiện ích) thực hiện chuyển hướng khi xảy ra 401 trong môi trường SSR của Next.js (App Router).
Quy tắc hoạt động (cố định):
- Đối tượng chuyển hướng: /unauthorized
- queryString: redirect_uri=<trang hiện tại> + logout=true
- Trang hiện tại được đọc từ header x-page-url (nếu không có thì là /)
Nghĩa là, chỉ sử dụng quy tắc đường dẫn/query trên nếu chúng phù hợp với dự án. Nếu đường dẫn khác hoặc quy tắc truy vấn khác, bạn có thể tự triển khai onServer401 như dưới đây và tiêm vào.
callApiSsrCache
Trợ giúp bộ nhớ đệm SSR dựa trên next/cache(unstable_cache) của Next.
- GET + cacheTime > 0 → force-cache + revalidate
- Các trường hợp khác → no-store
- Tiêm Cookie / Authorization theo yêu cầu bằng headersProvider
- Khi xảy ra 401, nếu có onServer401 thì sẽ thực thi (thường là redirect())
Ví dụ tích hợp Next.js: Mã nguồn toàn bộ dự án rxjsHttpService/commonService
Dưới đây là rxjsHttpService.ts, là bộ điều hợp HTTP chung mà file commonServiceFile trong ví dụ generator sau chỉ đến. Đây không phải là file do thư viện tạo ra mà là do dự án tự quản lý, xuất core client + session auth + CSR cache + SSR cache helper tại một nơi. Dưới đây là mã nguồn đầy đủ.
rxjsHttpService.ts
tsTài liệu tham khảo API (core)
createHttpClient<Paths>(options)
Trả về:
callApi<R>(args): Observable<R>callApiStream<RChunk>(args): Observable<RChunk>uploadFile({ file, url, ifNoneMatch?, headers? }): Observable<Response>createSSEObservable<R>(args): Observable<R>
Tùy chọn:
baseUrl: stringheaderStore?: HeaderStoreheadersProvider?: () => Record<string, string> | Promise<Record<string, string>>- dropAuthWhenCacheControl?: boolean (mặc định: true)
onServer401?: () => void | Promise<void>
createHeaderStore(initial?)
get(), set(), merge(), remove(), clear()
createCsrCache<CacheName>()
callApiCsrCache(callApiFn, serviceArgs, cacheForService)- removeCsrCache(cacheName) (kiểu + chuỗi)
createSessionAuth(options)
withSessionAuth(), withEnsureToken()ensureToken$(), refreshToken$(), logout$()
Yêu cầu thời gian chạy
- Sử dụng fetch / Response API (rxjs/fetch)
- Streaming (NDJSON) cần ReadableStream + TextDecoder
- SSE cần EventSource
Hầu hết các trình duyệt hiện đại và thời gian chạy Next.js đều hỗ trợ sẵn. Thời gian chạy Node tùy chỉnh có thể cần polyfill.
Auto Node Script: Tạo mã OpenAPI/Swagger (tùy chọn)
Gói này cung cấp một script Node để tạo mã kiểu/dịch vụ từ JSON OpenAPI/Swagger, riêng biệt với HTTP client thời gian chạy. Script này là tính năng tùy chọn.
Người dùng thông thường của @byeolnaerim/typed-rx-http, /next, /rsocket không cần phải chạy script này và cũng không cần cài đặt openapi-typescript.
Cách ly phụ thuộc
Việc tạo kiểu OpenAPI yêu cầu openapi-typescript CLI. Tuy nhiên, gói này không đưa openapi-typescript vào dependencies thông thường.
Thư viện @byeolnaerim/typed-rx-http sử dụng TypeScript 6.0.3 trong devDependencies.typescript. Các entrypoint và build thư viện typed-rx-http, /next, /rsocket duy trì tiêu chuẩn TypeScript 6.0.3 này.
Tuy nhiên, openapi-typescript có thể yêu cầu một phiên bản TypeScript 5.x cụ thể, vì vậy chỉ script auto node OpenAPI được thực thi trong môi trường tạm thời npx riêng biệt với openapi-typescript và [email protected]. Môi trường tạm thời này không thay đổi devDependencies.typescript 6.0.3 của thư viện và cũng không sử dụng phiên bản typescript hoặc openapi-typescript đã cài đặt trong dự án của người dùng.
Giá trị mặc định là tạo và thực thi lệnh dưới đây chỉ tại thời điểm thực thi script tự động.
Do đó, cách sử dụng không thay đổi. Bạn chỉ cần gọi script auto node như trước, và chỉ trong giai đoạn tạo kiểu OpenAPI, môi trường TypeScript 5.9.3 cách ly sẽ được sử dụng. Người dùng không sử dụng script tự động sẽ không bị ràng buộc bởi openapi-typescript hoặc TypeScript 5.9.3.
Nếu cần, bạn có thể cố định lệnh trực tiếp bằng openApiTypescriptCommand.
Hoặc bạn chỉ có thể thay đổi phiên bản gói cấu hình lệnh cơ bản.
Tệp được tạo ra
Cấu hình mặc định sẽ tạo ra các tệp dưới đây.
apiUnionArrays.ts không chỉ tạo enum schema OpenAPI mà còn tạo enum cho các tham số query, path, header, cookie dưới dạng mảng hằng số. Nó cũng xử lý items.enum của tham số query dạng mảng.
Giám sát EventStream
Yêu cầu HTTP một lần
Tạo từ tệp cục bộ
Ví dụ tích hợp dự án hiện có: WebFlux + Tạo tự động Swagger
Từ đây là ví dụ tích hợp dự án sử dụng Swagger backend và dịch vụ tạo tự động. Cách sử dụng Core ở trên và các tính năng tùy chọn có thể được sử dụng chỉ với typed-rx-http, và quy trình dưới đây được áp dụng thêm trong dự án sử dụng dịch vụ tạo tự động dựa trên Swagger.
1. Viết endpoint REST cho backend.
Mã backend được viết như bình thường. Trong ví dụ này, nhận tên qua biến đường dẫn và tin nhắn qua tham số truy vấn. MonoĐể phản hồi.
TypedRxHttpExampleRouter.java
java2. Tạo dịch vụ frontend từ Swagger.
Nhận từ backend. Tuy nhiên, tôi không muốn chỉ sử dụng typed-rx-http cho WebFlux. Ngay cả khi backend không tạo Swagger trực tiếp, nếu có kiểu TypeScript phù hợp với đặc tả OpenAPITạo tệp kiểu và dịch vụ. Công việc này có thể được gọi một lần khi chạy máy chủ phát triển hoặc kết nối với script theo dõi.
generateSwagger.cjs
js3. Gửi yêu cầu bằng hàm đã tạo.
Có thể thay đổi ở dưới đây. Mã Backendvà Kết quảNhấn vào để mở màn hình thực thi bên phải. Thay đổi giá trị và nhấn nút yêu cầu. Phần hiển thị trong dự án thực tế.Mã Frontend