lightbug_http icon indicating copy to clipboard operation
lightbug_http copied to clipboard

Propose Middleware Solution

Open drujensen opened this issue 9 months ago • 6 comments

This is a proposal and code sample for adding middleware to the light bug project.

Proposal

The chain of responsibility design pattern is used to chain together pieces of middleware that will each handle some aspect of the Request/Response. This allows someone to choose which middleware they want and allow them to remove or replace anything they need. It also supports adding their own custom middleware.

The Context is used to wrap the HTTPRequest and provided a dictionary of parameters. It should support AnyType of value so you can add middleware to handle authentication or parsing cookies, query strings, paths and provide that to other middleware or handlers.

In the middleware package, I've provided 8 example middleware handlers: Error, Compression, Logger, CORS, Basic Authentication, Static, Router, and NotFound.

The Router middleware is special in that it allows for different leaf nodes to be registered for a particular Request Pattern. This can become complex with routing based on any method, path, header combination. Also, it will need to support variable paths. The one provided is very rudimentary. We will want one that uses a high speed tree structure for the best performance.

The HTTPHandler trait is used by the Router for the leaf nodes. We can add a LambdaHandler and support Lambdas when they become available.

The NotFound is the last item in the chain. If no other middleware handles the Request, it will return a 404, not found response. By not hard coding this in the Router, we can support multiple routers in the chain which provides flexibility for mounting other projects or have Authorized vs Unauthorized routes.

The MiddlewareChain handles creating the linked list of Middleware. I added support for the existing HTTPService trait so it can easily be used instead of the existing services.

The lightbug_http.mojo was modified to demonstrate the use of the Middleware.

I also renamed the lightbug_welcome.html to index.html so the StaticMiddleware could be used.

Current Issues:

  1. Traits are not fully supported yet so the next in the middleware and the root in the chain are failing to compile:
/middleware/router.mojo:11:5: error: TODO: dynamic traits not supported yet, please use a compile time generic inste
ad of 'Middleware'
    var next: Middleware
  1. The Dict collection requires the value to support the CollectionElement trait. Both the HTTPHandler and AnyType are traits and not implementations so this causes issues with the Dict in the Router and Dict in the Context that holds the parameters.
/middleware/router.mojo:12:30: error: 'Dict' parameter #1 has 'CollectionElement' type, but value has type 'AnyTrait
[HTTPHandler]'
    var routes: Dict[String, HTTPHandler]

drujensen avatar May 05 '24 16:05 drujensen