Gothic Framework G symbol

Cache Control Headers

The Gothic Framework provides a built-in pluggable cache system that handles page and API response caching with multiple strategy options. You configure the cache in the Runtime block of your gothic.config.go file, which sets the cache strategy and static file serving. The runtime Middleware then applies that configuration, and RegisterFileBasedRoutes wires up your file-based routes.

CACHE_CONTROL_HEADERS is the default strategy. It does not store cached data in your application. Instead, it sets Cache-Control headers on responses so that a CDN (like AWS CloudFront) caches them at the edge. This is the recommended strategy for AWS deployments with the Gothic deploy tool.

The runtime Middleware reads the GOTHIC_MODE environment variable. Set GOTHIC_MODE=dev in your .env file for local development. When absent or set to any other value, the application runs in production mode.

Here is a typical gothic.config.go using Cache Control Headers:

package main

import gothic "github.com/gothicframework/core/config"

var Config = gothic.Config{
	ProjectName: "my-project",
	Runtime: gothic.RuntimeConfig{
		CacheStrategy:         gothic.CACHE_CONTROL_HEADERS,
		LocalDevelopmentCache: gothic.IN_MEMORY,
		ServeStaticFiles:      gothic.CDN,
	},
}

And here is the main.go that applies it with the runtime Middleware:

package main

import (
	"log"
	"log/slog"
	"net/http"
	"os"

	"your-module/src/routes"
	gothicServer "github.com/gothicframework/middlewares"

	"github.com/go-chi/chi/middleware"
	"github.com/go-chi/chi/v5"
	"github.com/joho/godotenv"
)

func main() {
	godotenv.Load()
	router := chi.NewMux()
	router.Use(middleware.Logger)

	router.Use(gothicServer.Middleware(Config.Runtime))
	routes.RegisterFileBasedRoutes(router)

	port := os.Getenv("HTTP_LISTEN_ADDR")
	slog.Info("application running", "port", port)
	log.Fatal(http.ListenAndServe(port, router))
}

ServeStaticFiles controls when /public/* files are served from disk. CDN (default) serves them only in dev mode — in production, CloudFront serves static assets from S3. Use DISK for Docker or non-AWS deployments where the public folder ships alongside the binary.

EMBEDDED goes one step further: it bakes ./public into the server binary at build time via go:embed and serves /public/* straight from that embed in non-dev envs. The result is a single self-contained binary with no sidecar public/ folder — ideal for self-hosted container or VM deploys. It is not for AWS: there CloudFront and S3 serve /public/*, so embedding would only bloat the Lambda (and gothic deploy keeps syncing to S3, printing a warning when EMBEDDED is set). In dev mode (GOTHIC_MODE=dev) files are always served fresh from disk regardless of the mode.

package main

import gothic "github.com/gothicframework/core/config"

var Config = gothic.Config{
	ProjectName: "my-project",
	Runtime: gothic.RuntimeConfig{
		// Bake ./public into the server binary via //go:embed and serve
		// /public/* from that embed in non-dev envs.
		ServeStaticFiles: gothic.EMBEDDED,
	},
}

Want to cache pages directly in your application without a CDN? Check out the In Memory cache strategy!