Warning this one is still in theory mode so the issue may be long
Tasks
Description
The Middleware engine and API will be pretty straight forward. For info on what it may look like please visit the middleware.md notes
As of this moment I am unsure whether or not we will need a octoris/middleware
require or if we will only have a single function to handle middleware and that function can live in the octoris/utils
(or maybe even just have it live in octoris/router
) instead.
Usage
The flow will work something like this: (Or at least the idea is this)
const { route, static } = require('octoris/router')
const { send } = require('octoris/response')
const { GET } = require('octoris/methods')
const { use } = require('octoris/utils')
const someMiddleware = require('someMiddleware')
const homeHandler = () => send(200, 'hello world!')
route([static('home')], [
GET(homeHandler),
use(someMiddleware)
])
The problem here is how does the GET(homeHandler)
know about the use(someMiddleware)
? They're not exactly connected or related that well aside from the fact that one comes after the other.
A quick solution to this might be to change the above route to something more like this:
route([static('home')], [
[GET(homeHandler), use(someMiddleware)]
])
So now when route sees this array it will know that the GET
is also expecting something else like middleware.
My only problem with the above is that we are now needing to handle different data expectations, sometimes it could be a function sometimes its an array. Which isn't the worst but it isn't that good either.
Middleware Branch Concept
(We still need a way to get it to the radix tree which is what the above proposal would do)
Another theory/concept could be that middleware is given a branch within the Radix Tree of routes. For instance /home
with a GET
forms a Radix tree that looks like this:
Map {
'home': Map {
type: 'static'
optional: false,
methods: Map {
'GET': Function
}
}
}
So what if a middleware being attached to a route method just becomes a value within that Map something like this:
Map {
'home': Map {
type: 'static'
optional: false,
methods: Map {
'GET': Map(?*) {
handler: Function,
middleware: Function[] || Set
}
}
}
}
(?*): This doesn't need to be a Map, this could easily just be an Object here
With the above when the /home
route is triggered it will look at the GET
handler and see if any middleware is also there, if so use that first and then the handler.
Important: This layout would be used even if there was no attached middleware, in that instance middleware
would just be an empty Array/Set