Runtime Framework

Modern.js uses Hono.js as the BFF and Server runtime framework, so you can extend BFF Server based on the Hono.js ecosystem.

Getting Request Context

Sometimes in BFF functions, it's necessary to obtain the request context to handle more logic. In such cases, you can use useHonoContext to get it:

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

For more details, refer to useHonoContext.

Getting Cookies

When getting cookies in BFF functions, you need to get the request context through useHonoContext, then use c.req.header('cookie') to get the Cookie string and parse it manually:

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

// Helper function to parse Cookie string
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,
  };
});
Note

The c.req.cookie() method does not exist in the current version. You need to use c.req.header('cookie') to get the Cookie string and parse it manually.

Defining BFF Functions

When using Hono as the runtime framework, you can define interfaces through Api functions:

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

For more details about Api functions and operators, refer to Creating Extensible BFF Functions.

Using Middleware

Hono supports a rich middleware ecosystem, and you can use middleware in BFF functions:

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

export const getUser = Api(
  Get('/user'),
  Middleware(async (c, next) => {
    // You can access Hono's Context in middleware
    c.res.headers.set('X-Powered-By', 'Modern.js');
    await next();
  }),
  async () => {
    return {
      name: 'Modern.js',
      email: 'modernjs@bytedance.com',
    };
  },
);
Info

For more details about middleware, refer to Creating Extensible BFF Functions.

More Hono Documentation

For more detailed information about Hono, please refer to the Hono official documentation.