新的标准类,例如urlpattern,响应,请求和URL,使我思考了本机路由/路由器类的外观。我已经尝试了各种服务器框架,例如Express,Oak和Fresh,并且一直在考虑从Wintercg或Mozilla的角度来看服务器的外观。这是仅在方法和URL上匹配的简单路线和路由类。
type Handler = (req: Request) => Promise<Response> | Response
export class Route {
urlPattern: URLPattern
constructor (
public method: string,
public pathname: string,
public handler: Handler
) {
this.urlPattern = new URLPattern({ pathname })
}
static get (pathname: string, handler: Handler) {
return new Route("GET", pathname, handler)
}
}
export class Routes {
routes: Route[]
constructor (...routes: Route[]) {
this.routes = routes
}
async match (req: Request): Promise<Response> {
const matches = this.routes.filter(route => {
return route.urlPattern.test(req.url) && route.method === req.method
})
if (matches.length > 1) {
return new Response('internal error, more then one route with the same pathname')
} else if (matches.length === 0) {
return new Response('internal error, not found')
} else {
const response = await matches[0].handler(req)
return response
}
}
}
这将使您可以做类似的事情:
import { serve } from "https://deno.land/std@0.173.0/http/server.ts";
const routes = new Routes(
Route.get('/elephant', () => Response.json('elephant')),
Route.get('/monkey', () => Response.json('monkey')),
Route.get('/racoon', () => Response.json('racoon')),
Route.get('/bunny', () => Response.json('bunny')),
)
// To listen on port 4242.
serve((request) => {
return routes.match(request)
}, { port: 4242 });
这有一个问题:如果您想在请求的其他部分匹配该怎么办?这可能会很快变得复杂。除了标准URL和方法外,还有标题,查询,主体,应该在提取的,解析的身体上匹配匹配项吗?如果是这样,应该在请求对象中验证身体吗?要获得身体,这是一个承诺的背后。要匹配身体,您需要了解车身的类型(例如形式,XML,JSON),然后使用像ZOD这样的工具来验证它。它没有在这里概述,但是我创建了WrapedRequest
的想法,该想法会在WrapedRequest
实例中缓存身体,以便将诺言解决一次并传递给每个Router
以进行匹配。
一个更复杂的Route
类可以将所有匹配条件列为一系列选项和要求。
new RouteMatcher(
method.get,
oneOf(urlPattern('/elephant'), urlPattern('/elephant/:name')),
oneOf([queryParam('name'), urlPattern('/elephant/:name'), header('x-name')]),
)
我喜欢一个可以符合各种标准的简单路线/路由器的概念,我想知道其他人是否也在考虑这个想法。它无疑简化了仅与方法和URL路径匹配的事物。
我一直在思考可以与各种标准匹配的本地路线/路由器类的潜力。我一直在尝试不同的服务器框架,并从各个角度考虑服务器的设计。我建议可以在方法上匹配的简单路线和路由类是一个不错的起点,但是在其他条件下也有扩展的余地。我很想知道其他人是否分享了这一观点,并想对此主题进行讨论。