Skip to content

Cell - Http 组件 ​

Cell 的共享 HTTP 词汇表和用于调用其他服务的 HTTP 客户端,在前端和后端。

bash
npm install @celljs/http

常量 ​

HttpStatus(HttpStatus.NOT_FOUND 等)、HttpMethod、MediaType(MediaType.APPLICATION_JSON 等)和 HttpHeaders(HttpHeaders.AUTHORIZATION 等),由 @celljs/web、@celljs/mvc 和 @celljs/security 使用。

HTTP 客户端 ​

RestOperations 是运行时 fetch 的 HTTP 客户端(Node.js 18+、Bun、Deno、workerd、浏览器),没有第三方依赖。它的 API 是 axios 的熟悉子集:get、delete、head、options、post、put、patch 和 request 解析为 { status, statusText, headers, data, config }。

ts
import { Autowired, Component } from '@celljs/core';
import { RestOperations } from '@celljs/http';

@Component()
export class WeatherClient {
    @Autowired(RestOperations)
    protected readonly rest: RestOperations;

    async today(city: string) {
        const { data } = await this.rest.get('https://api.example.com/weather', { params: { city } });
        return data;
    }
}

请求配置(RequestConfig):

选项含义
url、method、baseURL如果 url 不是绝对的,baseURL 被加到前面
headers与默认请求头合并,不分大小写;undefined 将请求头去掉
params查询字符串;数组重复键(tag=a&tag=b),undefined / null 被去掉
data请求体:字符串、URLSearchParams、FormData、Blob、二进制数据或流按原样发送,其他作为 JSON 发送(除非设置 content-type: application/json)。GET 和 HEAD 不发送请求体
timeout毫秒;默认无限制
signal一个 AbortSignal 取消请求
responseTypejson(默认:JSON 被解析,其他保留为文本)、text、arraybuffer、blob 或 stream(响应体的 ReadableStream)
validateStatus哪些状态解析,默认 2xx;null 解析每个状态
withCredentials在浏览器中,也跨源发送 Cookie(credentials: 'include')

响应请求头为小写名称。失败的请求用 HttpClientError 拒绝,其 code 说明原因:CELL_HTTP_BAD_STATUS(状态未通过 validateStatus;error.response 持有响应)、CELL_HTTP_TIMEOUT、CELL_HTTP_ABORTED 或 CELL_HTTP_NETWORK(error.cause 是 fetch 的错误)。HttpClientError.is(error, 'CELL_HTTP_BAD_STATUS') 测试一种。

ts
try {
    await this.rest.post('/orders', order);
} catch (error) {
    if (HttpClientError.is(error, 'CELL_HTTP_BAD_STATUS') && error.response!.status === 409) {
        // ...
    }
    throw error;
}

http.client 在 cell.yml 中持有每个请求的默认值,带上述选项;前端也接收它。默认值发送 X-Requested-With: XMLHttpRequest,这告诉 @celljs/security 返回 401 而不是重定向到登录页面,和 withCredentials: true,仅浏览器使用。

拦截器如 axios 一样工作,除了两种都按添加的顺序运行:rest.interceptors.request.use(config => config) 在请求发送前改变配置,rest.interceptors.response.use(onAnswer, onError) 改变响应或失败;use 返回一个 eject 的 id。要将它们添加到共享实例,在组件中注入 RestOperations 并在 @PostConstruct 方法中调用 use,或绑定你自己的 RestOperationsFactory(rebind: true)。new DefaultRestOperations(config) 给一个单独的客户端。

在服务器上,URL 必须是绝对的(或相对于 baseURL)。在 HTTP 代理后面,Node.js 的 fetch 忽略 HTTP_PROXY / HTTPS_PROXY,除非设置了 NODE_USE_ENV_PROXY=1,仅最近的 Node.js 版本支持;Bun 和 Deno 自己读取它们。

对于 Cell 应用之间的调用,@celljs/rpc 给出类型化代理。