Extend BFF Server

In some applications, developers may want to handle all BFF functions uniformly, such as authentication, logging, data processing, etc.

Modern.js allows users to freely extend the BFF Server through the Custom Server method.

Using Middleware

Developers can use middleware by configuring middlewares in server/modern.server.ts. The following describes how to write a BFF middleware manually to add permission verification:

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,
    },
  ]
});

Then add a regular BFF function api/lambda/hello.ts:

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

Next, in the frontend src/routes/page.tsx, add the interface access code and directly use the integrated method to call:

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>;
};

Now run the dev command to start the project, and access http://localhost:8080/ to find that the request for /api/hello has been intercepted:

Network

Finally, modify the frontend code src/routes/page.tsx, and call the login interface before accessing /api/hello:

NOTE

This part does not implement a real login interface; the code is just for demonstration.

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>;
};

Refresh the page, and you can see that the access to /api/hello is successful:

Network

The above code simulates defining middleware in server/Modern.server.ts and implements a simple login function. Similarly, other functionalities can be implemented in this configuration file to extend the BFF Server.

ON THIS PAGE