-
Notifications
You must be signed in to change notification settings - Fork 639
/
Copy pathroute.ts
100 lines (97 loc) · 2.64 KB
/
route.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
/**
* Request handler for {@linkcode Route}.
*
* @experimental **UNSTABLE**: New API, yet to be vetted.
*
* Extends {@linkcode Deno.ServeHandlerInfo} by adding adding a `params` argument.
*
* @param request Request
* @param info Request info
* @param params URL pattern result
*/
export type Handler = (
request: Request,
info?: Deno.ServeHandlerInfo,
params?: URLPatternResult | null,
) => Response | Promise<Response>;
/**
* Route configuration for {@linkcode route}.
*
* @experimental **UNSTABLE**: New API, yet to be vetted.
*/
export interface Route {
/**
* Request URL pattern.
*/
pattern: URLPattern;
/**
* Request method.
*
* @default {"GET"}
*/
method?: string;
/**
* Request handler.
*/
handler: Handler;
}
/**
* Routes requests to different handlers based on the request path and method.
*
* @experimental **UNSTABLE**: New API, yet to be vetted.
*
* @example Usage
* ```ts no-eval
* import { route, type Route } from "@std/http/route";
* import { serveDir } from "@std/http/file-server";
*
* const routes: Route[] = [
* {
* pattern: new URLPattern({ pathname: "/about" }),
* handler: () => new Response("About page"),
* },
* {
* pattern: new URLPattern({ pathname: "/users/:id" }),
* handler: (_req, _info, params) => new Response(params?.pathname.groups.id),
* },
* {
* pattern: new URLPattern({ pathname: "/static/*" }),
* handler: (req: Request) => serveDir(req)
* }
* ];
*
* function defaultHandler(_req: Request) {
* return new Response("Not found", { status: 404 });
* }
*
* Deno.serve(route(routes, defaultHandler));
* ```
*
* @param routes Route configurations
* @param defaultHandler Default request handler that's returned when no route
* matches the given request. Serving HTTP 404 Not Found or 405 Method Not
* Allowed response can be done in this function.
* @returns Request handler
*/
export function route(
routes: Route[],
defaultHandler: (
request: Request,
info?: Deno.ServeHandlerInfo,
) => Response | Promise<Response>,
): (
request: Request,
info?: Deno.ServeHandlerInfo,
) => Response | Promise<Response> {
// TODO(iuioiua): Use `URLPatternList` once available (https://github.com/whatwg/urlpattern/pull/166)
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")) {
return route.handler(request, info, match);
}
}
return defaultHandler(request, info);
};
}