httpservice

package module
v1.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2026 License: MIT Imports: 19 Imported by: 0

README

http_service — Caddy HTTP Handler Module

A Caddy v2 HTTP handler module that proxies requests to an external HTTP service, parses the JSON response, and injects each key as a {http_service.<key>} placeholder available to subsequent handlers in the middleware chain.

Supports response caching using Caddy's configurable storage backend (file system, Redis, Consul, etc.) with a stale-if-error fallback pattern: when the upstream service is unavailable, a stale (expired) cache entry is served instead of returning an error.

Configuration Reference

All fields are optional unless noted otherwise.

Field Type Default Description
url string required External service URL. Supports Caddy placeholders ({host}, {path}, etc.).
method string GET HTTP method for the external request.
headers map[string]string Custom headers sent to the external service. Keys and values support placeholders.
body string Request body template. Supports placeholders. Typically used with POST/PUT.
timeout duration Maximum duration for the external request. Zero means no timeout.
tls_skip_verify bool false Skip TLS certificate verification. Only use in trusted environments.
cache_enabled bool false Enable response caching via the configured Caddy storage backend.
cache_ttl duration Time-to-live for cache entries. A zero value means entries never expire.
cache_stale_enabled bool false Serve stale (expired) cache entries when the upstream request fails.
cache_key_template string required when cache_enabled Template for building cache keys. Supports Caddy placeholders.
params map[string]string Query parameters to append to the URL. Keys and values support placeholders. Values are URL-encoded before being appended.

Placeholder Usage

After a successful external service call, every top-level JSON key is available as {http_service.<key>}. Nested objects are flattened with dot-separated keys.

Example JSON response:

{
    "tenant": "acme",
    "version": 2,
    "user": {
        "name": "alice",
        "role": "admin"
    }
}

Available placeholders:

{http_service.tenant}         → "acme"
{http_service.version}         → "2"
{http_service.user.name}      → "alice"
{http_service.user.role}      → "admin"

JSON types are converted to strings:

  • string → as-is
  • float64 → integer formatting when whole, decimal otherwise
  • bool"true" or "false"
  • null"" (empty string)

Cache Behavior

When cache_enabled is true and a Caddy storage backend is configured:

  1. Cache Hit — A cached entry exists and hasn't expired. The stored JSON data is injected as placeholders without making an outbound HTTP call.
  2. Cache Miss — No cached entry exists. The outbound HTTP call is made, the JSON response is injected, and the result is stored in the cache.
  3. Expired Entry — A cached entry exists but its TTL has passed. A fresh HTTP call is made and the cache is updated.

With cache_stale_enabled enabled:

  1. Stale Fallback — If the outbound HTTP call fails (connection error, timeout, 5xx) and a cache entry exists (even if expired), the stale data is served instead of passing through to the next handler with no placeholders set.

Cache keys are prefixed with http_service/ in storage to avoid collisions with other modules.

Caddyfile Syntax

Caddyfile Directives
Directive Arguments Description
url <string> External service URL (required).
method <string> HTTP method (default: GET).
header <key> <value> Add a custom header (repeatable).
body <string> Request body template.
timeout <duration> Request timeout (e.g., 5s, 1m).
tls_skip_verify Skip TLS certificate verification.
cache_enabled Enable response caching.
cache_disabled Explicitly disable caching.
cache_ttl <duration> Cache TTL (e.g., 1h, 30m).
cache_stale_enabled Enable stale-if-error fallback.
cache_key_template <string> Cache key template.
param <key> <value> Add a URL-encoded query parameter (repeatable).
Examples

Basic — Tenant resolution:

example.com {
    http_service {
        url http://internal-api/tenants/{host}
    }
    root * /srv/{http_service.tenant}
    file_server
}

Query parameters (URL-encoded):

example.com {
    http_service {
        url http://internal-api/tenants
        param domain {host}
        param page 1
    }
    root * /srv/{http_service.tenant}
    file_server
}

With caching and Redis storage:

{
    storage redis {
        host localhost
        port 6379
    }
}

geo.example.com {
    http_service {
        url https://geo-api.internal/lookup/{http.request.remote.host}
        cache_enabled
        cache_key_template geo:{http.request.remote.host}
        cache_ttl 1h
        cache_stale_enabled
    }
    header X-Geo-Country {http_service.country}
}

Fallback pattern — static paths bypass the API:

app.example.com {
    handle /static/* {
        root * /var/www/static
        file_server
    }
    handle {
        http_service {
            url http://api.internal/info
            cache_enabled
            cache_key_template info:{host}
            cache_ttl 30m
        }
        root * /data/{http_service.tenant_id}
        file_server
    }
}

See the Caddyfile for more complete examples.

Build & Install

Build with xcaddy:

xcaddy build \
    --with github.com/aureolebigben/caddy-http-service

Replace the module path with your own if you've forked or renamed it.

License

MIT — see LICENSE.


Development assisted by AI.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type HttpService

type HttpService struct {
	// URL is the external service URL. It may contain Caddy placeholders
	// such as {host}, {uri}, {path}, {method}, etc.
	URL string `json:"url,omitempty"`

	// Method is the HTTP method used when calling the external service.
	// Defaults to GET if empty.
	Method string `json:"method,omitempty"`

	// Headers are custom headers to include in the request to the external
	// service.
	Headers map[string]string `json:"headers,omitempty"`

	// Body, when non-empty, provides a request body template. Typically
	// used for POST and PUT requests.
	Body string `json:"body,omitempty"`

	// Timeout is the maximum duration for the request to the external
	// service. Zero means no timeout.
	Timeout caddy.Duration `json:"timeout,omitempty"`

	// TLSSkipVerify controls whether the TLS certificate presented by the
	// external service is verified. It should only be used in trusted
	// development or internal environments.
	TLSSkipVerify bool `json:"tls_skip_verify,omitempty"`

	// CacheEnabled controls whether responses from the external service
	// are cached. When true, responses are stored using the configured
	// Caddy storage backend and served from cache on subsequent matching
	// requests until the TTL expires. Default: true.
	CacheEnabled bool `json:"cache_enabled,omitempty"`

	// CacheTTL is the time-to-live for cache entries. After this duration,
	// the cached entry is considered expired and a fresh request is made
	// to the external service. A zero value means entries do not expire.
	CacheTTL caddy.Duration `json:"cache_ttl,omitempty"`

	// CacheStaleEnabled controls whether a stale (expired) cache entry is
	// served when the external service request fails. When true, if a
	// fresh HTTP call fails and a cache entry exists (even if expired),
	// the stale data is served instead of returning an error. Default: true.
	CacheStaleEnabled bool `json:"cache_stale_enabled,omitempty"`

	// CacheKeyTemplate defines the template used to build the cache key.
	// It supports Caddy placeholders. Default: "{method}:{url}".
	CacheKeyTemplate string `json:"cache_key_template,omitempty"`

	// Params are query parameters to append to the URL. Each key is the
	// parameter name; each value is a Caddy placeholder template. Values
	// are expanded and URL-encoded before being appended as query strings.
	Params map[string]string `json:"params,omitempty"`
	// contains filtered or unexported fields
}

HttpService implements an HTTP handler module that proxies requests to an external HTTP service. parses the JSON response, and injects each key as a {http_service.<key>} placeholder available to subsequent handlers in the middleware chain. It is registered as http.handlers.http_service.

func (HttpService) CaddyModule

func (HttpService) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*HttpService) Provision

func (h *HttpService) Provision(ctx caddy.Context) error

Provision validates the configuration and prepares the HTTP client and cache storage backend.

func (HttpService) ServeHTTP

func (h HttpService) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error

ServeHTTP calls the configured external HTTP service, injects JSON response keys as {http_service.<key>} placeholders, and passes control to the next handler in the middleware chain.

When caching is enabled, the handler first checks the configured Caddy storage backend for a matching cache entry. On a cache hit, the stored JSON data is injected without making an outbound HTTP call. On a miss, the HTTP call is made and the result is cached.

If CacheStaleEnabled is true and the outbound call fails, a stale (expired) cache entry is served as a fallback.

func (*HttpService) UnmarshalCaddyfile

func (h *HttpService) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile parses the http_service Caddyfile directive.

Directories

Path Synopsis
Mock server for testing http_service module Run: go run mock_server.go
Mock server for testing http_service module Run: go run mock_server.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL