Skip to content

FAQ

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.

If you really want middleware-like behavior, you can easily implement it in your own project.

lib/middlewares/types.go
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.
}
lib/middlewares/apply.go
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.
}
}
}
main.go
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/dist
var efs embed.FS
var 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.