FAQ
Why doesn’t Frizzante have middleware?
Section titled “Why doesn’t Frizzante have middleware?”Frizzante intentionally uses guards instead of middleware.
Middleware have some limitations.
- All middleware must be invoked for each request
- Some middleware may contain path-checking logic while others may not, which introduces ambiguity and more details to remember as a developer
- Managing middleware execution order across different routes is complex
While guards have some advantages.
- Efficient - each route has a defined slice of guards and only those guards will execute each time the route is matched
- Explicit - since each route explicitly defines its guards, you can see exactly which guards execute for any route just by looking at the slice
- Composable - in order to add a new guard you can just add a guard to the route’s guards slice
- Easy to order - it’s easy to define the order in which guards execute, you can simply move them around in the route’s guards slice
For more details see the guards page.
Middleware Implementation
Section titled “Middleware Implementation”If you really want middleware-like behavior, you can easily implement it in your own project.
package middlewares
import "main/lib/core/clients"
type Hook func(client *clients.Client, next func()) // Defines a hook function type which will be used by the middleware.
type Middleware struct { // Defines a structure holding multiple hooks. Hooks []Hook // Defines the actual hooks slice.}package middlewares
import ( "main/lib/core/clients" "main/lib/core/routes")
func Apply(middleware *Middleware, routes []routes.Route) { for _, route := range routes { // For each route... handler := r.Handler // ...saves the route handler for later use. route.Handler = func(client *clients.Client) { // Assigns a new wrapper route handler. var quit bool // Creates flag used to interrupt the chain. for _, hook := range middleware.Hooks { // Iterate over hooks. quit = true // Prepares to quit. if hook(client, func() { quit = false }); quit { // Invokes hook and checks if route should quit. return // Quits. } } handler(client) // Invokes the actual route handler. } }}Middleware Usage
Section titled “Middleware Usage”package main
import ( "embed" "main/lib/core/clients" "main/lib/core/routes" "main/lib/core/servers" "main/lib/core/view/ssr" "main/lib/middlewares" "main/lib/routes/fallback" "main/lib/routes/todos" "main/lib/routes/welcome" "os")
//go:embed app/distvar efs embed.FSvar server = servers.New()
var middleware = &middlewares.Middleware{ Hooks: []middleware.Hook{ func(client *clients.Client, next func()) { // Hook logic goes here. }, },}
func main() { defer servers.Start(server) defer middlewares.Apply(middleware, server.Routes) // Applies middleware to server routes. // Remember that deferred functions are executed in reverse, // so this line will execute before the server starts. server.Efs = efs // Sets embedded file system. server.Routes = []routes.Route{ {Pattern: "GET /", Handler: fallback.View}, {Pattern: "GET /welcome", Handler: welcome.View}, {Pattern: "GET /todos", Handler: todos.View}, {Pattern: "GET /check", Handler: todos.Check}, {Pattern: "GET /uncheck", Handler: todos.Uncheck}, {Pattern: "GET /add", Handler: todos.Add}, {Pattern: "GET /remove", Handler: todos.Remove}, }}Can I use Frizzante with other frontend frameworks?
Section titled “Can I use Frizzante with other frontend frameworks?”Yes you can, as long as Vite supports your framework.
All you need to do is configure your app/app.client.ts and app/app.server.ts to render your framework.
You can find a Vue3 example here.