首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >覆盖下一个连接中间件中的请求类型

覆盖下一个连接中间件中的请求类型
EN

Stack Overflow用户
提问于 2022-09-15 11:03:33
回答 1查看 186关注 0票数 3

我正在使用next-connect next.js & typescript,我希望创建一个中间件,它添加一些字段来请求对象并推断新的请求类型。守则如下:

代码语言:javascript
复制
// multipart middleware
export type NextApiRequestMultipart = NextApiRequest & {
  files: Files;
  fields: Fields;
};
export function multipart(
  config?: Options
) {
  return async (
    req: NextApiRequest,
    res: NextApiResponse,
    next: NextHandler
  ) => {
    const { files, fields } = await parseForm(req, config);
    (req as NextApiRequestMultipart).files = files;
    (req as NextApiRequestMultipart).fields = fields;
    return next();
  };
}
代码语言:javascript
复制
export router().post(
  multipart({ multiples: false }),
  async (req, res) => {
    // I want to access properties without statically typing the request
    const { files, fields } = req;
  }
);

StackBlitz回购:见代码

EN

回答 1

Stack Overflow用户

发布于 2022-09-21 15:41:37

我设法实现为示例解决方案。这里是代码演示: stakc-blitz改进

示例描述的方法

我还没有测试过它,但我想展示它的方法。

我们需要一个控制器路由器建设者来做到这一点。该控制器构建器将需要“堆栈”所有中间件的请求对象中添加的类型。

样本

代码语言:javascript
复制
class ControllerBuilder<RequestType> {
   addMiddleWare(middleWare): ControllerBuilder<RequestType & middlewareTypeAdditions> {
   // implementation
 }
}

为了提取中间件类型-我需要让它声明一些软件。这就是为什么我引入了一个装饰中间件。

下面是装饰中间件的抽象:

代码语言:javascript
复制
abstract class DecoratedMiddleware<MiddlewareReqTypeAdditions> {
  ///
}

现在,在ControllerBuilder中,我们可以“提取”每个中间件的类型,并通过返回带有unin类型的新实例来“堆栈”它们:到目前为止,ReqeustType与新中间件将添加的内容结合在一起。

代码语言:javascript
复制
class ControllerBuilder<RequestType> {
   addMiddleWare(middleWare: DecoratedMiddleware<MiddlewareReqTypeAdditions>): ControllerBuilder<RequestType & MiddlewareReqTypeAdditions> {
   // implementation
   return new ControllerBuilder<>
 }
}

下面是一个中间件实现示例。我们只需要声明请求的附加属性,构建器将设置这些属性。process函数必须返回这些道具的承诺,确保所有这些都是根据中间件类型契约设置的。

代码语言:javascript
复制
type AuthRequestAddtion = {
  role: string;
  id: number | string;
  hotelId: number;
};

class AuthMiddleware extends DecoratedMiddleware<AuthRequestAddtion> {
  protected process: MuddlewareFunc<AuthRequestAddtion> = (req, res) => {
    return Promise.resolve({
      id: 1,
      role: 'GUEST',
      hotelId: 3,
    });
  };
}

最后是一个示例用法:

代码语言:javascript
复制
ControllerBuilder.get(router(), '/with-weather')
  .addMiddleware(authMiddleware)
  .addMiddleware(multipartMiddleware)
  .addMiddleware(weatherMiddleware)
  .handle(async (req, res) => {
    //now we have types for all the middlewares
    const hotelId = req.hotelId;
    const files = req.files;
    const temp = req.weather.temperature;
    res.status(200).json({ hotelId, files, temp });
  });

建筑商不是100%完成,我的意图是展示的方法。我可能会修改它,以便可以使用一组中间件。

请注意,在调用句柄之前,它以Builder的形式运行。因此,它是不可变的,并且可以被链锁和结果重用。

就像这样:

代码语言:javascript
复制
const authUserWithWeather = ControllerBuilder.create()
  .addMiddleware(authMiddleware)
  .addMiddleware(weatherMiddleware);


authUserWithWeather.get("/").handle(() => {});
authUserWithWeather
  .addMiddleware(multipartMiddleware)
  .get("/something")
  .handle(() => {})

再次链接到演示:stakc-blitz改进

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73729967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档