Guards
A guard is an object that is composed of an optional name and a required handler.
You can add guards to your routes in order to protect them or modify their scope.
package main

import (
    "main/lib/core/guards"
    "main/lib/core/routes"
    "main/lib/core/scopes"
    "main/lib/routes/data"
    "net/http"
)

var _ = []routes.Route{
    {
        Pattern: "GET /api/xml/data",
        Handler: data.Get,
        Guards: []guards.Guard{
            {
                Name: "jsonless",
                Handler: func(_ scopes.Scope, request *http.Request, writer http.ResponseWriter, allow func()) {
                    if request.Header.Get("Content-Type") == "application/json" {
                        writer.WriteHeader(http.StatusBadRequest)
                        return
                    }
                    allow()
                },
            },
        },
    },
}
Guards will block all incoming requests by default, you must call allow() to explicitly allow the request through.
In this example, the route GET /api/xml/data will decline requests with content type application/json


Composition
You can compose multiple guards in order to create more advanced restrictions.
package main

import (
    "main/lib/core/databases"
    "main/lib/core/databases/schema"
    "main/lib/core/guards"
    "main/lib/core/negotiate"
    "main/lib/core/routes"
    "main/lib/core/scopes"
    "main/lib/routes/dashboard"
    "main/lib/routes/public"
    "main/lib/routes/settings"
    "main/lib/routes/users"
    "net/http"
)

var _, queries, _ = databases.Connect()

var authenticate = guards.Guard{
    Name: "authenticate",
    Handler: func(scope scopes.Scope, request *http.Request, writer http.ResponseWriter, allow func()) {
        sessionId, _ := negotiate.SessionId(writer, request)
        session, _ := queries.FindSessionById(request.Context(), sessionId)
        if session.ID == "" {
            writer.WriteHeader(401)
            writer.Write([]byte("not authenticated"))
            return
        }
        scope["session"] = session
        allow()
    },
}

var authorize = guards.Guard{
    Name: "authorize",
    Handler: func(scope scopes.Scope, request *http.Request, writer http.ResponseWriter, allow func()) {
        session, _ := scope["session"].(schema.Session)
        if request.PathValue("user_id") != session.UserID {
            writer.WriteHeader(403)
            writer.Write([]byte("missing permissions"))
            return
        }
        allow()
    },
}

var server_routes = []routes.Route{
    {Pattern: "GET /public", Handler: public.Get},
    {Pattern: "GET /dashboard", Handler: dashboard.Get, Guards: []guards.Guard{authenticate}},
    {Pattern: "GET /users/{user_id}/settings", Handler: settings.Get, Guards: []guards.Guard{authenticate, authorize}},
    {Pattern: "DELETE /users/{user_id}", Handler: users.Delete, Guards: []guards.Guard{authenticate, authorize}},
}