From e1c8d2414420006dd01efaef8b89e11def8fcb72 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Wed, 18 Sep 2024 14:28:27 +0800 Subject: [PATCH] feat(http/unstable): add support for multiple request methods on route (#6003) feat(http): add suppport multiple request methods on route --- http/unstable_route.ts | 18 ++++++++++++++---- http/unstable_route_test.ts | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/http/unstable_route.ts b/http/unstable_route.ts index 6b7992ba0022..cec7eeeb13eb 100644 --- a/http/unstable_route.ts +++ b/http/unstable_route.ts @@ -28,11 +28,11 @@ export interface Route { */ pattern: URLPattern; /** - * Request method. + * Request method. This can be a string or an array of strings. * * @default {"GET"} */ - method?: string; + method?: string | string[]; /** * Request handler. */ @@ -61,7 +61,12 @@ export interface Route { * { * pattern: new URLPattern({ pathname: "/static/*" }), * handler: (req: Request) => serveDir(req) - * } + * }, + * { + * pattern: new URLPattern({ pathname: "/api" }), + * method: ["GET", "HEAD"], + * handler: (req: Request) => new Response(req.method === 'HEAD' ? null : 'ok'), + * }, * ]; * * function defaultHandler(_req: Request) { @@ -91,7 +96,12 @@ export function route( return (request: Request, info?: Deno.ServeHandlerInfo) => { for (const route of routes) { const match = route.pattern.exec(request.url); - if (match && request.method === (route.method ?? "GET")) { + if ( + match && + (Array.isArray(route.method) + ? route.method.includes(request.method) + : request.method === (route.method ?? "GET")) + ) { return route.handler(request, info, match); } } diff --git a/http/unstable_route_test.ts b/http/unstable_route_test.ts index 9205c59a110d..aaf5913b7106 100644 --- a/http/unstable_route_test.ts +++ b/http/unstable_route_test.ts @@ -18,6 +18,12 @@ const routes: Route[] = [ method: "POST", handler: () => new Response("Done"), }, + { + pattern: new URLPattern({ pathname: "/resource" }), + method: ["GET", "HEAD"], + handler: (request: Request) => + new Response(request.method === "HEAD" ? null : "Ok"), + }, ]; function defaultHandler(request: Request) { @@ -54,4 +60,18 @@ Deno.test("route()", async (t) => { assertEquals(response?.status, 404); assertEquals(await response?.text(), "/not-found"); }); + + await t.step("handles multiple methods", async () => { + const getMethodRequest = new Request("http://example.com/resource"); + const getMethodResponse = await handler(getMethodRequest); + assertEquals(getMethodResponse?.status, 200); + assertEquals(await getMethodResponse?.text(), "Ok"); + + const headMethodRequest = new Request("http://example.com/resource", { + method: "HEAD", + }); + const headMethodResponse = await handler(headMethodRequest); + assertEquals(headMethodResponse?.status, 200); + assertEquals(await headMethodResponse?.text(), ""); + }); });