扩展 BFF Server

部分应用中,开发者可能希望对所有 BFF 函数做统一的处理,例如鉴权、日志、数据处理等。

Modern.js 支持用户通过 Custom Server 的方式来自由扩展 BFF Server。

使用中间件

开发者可以在 server/modern.server.ts 中通过 配置 middlewares 来使用中间件。下面介绍如何手写一个 BFF 中间件,添加权限校验:

server/modern.server.ts
import {
  type MiddlewareHandler,
  defineServerConfig,
} from '@modern-js/server-runtime';

const requireAuthForApi: MiddlewareHandler = async (c, next) => {
  if (c.req.path.startsWith('/api') && c.req.path !== '/api/login') {
    const sid = c.req.cookie('sid');
    if (!sid) {
      return c.json({ code: -1, message: 'need login' }, 400);
    }
  }
  await next();
};

export default defineServerConfig({
  middlewares: [
    {
      name: 'require-auth-for-api',
      handler: requireAuthForApi,
    },
  ]
});

然后添加一个普通的 BFF 函数 api/lambda/hello.ts

api/lambda/hello.ts
export default async () => {
  return 'Hello Modern.js';
};

接下来,在前端 src/routes/page.tsx 添加接口的访问代码,直接使用一体化的方式调用:

src/routes/page.tsx
import { useState, useEffect } from 'react';
import { get as hello } from '@api/hello';

export default () => {
  const [text, setText] = useState('');

  useEffect(() => {
    async function fetchMyApi() {
      const { message } = await hello();
      setText(message);
    }

    fetchMyApi();
  }, []);

  return <p>{text}</p>;
};

现在运行 dev 命令启动项目,访问 http://localhost:8080/ 会发现 /api/hello 的请求被拦截了:

Network

最后修改前端代码 src/routes/page.tsx,在访问 /api/hello 前先调用登录接口:

NOTE

此处没有真实实现登录接口,代码仅作为演示。

import { useState, useEffect } from 'react';
import { get as hello } from '@api/hello';
import { post as login } from '@api/login';

export default () => {
  const [text, setText] = useState('');

  useEffect(() => {
    async function fetchAfterLogin() {
      const { code } = await login();
      if (code === 0) {
        const { message } = await hello();
        setText(message);
      }
    }
    fetchAfterLogin();
  }, []);

  return <p>{text}</p>;
};

刷新页面,可以看到 /api/hello 访问成功:

Network

以上代码模拟了在 server/Modern.server.ts 中定义中间件的方式,实现了简易的登录功能。同样,可以在这个配置文件中实现其他功能来扩展 BFF Server。

ON THIS PAGE