For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt, and this page is available as Markdown at /zh/guides/advanced-features/bff/sdk.md.
  • 简体中文
  • 扩展一体化调用 SDK

    BFF 函数的一体化调用在 CSR 和 SSR 是同构的。Modern.js 封装的请求 SDK,在浏览器端依赖了 Fetch API,在服务端依赖了 node-fetch。但在实际业务场景下,有时需要对请求或响应做一些额外的处理,例如:

    • 在请求头中写入鉴权信息
    • 对响应的数据或错误进行统一的处理
    • 特定平台无法使用浏览器的原生 fetch 函数,需要使用其他方式发送请求

    针对上述的场景,Modern.js 提供了 configure 函数,开放了一系列扩展能力,可以用它配置 ssr 透传请求头,添加拦截器,自定义请求 SDK。

    注意

    configure 函数的调用需要在所有 BFF 请求发送前调用,以确保覆盖默认的请求配置。

    routes/page.tsx
    import { configure } from '@modern-js/plugin-bff/client';
    
    configure({
      // ...
    });
    
    const Index = () => <div>Hello world</div>;
    export default Index;

    配置 SSR 透传请求头

    在同时使用 Modern.js SSR 和 BFF 的场景下,常常需要将 SSR 页面请求上的一些请求头信息,透传给 BFF 服务。

    例如项目有页面地址是 https://website.com,该页面是 SSR 的,在组件中会调用 API 接口 https://website.com/api/info,该接口需要用户的 cookie 信息做鉴权。页面在请求该 API 接口时,需要将 SSR 页面请求的 cookie 传给 BFF。

    目前以下请求头在 Modernjs 中是自动透传的:

    ['cookie', 'user-agent', 'x-tt-logid', 'x-tt-stress'];

    可以通过 configure 配置请求头。例如以下例子,Modern.js 会自动将 SSR 页面请求的 x-uid 信息透传给 BFF 服务:

    configure({
      allowedHeaders: ['x-uid'],
    });

    添加拦截器

    在有些业务场景下需要对请求和响应进行统一的处理,这种场景下可以通过配置拦截器满足需求:

    configure({
      // 这里的 request 是一体化默认的请求工具,interceptor 函数需返回一个新的 request。
      // 新 request 的出参必须是 parse body 之后的结果
      interceptor(request) {
        return async (url, params) => {
          const res = await request(url, params);
          // 拦截器可能返回 Response 对象,需要手动解析 JSON
          if (res instanceof Response) {
            return res.json();
          }
          // 如果已经是解析后的数据,直接返回
          return res;
        };
      },
    });

    自定义请求 SDK

    如果仅仅通过配置拦截器无法满足需求,希望自定义请求函数,也可以通过 configure 进行配置:

    import nodeFetch from 'node-fetch';
    
    const customFetch = (input: RequestInfo | URL, init: RequestInit) => {
      const curFetch =
        process.env.MODERN_TARGET !== 'node'
          ? fetch
          : (nodeFetch as unknown as typeof fetch);
      return curFetch(input, init).then(async res => {
        const data = await res.json();
        data.hello = 'hello custom sdk';
        return data;
      });
    };
    
    configure({
      request: customFetch,
    });

    配置自定义请求函数有以下约定:

    • 函数的入参与浏览器中的 Fetch 或 node-fetch 对齐,所有 BFF 函数的一体化调用会通过该函数发送请求。
    • 函数出参必须是接口实际返回的数据,不能是 Promise,否则会导致 BFF 函数无法正常返回数据。
    • 如果是 SSR 项目,函数必须要同时支持浏览器端和服务器端发送请求。

    下面是使用 axios 定制自定义请求函数的示例:

    App.tsx
    import { configure } from '@modern-js/plugin-bff/client';
    import type { Method, AxiosRequestHeaders as Headers } from 'axios';
    
    configure({
      async request(...config: Parameters<typeof fetch>) {
        const [url, params] = config;
        const res = await axios({
          url: url as string, // 这里因为 fetch 和 axios 类型有些不兼容,需要使用 as
          method: params?.method as Method,
          data: params?.body,
          headers: params?.headers as Headers,
        });
        return res.data;
      },
    });