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.
- Explicit - you can see exactly which routes use which guards by looking at their tags
- Efficient - guards only execute when their tags match - no wasted computation
- Composable - easy to manage execution order per route
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.