运行时框架

Modern.js 以 Hono.js 作为 BFF 和 Server 运行时框架,因此可以基于 Hono.js 生态扩展 BFF Server

获取请求上下文

在 BFF 函数中,有时需要获取请求上下文,来处理更多逻辑。此时,你可以通过 useHonoContext 来获取:

api/lambda/hello.ts
import { useHonoContext } from '@modern-js/server-runtime';

export const get = async () => {
  const c = useHonoContext();
  console.info(`access url: ${c.req.url}`);
  return 'Hello Modern.js';
};
Info

详细内容可以参考 useHonoContext

在 BFF 函数中获取 Cookie 时,需要通过 useHonoContext 获取请求上下文,然后使用 c.req.header('cookie') 获取 Cookie 字符串并手动解析:

api/lambda/cookies.ts
import { Api, Get } from '@modern-js/plugin-bff/server';
import { useHonoContext } from '@modern-js/server-runtime';

// 解析 Cookie 字符串的辅助函数
function parseCookies(
  cookieHeader: string | undefined,
): Record<string, string> {
  const cookies: Record<string, string> = {};
  if (!cookieHeader) return cookies;

  cookieHeader.split(';').forEach(cookie => {
    const [name, ...rest] = cookie.trim().split('=');
    if (name) {
      cookies[name] = rest.join('=');
    }
  });

  return cookies;
}

export const getCookies = Api(Get('/cookies'), async () => {
  const c = useHonoContext();
  const cookieHeader = c.req.header('cookie');
  const cookies = parseCookies(cookieHeader);
  const token = cookies.token;
  const sessionId = cookies.sessionId;
  return {
    hasToken: !!token,
    token: token || null,
    sessionId: sessionId || null,
  };
});
注意

c.req.cookie() 方法在当前版本中不存在,需要使用 c.req.header('cookie') 获取 Cookie 字符串,然后手动解析。

定义 BFF 函数

使用 Hono 作为运行时框架时,可以通过 Api 函数 定义接口:

api/lambda/user.ts
import { Api, Get, Query } from '@modern-js/plugin-bff/server';
import { z } from 'zod';

const QuerySchema = z.object({
  id: z.string(),
});

export const getUser = Api(
  Get('/user'),
  Query(QuerySchema),
  async ({ query }) => {
    return {
      id: query.id,
      name: 'Modern.js',
      email: 'modernjs@bytedance.com',
    };
  },
);
Info

更多关于 Api 函数和操作符的详细内容,可以参考 创建可扩展的 BFF 函数

使用中间件

Hono 支持丰富的中间件生态,可以在 BFF 函数中使用中间件:

api/lambda/user.ts
import { Api, Get, Middleware } from '@modern-js/plugin-bff/server';

export const getUser = Api(
  Get('/user'),
  Middleware(async (c, next) => {
    // 在中间件中可以访问 Hono 的 Context
    c.res.headers.set('X-Powered-By', 'Modern.js');
    await next();
  }),
  async () => {
    return {
      name: 'Modern.js',
      email: 'modernjs@bytedance.com',
    };
  },
);
Info

更多关于中间件的详细内容,可以参考 创建可扩展的 BFF 函数

更多 Hono 文档

更多关于 Hono 的详细信息可查看 Hono 官方文档