Help us shape the future of Go! Take the 2026 Go Developer Survey

redirects

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: AGPL-3.0 Imports: 23 Imported by: 0

Documentation

Overview

Package redirects manages URL redirects.

contract.go holds the frozen wave-0 contract (types and interfaces only). The implementation arrives in wave 1.

Index

Constants

View Source
const HookSaved = "redirects.saved"

HookSaved is emitted (async) after redirects change; payload SavedEvent.

View Source
const Perm = "redirects.manage"

Perm is the permission for managing redirects.

Variables

View Source
var ErrNotFound = errors.New("redirects: not found")

ErrNotFound is returned for unknown redirects.

View Source
var ReservedPrefixes = []string{"/admin", "/api", "/mcp", "/auth", "/webhooks", "/media", "/static", "/checkout",
	"/account", "/healthz", "/readyz"}

ReservedPrefixes are application paths a redirect may never take over: saving one is a validation error and the middleware never answers them.

Functions

func HostOf

func HostOf(raw string) string

HostOf returns the lower-cased host of an absolute URL, or "".

func Middleware

func Middleware(svc Service) func(http.Handler) http.Handler

Middleware answers GET/HEAD requests whose path has an enabled redirect (exact, case-sensitive, trailing-slash-insensitive) and counts the hit. The original query string is kept unless the target has its own.

func NormalizePath

func NormalizePath(p string) string

NormalizePath returns p as stored and matched: percent-decoded, query and fragment removed, a leading "/" and no trailing "/" (except the root). Matching stays case-sensitive.

func Reserved

func Reserved(path string) bool

Reserved reports whether path is one of ReservedPrefixes or below one, by whole path segment and ignoring case ("/admin" and "/Admin/x" are, "/administration" and "/my-account" are not).

func ValidStatus

func ValidStatus(code int) bool

ValidStatus reports whether code is an allowed redirect status.

Types

type DeleteResponse

type DeleteResponse struct {
	ID      string `json:"id"`
	Deleted bool   `json:"deleted"`
}

DeleteResponse is returned by DELETE /v1/redirects/{id}.

type ImportResult

type ImportResult struct {
	Imported int        `json:"imported"`
	Errors   []RowError `json:"errors"`
}

ImportResult summarizes a CSV import.

type ListQuery

type ListQuery struct {
	Search  string `json:"search"`
	Page    int    `json:"page"`
	PerPage int    `json:"per_page"`
	Sort    string `json:"sort"`
	Order   string `json:"order"`
}

ListQuery filters Service.List.

type Module

type Module struct{}

Module is the redirects kernel.Module.

func New

func New() *Module

New returns the redirects module.

func (*Module) Catalogs

func (*Module) Catalogs() fs.FS

Catalogs implements kernel.CatalogProvider.

func (*Module) Migrations

func (*Module) Migrations() fs.FS

Migrations implements kernel.Module.

func (*Module) Name

func (*Module) Name() string

Name implements kernel.Module.

func (*Module) Register

func (*Module) Register(d *kernel.Deps) error

Register publishes kernel.ServiceRedirects, wraps every public route with the redirect middleware, and adds the admin screen and API operations.

type Redirect

type Redirect struct {
	ID        string `json:"id"`
	FromPath  string `json:"from_path"`
	ToURL     string `json:"to_url"`
	Status    int    `json:"status"`
	Hits      int    `json:"hits"`
	Enabled   bool   `json:"enabled"`
	CreatedAt string `json:"created_at"`
}

type RowError

type RowError struct {
	Line int    `json:"line"`
	Key  string `json:"key"`
}

RowError is one rejected CSV line; Key is an i18n key.

type SaveRequest

type SaveRequest struct {
	ID       string `json:"id"`
	FromPath string `json:"from_path"`
	ToURL    string `json:"to_url"`
	Status   int    `json:"status" doc:"301 (default), 302, 307 or 308"`
	Enabled  *bool  `json:"enabled,omitempty" doc:"default true"`
}

SaveRequest is the body of POST /v1/redirects (create when ID is empty).

type SavedEvent

type SavedEvent struct {
	Action   string `json:"action"` // save | delete | import
	ID       string `json:"id,omitempty"`
	FromPath string `json:"from_path,omitempty"`
	Count    int    `json:"count,omitempty"`
}

SavedEvent is the HookSaved payload.

type Service

type Service interface {
	Lookup(ctx context.Context, path string) (*Redirect, bool)
	List(ctx context.Context, q ListQuery) ([]Redirect, int, error)
	Save(ctx context.Context, r Redirect) (*Redirect, error)
	Delete(ctx context.Context, id string) error
	Hit(ctx context.Context, id string)
}

type ValidationError

type ValidationError struct {
	Fields map[string]string `json:"fields"`
}

ValidationError lists invalid fields (values are i18n keys).

func (*ValidationError) Error

func (e *ValidationError) Error() string

Jump to

Keyboard shortcuts

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