Next.js serverless CRUD

1 serverless function, multiple requests
import type {NextApiRequest, NextApiResponse} from 'next';

type Handlers = {
  GET?: (req: NextApiRequest, res: NextApiResponse) => Promise<unknown>;
  POST?: (req: NextApiRequest, res: NextApiResponse) => Promise<unknown>;
  PATCH?: (req: NextApiRequest, res: NextApiResponse) => Promise<unknown>;
  DELETE?: (req: NextApiRequest, res: NextApiResponse) => Promise<unknown>;
};

export function createHandlers(handlers: Handlers) {
  return async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {
    if (req.method && req.method in handlers) {
      const handler = handlers[req.method];

      try {
        await handler(req, res);
      } catch (err) {
        res.status(err.status || 500).end(err.message);
      }
    } else {
      res.setHeader('Allow', Object.keys(handlers));
      res.status(405).end(`Method ${req.method} Not Allowed`);
    }
  };
}

Usage

import type {NextApiRequest, NextApiResponse} from 'next';

import {deleteTeammate} from '@/api/services/teammate-delete';
import {getTeammate} from '@/api/services/teammate-get';
import {patchTeammate} from '@/api/services/teammate-patch';
import {createHandlers} from '@/utils/rest';

export default function teammate(
  req: NextApiRequest,
  res: NextApiResponse
): Promise<unknown> {
  const handler = createHandlers(handlers);
  return handler(req, res);
}

const handlers = {
  GET: getTeammate,
  PATCH: patchTeammate,
  DELETE: deleteTeammate,
};