我如何将多个中间地点连接到一条路线?

发布于 2025-02-12 23:30:23 字数 564 浏览 0 评论 0 原文

我想在deno Oak中链接2个中间Wares的功能:

const addProductPanier = async(req:any,res:any) => {...}
const showPanier = async(ctx:any) => {...}

router.post('/OBV/panier',addProductPanier).post('/OBV/panier',showPanier);

我尝试了很多方式,并在橡木文档中搜索了一个解决方案,但是.post中的字符串路径不可能相同,例如:

router.post('/OBV/panier',addProductPanier).post('/OBV/panier/one',showPanier);

我还试图将两个中间件合并为几天前,但是由于某些未知原因,它不再起作用。如您所见,我将它们分开了,以使AddProductPanier将数据发送到我的数据库和ShowPanier,以获取此数据并使用CTX.Render()在我的HTML页面上显示。

那么,您知道如何将中间件链带到一条路线吗?

I want to chain 2 middlewares functions in deno oak like this:

const addProductPanier = async(req:any,res:any) => {...}
const showPanier = async(ctx:any) => {...}

router.post('/OBV/panier',addProductPanier).post('/OBV/panier',showPanier);

I've tried in so many ways and searched for a solution in the oak documentation, but string paths in .post can not be the same, I need to have for example:

router.post('/OBV/panier',addProductPanier).post('/OBV/panier/one',showPanier);

I also tried to merge the 2 middlewares in one, it worked few days ago, but for some unknown reason it don't work anymore replying me that response.render() is not a function. As you can see I separated both of them to have addProductPanier sending data to my database and showPanier to fetch this data and display it on my html page using ctx.render().

So do you know how to chain multiples middlewares to one route ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南风起 2025-02-19 23:30:23

答案摘要

您可以使用Oak的中间件构图功能( composemiddlware ),或者您可以简单地提供每个中间件功能是路由器方法的位置参数。


指导性解释

是因为没有一个最小,可复制的示例在您的问题中,我将以下面的形式提供一个一个简单的问候应用程序,并使用它来解决您的问题,详细介绍了两种在同一路线上撰写中间件的方法。

有用的参考文档:


https://github.com/pillarjs/path-to-to-regexp/blob/1cbb9f3d9c3bff97298ec45b1bbb2b2b2b2b2b2b2b2b0beb879babbf/readme.md想要创建一个应该应该的网络服务器respond to GET requests at /greet, and also allow an

  • 记录 name 路由参数(在服务器控制台中)的值,然后
  • 使用明文问候消息进行响应。

上面描述的中间件功能可能看起来像这样:

./ middleware.ts

import { type RouterMiddleware } from "https://deno.land/x/[email protected]/mod.ts";

export const logName: RouterMiddleware<"/greet/:name?"> = (ctx, next) => {
  const { name } = ctx.params;
  console.log({ name });
  return next();
};

export const sendGreeting: RouterMiddleware<"/greet/:name?"> = (ctx, next) => {
  const name = ctx.params.name ?? "World";
  const msg = `Hello ${name}!`;
  ctx.response.body = msg;
  ctx.response.type = "text/plain";
  return next();
};

现在,让我们创建一个将定义路由的模块。目前,我们将仅初始化路由器并导出它,以便在继续设置时没有类型错误,但是我们会回到这里探索两种构图方法:

./ doutes.ts.ts

import { Router } from "https://deno.land/x/[email protected]/mod.ts";

export const router = new Router();

我们还创建一个模块,在其中初始化和导出应用程序(以及服务器启动时将启动消息打印到控制台的函数):

./ app.ts

import { Application } from "https://deno.land/x/[email protected]/mod.ts";
import { router } from "./routes.ts";

// This is not necessary, but is potentially helpful to see in the console
function printStartupMessage({ hostname, port, secure }: {
  hostname: string;
  port: number;
  secure?: boolean;
}): void {
  const address = new URL(
    `http${secure ? "s" : ""}://${
      hostname === "0.0.0.0" ? "localhost" : hostname
    }:${port}/`,
  ).href;
  console.log(`Listening at ${address}`);
  console.log("Use ctrl+c to stop");
}

export const app = new Application();
app.addEventListener("listen", printStartupMessage);

app.use(router.routes());
app.use(router.allowedMethods());

对于最后一部分设置,我们将创建启动服务器的主要应用程序入门点模块:

./ main.ts

import { app } from "./app.ts";

await app.listen({ port: 8000 });

现在,让我们返回到 ./ doutes.ts 以探索组合方法:

编写中间件函数

可以构成中间件的第一种方式是使用橡木导出的功能为此目的: composemiddlware < /code>

我们的路线的修改版本看起来像这样:

./ doutes.ts

import {
  composeMiddleware,
  Router,
} from "https://deno.land/x/[email protected]/mod.ts";

import { logName, sendGreeting } from "./middleware.ts";

export const router = new Router();
const greetMiddleware = composeMiddleware([logName, sendGreeting]);
router.get("/greet/:name?", greetMiddleware);

或者,更简单地说,每个中间件功能都可以作为位置参数提供给路由器方法的顺序:

./ douts./toures.ts.ts

import { Router } from "https://deno.land/x/[email protected]/mod.ts";

import { logName, sendGreeting } from "./middleware.ts";

export const router = new Router();
router.get("/greet/:name?", logName, sendGreeting);

两者都其中产生相同的结果。

测试应用程序

在终端控制台中使用适当的 permissions 用于网络访问:

% deno run --allow-net=0.0.0.0:8000 main.ts
Listening at http://localhost:8000/
Use ctrl+c to stop

如果您导航到 http:// localhost:8000/ettry 在浏览器中,您应该在视口上看到文本 Hello World! > {名称:未定义}

同样,如果您导航到 hello visitor!在视口上,然后返回终端控制台,带有 {name:“ visitor”的线路}

Answer summary

You can use Oak's middleware composition function (composeMiddlware) or you can simply provide each middleware function as a positional argument to the router method.


Guided explanation

Because there's not a minimal, reproducible example in your question, I'll provide one below in the form of a simple greeting app and use it to address your question, detailing two ways to compose middleware on the same route.

Useful reference documentation:

Example app description

Let's say we want to create a web server that should respond to GET requests at /greet, and also allow an optional route parameter name for the name to greet, so the route will look like this: /greet/:name?. When that route is matched, the server should use individual middleware to:

  • log the value of the name route parameter (in the server console), and then
  • respond with a plaintext greeting message.

The middleware functions described above might look like this:

./middleware.ts:

import { type RouterMiddleware } from "https://deno.land/x/[email protected]/mod.ts";

export const logName: RouterMiddleware<"/greet/:name?"> = (ctx, next) => {
  const { name } = ctx.params;
  console.log({ name });
  return next();
};

export const sendGreeting: RouterMiddleware<"/greet/:name?"> = (ctx, next) => {
  const name = ctx.params.name ?? "World";
  const msg = `Hello ${name}!`;
  ctx.response.body = msg;
  ctx.response.type = "text/plain";
  return next();
};

Now let's create a module where the routes will be defined. For now, we'll just initialize a router and export it so that there aren't type errors as we continue setup, but we'll come back here to explore the two composition methods:

./routes.ts:

import { Router } from "https://deno.land/x/[email protected]/mod.ts";

export const router = new Router();

Let's also create a module where we initialize and export the app (and a function for printing a startup message to the console when the server starts):

./app.ts:

import { Application } from "https://deno.land/x/[email protected]/mod.ts";
import { router } from "./routes.ts";

// This is not necessary, but is potentially helpful to see in the console
function printStartupMessage({ hostname, port, secure }: {
  hostname: string;
  port: number;
  secure?: boolean;
}): void {
  const address = new URL(
    `http${secure ? "s" : ""}://${
      hostname === "0.0.0.0" ? "localhost" : hostname
    }:${port}/`,
  ).href;
  console.log(`Listening at ${address}`);
  console.log("Use ctrl+c to stop");
}

export const app = new Application();
app.addEventListener("listen", printStartupMessage);

app.use(router.routes());
app.use(router.allowedMethods());

For the last part of the setup, we'll create the main app entrypoint module where the server is started:

./main.ts:

import { app } from "./app.ts";

await app.listen({ port: 8000 });

Now, let's return to ./routes.ts to explore the composition methods:

Composing middleware functions

The first way that middleware can be composed is to use a function exported by Oak for exactly this purpose: composeMiddlware

The modified version of our routes module would look like this:

./routes.ts:

import {
  composeMiddleware,
  Router,
} from "https://deno.land/x/[email protected]/mod.ts";

import { logName, sendGreeting } from "./middleware.ts";

export const router = new Router();
const greetMiddleware = composeMiddleware([logName, sendGreeting]);
router.get("/greet/:name?", greetMiddleware);

Or, more simply, each middleware function can just be supplied as a positional argument to the router method in order:

./routes.ts:

import { Router } from "https://deno.land/x/[email protected]/mod.ts";

import { logName, sendGreeting } from "./middleware.ts";

export const router = new Router();
router.get("/greet/:name?", logName, sendGreeting);

Both of these produce the same result.

Testing the app

Start the app in the terminal console with the appropriate permissions for network access:

% deno run --allow-net=0.0.0.0:8000 main.ts
Listening at http://localhost:8000/
Use ctrl+c to stop

If you navigate to http://localhost:8000/greet in your browser, you should see the text Hello World! in the viewport, and back in the terminal console a line with { name: undefined }.

Again, if you navigate to http://localhost:8000/greet/visitor, you should see the text Hello visitor! in the viewport, and back in the terminal console a line with { name: "visitor" }.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文