keroxp/servest

Type-aware middleware system

Closed this issue · 1 comments

Servest have built-in middleware system for App and Router.

app.use(req => {
  // filter every request on app
})
app.handle(req =>{
  // filter before response handler
}, req => {
  req.respond({ ... })
})

This system is inspired by ExpressJS. It's nice and clear way to filter or map request.
However, there is lack of type awareness. For example, Express's body parser middleware extends request, adding .body property. It's thanks to JavaScript's dynamic language feature.

This is easy way to add common procedures to your application, but this is not perfect to TypeScript. On response handler, there is less information about how request was extended by middleware.

Ideally, code like below should work:

app.use(req => {
  req.something = "great" // error!
});
app.get(req => {
  const great = req.something; // error!
})

As you know, it can't be compiled because req: ServerRequest doesn't have something property.

Proposal1

const greatExtender = req => {
  return {something: "great"} 
}
const niceExtender = req => {
  return {deno: "nice"}
}
const app = createAppBuilder()
  .use(greatExtender)
  .use(niceExtender);
app.get((req, {somehing, deno} )=> {

})

Proposal2

const Great = {
  repo: new WeakMap<ServerRequest>(),
  handle(req) {
     this.repo.set(req, "great")
  },
  get(req)  {
    return this.repo.get(req);
  }
}
const app = createApp();
app.use(Great.handle);
app.get(req => {
  const great = Great.get(req);
});

Done by #101