Configure your server
The httpserver package provides flexible configuration options through YAML config files. All settings live under httpserver.<name> where <name> is the server name you pass to NewServer.
Default server
The simplest configuration is a single server named "default":
httpserver:
default:
port: 8080
httpserver.RunDefaultServer(func(ctx context.Context, config cfg.Config, logger log.Logger, router *httpserver.Router) error {
router.GET("/ping", handler)
return nil
})
Multiple named servers
You can run multiple HTTP servers in one application, each with its own configuration:
httpserver:
public:
port: 8080
admin:
port: 8090
mode: release
httpserver.RunServers(map[string]httpserver.RouterFactory{
"public": publicDefiner,
"admin": adminDefiner,
})
Or register them individually as module factories:
application.WithModuleFactory("http-public", httpserver.NewServer("public", publicDefiner))
application.WithModuleFactory("http-admin", httpserver.NewServer("admin", adminDefiner))
Full configuration reference
Settings
| Field | Type | Default | Description |
|---|---|---|---|
port | string | "8080" | Port the server listens on. Use "0" for a random port (useful in tests). |
mode | string | "release" | Gin mode: debug, release, or test. |
compression | CompressionSettings | - | Gzip compression settings. |
timeout | TimeoutSettings | - | IO timeout settings. |
logging | LoggingSettings | - | Request logging settings. |
errors | ErrorsSettings | - | Error response privacy settings. |
router | RouterSettings | - | Gin router settings. |
max_body_bytes | int | 10485760 | Maximum incoming request body size in bytes. 0 disables the limit. |
concurrency | ConcurrencySettings | - | Concurrent request and connection pressure limits. See Concurrency and connection pressure. |
Error settings
httpserver:
default:
errors:
privacy: private
| Field | Type | Default | Description |
|---|---|---|---|
privacy | string | "private" | Error detail policy for 5xx responses. Use "private" to hide internal details, or "public" to return the original error message. |
With the default private setting, internal 5xx errors return {"err":"internal server error"}. Status errors below 500 still expose their message, so client errors returned through NewErrorWithStatus or GetErrorHandler()(status, err) remain useful to API clients.
Set privacy to public only when exposing internal 5xx error messages is intentional:
httpserver:
default:
errors:
privacy: public
Request body size limit
By default, each server limits incoming request bodies to 10 MiB. The limit is applied after request decompression, so compressed uploads are checked by their decompressed size.
httpserver:
default:
max_body_bytes: 10485760
Set max_body_bytes to 0 to disable the limit, or raise it for endpoints that intentionally accept larger bodies.
Timeout settings
httpserver:
default:
timeout:
read: 60s
write: 60s
idle: 60s
drain: 0s
shutdown: 60s
| Field | Type | Default | Description |
|---|---|---|---|
read | duration | 60s | Maximum duration for reading the entire request, including the body. Minimum 1s. |
write | duration | 60s | Maximum duration before timing out writes of the response. Minimum 1s. |
idle | duration | 60s | Maximum time to wait for the next request when keep-alives are enabled. Minimum 1s. |
drain | duration | 0s | Time to wait after receiving a shutdown signal before starting graceful shutdown. Useful for load balancer deregistration. |
shutdown | duration | 60s | Maximum time for graceful shutdown. Minimum 1s. |
For long-running operations, increase the timeouts:
httpserver:
default:
port: 8081
timeout:
read: 10m
write: 10m
Compression settings
httpserver:
default:
compression:
level: default
decompression: true
exclude:
path:
- /api/events
extension:
- .png
pathRegex:
- \.json$
| Field | Type | Default | Description |
|---|---|---|---|
level | string | "default" | Compression level: "none", "default", "fast", "best", or "0"–"9". |
decompression | bool | true | Whether to decompress gzip-encoded request bodies. |
exclude | CompressionExcludeSettings | - | Paths/extensions/regexes to exclude from compression. |
Compression exclude settings
| Field | Type | Description |
|---|---|---|
path | string array | Exact paths to exclude (e.g., /api/events). |
extension | string array | File extensions to exclude (e.g., .png). |
pathRegex | string array | Regex patterns to exclude (e.g., \.json$). |
Always exclude SSE endpoints from compression. Gzip buffering will break real-time streaming. See Stream with SSE for details.
Health check server
The health check server runs on a separate port and is useful for load balancer health checks:
httpserver:
default:
port: 8080
The main server automatically registers a /health endpoint. Unhealthy modules are returned as "unhealthy"; underlying error messages are logged but not exposed in the HTTP response. For a separate health check server, the health check module is available separately. See Write health checks for details.
Profiling
Enable Go's built-in profiling endpoints (pprof) on a separate port:
profiling:
enabled: true
api:
port: 8091
When enabled, profiling endpoints are available at /debug/profiling/*. The profiling server binds to 127.0.0.1:<port>.
Graceful shutdown
The httpserver supports graceful shutdown:
- When the application context is cancelled, the server sets its healthy flag to
false - It waits for the
drainduration (useful for load balancer deregistration) - It calls
server.Shutdownwith theshutdowntimeout - In-flight requests are given time to complete
Connection lifecycle
In Kubernetes environments where load balancing only happens on new connections, you can configure the connection lifecycle advisor to periodically close connections:
httpserver:
default:
connection_lifecycle:
enabled: true
max_age: 1m
max_request_count: 0
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Enable/disable the connection lifecycle advisor. |
max_age | duration | 1m | Maximum age of a connection before it is closed. |
max_request_count | int | 0 | Maximum number of requests per connection. 0 means disabled. |
For full details on connection lifecycle, connection pressure management, and concurrent request limiting, see Concurrency and connection pressure.