aastro

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: May 26, 2026 License: Apache-2.0 Imports: 46 Imported by: 0

README

Aastro API Gateway

A lightweight, modular, and high-performance API Gateway for modern microservices.

Built with simplicity, performance, and developer-friendly configuration in mind.

Go Version License Go Report Card codecov Docker Pulls GitHub Created At GitHub release


✨ Features

  • 🚀 High-performance HTTP reverse proxy
  • 🔀 Request fan-out & response aggregation (merge, array, namespace)
  • 🧩 Dynamic .so plugin system (request & response phase)
  • 🔗 Path parameter extraction and forwarding
  • 🔁 Retry, circuit breaker & load balancing (round-robin, least-conns)
  • 📊 Prometheus metrics with circuit breaker state tracking
  • 🛡 Rate limiting & trusted proxy support
  • 📦 YAML-based configuration
  • 🐳 Docker-ready

🚀 Quick Start

git clone https://github.com/starwalkn/aastro.git
cd aastro

make all GOOS=<YOUR_OS> GOARCH=<YOUR_ARCH>
./bin/aastro -c path/to/config.yaml

Or with Docker:

docker run \
  -p 7805:7805 \
  -v $(pwd)/config.yaml:/etc/aastro/config.yaml \
  -e AASTRO_CONFIG=/etc/aastro/config.yaml \
  starwalkn/aastro:latest

📖 Documentation

Full documentation, configuration reference, and plugin guide are available at:

starwalkn.github.io/aastrodocs


📄 License

Open-source. See LICENSE file for details.


Made with ❤️ in Go

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WriteError

func WriteError(w http.ResponseWriter, code ClientError, status int)

Types

type AddrList

type AddrList []string

func (*AddrList) UnmarshalYAML

func (a *AddrList) UnmarshalYAML(value *yaml.Node) error

type AdminConfig

type AdminConfig struct {
	Port          int           `yaml:"port"    validate:"required,min=1,max=65535"`
	BindAddr      string        `yaml:"bind_addr" default:"127.0.0.1"`
	Timeout       time.Duration `yaml:"timeout"   default:"5m"`
	HeaderTimeout time.Duration `yaml:"header_timeout" default:"5s"`
	EnablePprof   bool          `yaml:"enable_pprof" default:"false"`
}

type AggregationConfig

type AggregationConfig struct {
	BestEffort bool              `yaml:"best_effort"`
	Strategy   string            `yaml:"strategy"    validate:"required,oneof=array merge namespace"`
	OnConflict *OnConflictConfig `yaml:"on_conflict" validate:"required_if=Strategy merge"`
}

type CircuitBreakerConfig

type CircuitBreakerConfig struct {
	Enabled      bool          `yaml:"enabled"`
	MaxFailures  int           `yaml:"max_failures"`
	ResetTimeout time.Duration `yaml:"reset_timeout"`
}

type ClientError

type ClientError string
const (
	ClientErrRateLimitExceeded    ClientError = "RATE_LIMIT_EXCEEDED"
	ClientErrPayloadTooLarge      ClientError = "PAYLOAD_TOO_LARGE"
	ClientErrUpstreamBodyTooLarge ClientError = "UPSTREAM_BODY_TOO_LARGE"
	ClientErrUpstreamUnavailable  ClientError = "UPSTREAM_UNAVAILABLE"
	ClientErrUpstreamError        ClientError = "UPSTREAM_ERROR"
	ClientErrUpstreamMalformed    ClientError = "UPSTREAM_MALFORMED"
	ClientErrInternal             ClientError = "INTERNAL"
	ClientErrAborted              ClientError = "ABORTED"
	ClientErrValueConflict        ClientError = "VALUE_CONFLICT"
)

func (ClientError) String

func (err ClientError) String() string

type ClientResponse

type ClientResponse struct {
	Data   json.RawMessage `json:"data,omitempty"`
	Errors []ClientError   `json:"errors,omitempty"`
	Meta   ResponseMeta    `json:"meta,omitempty"`
}

ClientResponse is an output structure that wraps the final response from the gateway to the client.

type Config

type Config struct {
	Schema  string        `yaml:"schema" validate:"required,oneof=v1"`
	Debug   bool          `yaml:"debug"`
	Gateway GatewayConfig `yaml:"gateway" validate:"required"`
}

func LoadConfig

func LoadConfig(path string) (Config, error)

LoadConfig reads, parses, applies defaults, validates, and returns the config.

func (*Config) Marshal

func (c *Config) Marshal() ([]byte, error)

func (*Config) WriteTo

func (c *Config) WriteTo(w io.Writer) (int64, error)

type FlowConfig

type FlowConfig struct {
	Path        string `yaml:"path"   validate:"required,startswith=/"`
	Method      string `yaml:"method" validate:"required,oneof=GET POST PUT PATCH DELETE HEAD OPTIONS"`
	Passthrough bool   `yaml:"passthrough"`

	// ParallelUpstreams defaults to 2×NumCPU when unset or zero.
	ParallelUpstreams int64 `yaml:"parallel_upstreams"`

	Aggregation *AggregationConfig `yaml:"aggregation"  validate:"required_if=Passthrough false"`
	Upstreams   []UpstreamConfig   `yaml:"upstreams"    validate:"required,min=1,dive,required"`
	Plugins     []PluginConfig     `yaml:"plugins"      validate:"omitempty,dive"`
	Middlewares []MiddlewareConfig `yaml:"middlewares"  validate:"omitempty,dive"`
}

type GatewayConfig

type GatewayConfig struct {
	Service       ServiceConfig       `yaml:"service"`
	Server        ServerConfig        `yaml:"server"  validate:"required"`
	Admin         AdminConfig         `yaml:"admin" validate:"required"`
	Observability ObservabilityConfig `yaml:"observability"`
	Routing       RoutingConfig       `yaml:"routing" validate:"required"`
}

type LoadBalancingConfig

type LoadBalancingConfig struct {
	Mode string `yaml:"mode"`
}

type MetricsConfig

type MetricsConfig struct {
	Enabled  bool       `yaml:"enabled"`
	Exporter string     `yaml:"exporter" validate:"required_if=Enabled true,omitempty,oneof=otlp prometheus"`
	OTLP     OTLPConfig `yaml:"otlp"`
}

type MiddlewareConfig

type MiddlewareConfig struct {
	Name   string                 `yaml:"name"   validate:"required"`
	Source string                 `yaml:"source" validate:"required,oneof=builtin file"`
	Path   string                 `yaml:"path"   validate:"required_if=Source file,omitempty"`
	Config map[string]interface{} `yaml:"config"`
}

type OTLPConfig

type OTLPConfig struct {
	Endpoint string        `yaml:"endpoint"`
	Insecure bool          `yaml:"insecure"`
	Interval time.Duration `yaml:"interval"`
}

type ObservabilityConfig

type ObservabilityConfig struct {
	Tracing TracingConfig `yaml:"tracing"`
	Metrics MetricsConfig `yaml:"metrics"`
}

type OnConflictConfig

type OnConflictConfig struct {
	Policy   string `yaml:"policy"          validate:"oneof=overwrite error first prefer"`
	Upstream string `yaml:"prefer_upstream" validate:"required_if=Policy prefer"`
}

type PluginConfig

type PluginConfig struct {
	Name   string                 `yaml:"name"   validate:"required"`
	Source string                 `yaml:"source" validate:"required,oneof=builtin file"`
	Path   string                 `yaml:"path"   validate:"required_if=Source file"`
	Config map[string]interface{} `yaml:"config"`
}

type PolicyConfig

type PolicyConfig struct {
	HeaderBlacklist     []string `yaml:"header_blacklist"`
	AllowedStatuses     []int    `yaml:"allowed_statuses"`
	RequireBody         bool     `yaml:"require_body"`
	MaxResponseBodySize int64    `yaml:"max_response_body_size"`

	RetryConfig          RetryConfig          `yaml:"retry"`
	CircuitBreakerConfig CircuitBreakerConfig `yaml:"circuit_breaker"`
	LoadBalancingConfig  LoadBalancingConfig  `yaml:"load_balancing"`
}

type RateLimiterConfig

type RateLimiterConfig struct {
	Enabled bool                   `yaml:"enabled"`
	Config  map[string]interface{} `yaml:"config" validate:"required"`
}

type ResponseMeta

type ResponseMeta struct {
	RequestID string `json:"request_id,omitempty"`
	Partial   bool   `json:"partial,omitempty"`
}

type RetryConfig

type RetryConfig struct {
	MaxRetries      int           `yaml:"max_retries"`
	RetryOnStatuses []int         `yaml:"retry_on_statuses"`
	BackoffDelay    time.Duration `yaml:"backoff_delay"`
}

type Router

type Router struct {
	// contains filtered or unexported fields
}

func (*Router) Close

func (r *Router) Close() error

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP handles incoming HTTP requests through the full router pipeline:

  1. Rate limiting — rejects requests exceeding the configured limit.
  2. Flow matching — chi router finds the flow by method and path (404 if none).
  3. Middleware execution — per-flow middlewares wrap the handler.
  4. Request plugins — run before upstream scatter; may modify the request.
  5. Upstream scatter — fan-out to all configured upstreams.
  6. Response aggregation — merge/array/namespace strategies with bestEffort support.
  7. Response plugins — run after aggregation; may modify headers or body.
  8. Response writing — status, headers, and JSON body sent to the client.

Status codes: 200 on full success, 206 on partial (bestEffort), 502/500 on failure. Every response carries an X-Request-ID header and a JSON body with data/errors fields.

type RouterBundle

type RouterBundle struct {
	Router         *Router
	MeterProvider  otelcommon.Provider
	TracerProvider otelcommon.Provider
	PromRegistry   *prometheus.Registry // nil unless metrics.exporter == "prometheus"
}

func NewRouter

func NewRouter(ctx context.Context, cfgSet RoutingConfigSet, log *zap.Logger) (RouterBundle, error)

type RoutingConfig

type RoutingConfig struct {
	RateLimiter    RateLimiterConfig `yaml:"rate_limiter" validate:"omitempty"`
	TrustedProxies []string          `yaml:"trusted_proxies"`
	Flows          []FlowConfig      `yaml:"flows" validate:"min=1,dive,required"`
}

type RoutingConfigSet

type RoutingConfigSet struct {
	Routing        RoutingConfig
	Service        ServiceConfig
	ServiceVersion string // injected via ldflags
	Metrics        MetricsConfig
	Tracing        TracingConfig
}

type ServerConfig

type ServerConfig struct {
	Port          int             `yaml:"port"    validate:"required,min=1,max=65535"`
	Timeout       time.Duration   `yaml:"timeout" default:"5s"`
	HeaderTimeout time.Duration   `yaml:"header_timeout" default:"5s"`
	TLS           ServerTLSConfig `yaml:"tls"`
}

type ServerTLSConfig

type ServerTLSConfig struct {
	Enabled      bool   `yaml:"enabled"`
	CertFile     string `yaml:"cert_file"      validate:"required_if=Enabled true"`
	KeyFile      string `yaml:"key_file"       validate:"required_if=Enabled true"`
	MinVersion   string `yaml:"min_version"    default:"1.2" validate:"omitempty,oneof=1.2 1.3"`
	ClientAuth   string `yaml:"client_auth"    default:"none" validate:"omitempty,oneof=require optional none"`
	ClientCAFile string `yaml:"client_ca_file" validate:"required_unless=ClientAuth none"`
}

type ServiceConfig

type ServiceConfig struct {
	Name string `yaml:"name" default:"aastro"`
}

type TLSConfig

type TLSConfig struct {
	Enabled            bool   `yaml:"enabled"`
	CertFile           string `yaml:"cert_file" validate:"required_with=KeyFile"`
	KeyFile            string `yaml:"key_file" validate:"required_with=CertFile"`
	CAFile             string `yaml:"ca_file"`
	ServerName         string `yaml:"server_name"`
	InsecureSkipVerify bool   `yaml:"insecure_skip_verify"`
	MinVersion         string `yaml:"min_version" default:"1.2" validate:"omitempty,oneof=1.2 1.3"`
}

type TracingConfig

type TracingConfig struct {
	Enabled       bool       `yaml:"enabled"`
	Exporter      string     `yaml:"exporter" validate:"required_if=Enabled true,omitempty,oneof=otlp"`
	SamplingRatio float64    `yaml:"sampling_ratio" default:"1.0" validate:"min=0,max=1"`
	OTLP          OTLPConfig `yaml:"otlp"`
}

type TransportConfig

type TransportConfig struct {
	MaxIdleConns        int           `yaml:"max_idle_conns"         default:"100"`
	MaxIdleConnsPerHost int           `yaml:"max_idle_conns_per_host" default:"50"`
	IdleConnTimeout     time.Duration `yaml:"idle_conn_timeout"      default:"90s"`
}

type UpstreamConfig

type UpstreamConfig struct {
	Name    string        `yaml:"name" validate:"required"`
	Hosts   AddrList      `yaml:"hosts" validate:"min=1,dive"`
	Path    string        `yaml:"path"`
	Method  string        `yaml:"method"`
	Timeout time.Duration `yaml:"timeout" default:"3s"`

	ForwardHeaders []string `yaml:"forward_headers"`
	ForwardQueries []string `yaml:"forward_queries"`
	ForwardParams  []string `yaml:"forward_params"`

	Policy    PolicyConfig    `yaml:"policy"`
	Transport TransportConfig `yaml:"transport"`
	TLS       TLSConfig       `yaml:"tls"`
}

Directories

Path Synopsis
builtin
plugins/masker command
cmd
aastro command
aastroctl command
internal
otelcommon
Package otelcommon builds the shared OpenTelemetry Resource used by both the metric and tracing providers, so signals from the same process share a consistent identity (service.name, service.version, host, process, …) in the observability backend.
Package otelcommon builds the shared OpenTelemetry Resource used by both the metric and tracing providers, so signals from the same process share a consistent identity (service.name, service.version, host, process, …) in the observability backend.

Jump to

Keyboard shortcuts

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