Skip to content

Mapping Configuration to Go Structs

This guide shows how a configuration file is mapped directly to Go structures in Caddy.


1. The Configuration Formats

Format A: The Caddyfile (Human-Readable)

Suppose you have a simple Caddyfile that looks like this:

:8080 {
    respond "Hello, World!"
}

Format B: Adapted JSON (Caddy's Native Format)

When Caddy adapts the Caddyfile above, it translates it into the following JSON:

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [":8080"],
          "routes": [
            {
              "handle": [
                {
                  "handler": "static_response",
                  "body": "Hello, World!"
                }
              ]
            }
          ]
        }
      }
    }
  }
}


2. Tracing the JSON to Go Structs

When caddy.Load() receives the JSON above, it unmarshals it into Go structures. Here is exactly where those values go:

Step 1: The Root Config Struct

  • JSON Location: The entire JSON document.
  • Go Struct: caddy.go:L68
    type Config struct {
        Admin   *AdminConfig    `json:"admin,omitempty"`
        Logging *Logging        `json:"logging,omitempty"`
        AppsRaw ModuleMap       `json:"apps,omitempty"`
    }
    
  • Since our JSON does not have "admin" or "logging", those fields are ignored (omitempty).
  • The "apps" JSON key is unmarshaled into the AppsRaw field.

Step 2: The App Layer (http)

  • JSON Location: apps.http
  • Go Struct: In Caddy, "http" maps to the HTTP app module struct. The JSON key "http" becomes a raw message inside AppsRaw and is dynamically unmarshaled into the App structure for the HTTP server:
  • Key "servers" maps to a map of server configurations.
  • Key "listen" (e.g. [":8080"]) maps to a list of network socket addresses.
  • Key "routes" maps to an array of HTTP route configurations.

Step 3: The Route Handler Layer (static_response)

  • JSON Location: apps.http.servers.srv0.routes[0].handle[0]
    {
      "handler": "static_response",
      "body": "Hello, World!"
    }
    
  • Go Struct:
  • Caddy reads the "handler": "static_response" property.
  • It looks up the module registry and finds the static response handler.
  • It unmarshals "body": "Hello, World!" into the static response handler's Go struct:
    type StaticResponse struct {
        StatusCode string `json:"status_code,omitempty"`
        Body       string `json:"body,omitempty"`
    }
    
    (In this struct, the Body field is set to "Hello, World!").