Documentation
¶
Overview ¶
Package coreapi provides API management capabilities including rate limiting, API key management, and usage tracking.
CoreAPI is designed to work alongside CoreAuth for comprehensive API management:
- CoreAuth: Authentication & Authorization (who can access what)
- CoreAPI: API Management (how much, how fast, usage tracking)
Rate Limiting ¶
Rate limiting is policy-based, where policies can be assigned to OAuth clients:
store := coreapi.NewMemoryPolicyStore() store.SavePolicy(ctx, coreapi.PremiumPolicy) store.AssignPolicyToClient(ctx, "my-oauth-client-id", "premium")
Integration with HTTP Middleware ¶
Use with CoreForge session/ratelimit for HTTP enforcement:
resolver := ratelimit.NewPolicyResolver(store) limiter := ratelimit.New(storage, ratelimit.WithResolver(resolver)) router.Use(limiter.Middleware())
Index ¶
- Variables
- type ClientPolicyBinding
- type MemoryPolicyStore
- func (s *MemoryPolicyStore) BindClientToPolicy(ctx context.Context, clientID, policyID string) error
- func (s *MemoryPolicyStore) CreatePolicy(ctx context.Context, policy *RateLimitPolicy) error
- func (s *MemoryPolicyStore) DeletePolicy(ctx context.Context, policyID string) error
- func (s *MemoryPolicyStore) GetDefaultPolicy(ctx context.Context) (*RateLimitPolicy, error)
- func (s *MemoryPolicyStore) GetPolicy(ctx context.Context, policyID string) (*RateLimitPolicy, error)
- func (s *MemoryPolicyStore) GetPolicyForClient(ctx context.Context, clientID string) (*RateLimitPolicy, error)
- func (s *MemoryPolicyStore) ListClientBindings(ctx context.Context) ([]*ClientPolicyBinding, error)
- func (s *MemoryPolicyStore) ListClientsForPolicy(ctx context.Context, policyID string) ([]string, error)
- func (s *MemoryPolicyStore) ListPolicies(ctx context.Context) ([]*RateLimitPolicy, error)
- func (s *MemoryPolicyStore) SetDefaultPolicy(ctx context.Context, policyID string) error
- func (s *MemoryPolicyStore) UnbindClient(ctx context.Context, clientID string) error
- func (s *MemoryPolicyStore) UpdatePolicy(ctx context.Context, policy *RateLimitPolicy) error
- type PolicyStore
- type RateLimitPolicy
- type RateLimits
- type UsageRecord
- type UsageStore
- type UsageSummary
Constants ¶
This section is empty.
Variables ¶
var ( // FreePolicy is for free tier users and anonymous requests. FreePolicy = &RateLimitPolicy{ ID: "free", Name: "Free Tier", Description: "Rate limits for free tier users and anonymous requests", Enabled: true, Limits: RateLimits{ PerMinute: 10, PerHour: 100, PerDay: 500, BurstSize: 5, }, } // StandardPolicy is for standard paid users. StandardPolicy = &RateLimitPolicy{ ID: "standard", Name: "Standard Tier", Description: "Rate limits for standard tier users", Enabled: true, Limits: RateLimits{ PerMinute: 100, PerHour: 1000, PerDay: 10000, BurstSize: 20, }, } // PremiumPolicy is for premium users. PremiumPolicy = &RateLimitPolicy{ ID: "premium", Name: "Premium Tier", Description: "Rate limits for premium tier users", Enabled: true, Limits: RateLimits{ PerMinute: 1000, PerHour: 10000, PerDay: 100000, BurstSize: 100, }, } // EnterprisePolicy is for enterprise users with high limits. EnterprisePolicy = &RateLimitPolicy{ ID: "enterprise", Name: "Enterprise Tier", Description: "Rate limits for enterprise tier users", Enabled: true, Limits: RateLimits{ PerMinute: 10000, PerHour: 100000, PerDay: 1000000, BurstSize: 500, }, } // InternalPolicy is for internal service-to-service calls. InternalPolicy = &RateLimitPolicy{ ID: "internal", Name: "Internal Service", Description: "High limits for internal service-to-service communication", Enabled: true, Priority: 100, Limits: RateLimits{ PerSecond: 10000, BurstSize: 1000, }, } // UnlimitedPolicy has no rate limits (use with caution). UnlimitedPolicy = &RateLimitPolicy{ ID: "unlimited", Name: "Unlimited", Description: "No rate limits - use for trusted internal services only", Enabled: true, Priority: 1000, Limits: RateLimits{}, } )
Predefined rate limit policies for common use cases.
var ( ErrPolicyNotFound = errors.New("policy not found") ErrPolicyExists = errors.New("policy already exists") ErrBindingNotFound = errors.New("client binding not found") )
Common errors returned by the policy store.
Functions ¶
This section is empty.
Types ¶
type ClientPolicyBinding ¶
type ClientPolicyBinding struct {
// ClientID is the OAuth 2.0 client_id.
ClientID string `json:"client_id"`
// PolicyID is the ID of the bound policy.
PolicyID string `json:"policy_id"`
// Enabled controls whether this binding is active.
Enabled bool `json:"enabled"`
// CreatedAt is when the binding was created.
CreatedAt time.Time `json:"created_at,omitzero"`
}
ClientPolicyBinding associates an OAuth client with a rate limit policy.
type MemoryPolicyStore ¶
type MemoryPolicyStore struct {
// contains filtered or unexported fields
}
MemoryPolicyStore is an in-memory implementation of PolicyStore. Suitable for development, testing, or single-instance deployments.
func NewMemoryPolicyStore ¶
func NewMemoryPolicyStore() *MemoryPolicyStore
NewMemoryPolicyStore creates a new in-memory policy store. It initializes with a default "standard" policy.
func NewMemoryPolicyStoreWithPolicies ¶
func NewMemoryPolicyStoreWithPolicies(policies []*RateLimitPolicy, defaultPolicyID string) *MemoryPolicyStore
NewMemoryPolicyStoreWithPolicies creates a store initialized with the given policies.
func (*MemoryPolicyStore) BindClientToPolicy ¶
func (s *MemoryPolicyStore) BindClientToPolicy(ctx context.Context, clientID, policyID string) error
BindClientToPolicy implements PolicyStore.
func (*MemoryPolicyStore) CreatePolicy ¶
func (s *MemoryPolicyStore) CreatePolicy(ctx context.Context, policy *RateLimitPolicy) error
CreatePolicy implements PolicyStore.
func (*MemoryPolicyStore) DeletePolicy ¶
func (s *MemoryPolicyStore) DeletePolicy(ctx context.Context, policyID string) error
DeletePolicy implements PolicyStore.
func (*MemoryPolicyStore) GetDefaultPolicy ¶
func (s *MemoryPolicyStore) GetDefaultPolicy(ctx context.Context) (*RateLimitPolicy, error)
GetDefaultPolicy implements PolicyStore.
func (*MemoryPolicyStore) GetPolicy ¶
func (s *MemoryPolicyStore) GetPolicy(ctx context.Context, policyID string) (*RateLimitPolicy, error)
GetPolicy implements PolicyStore.
func (*MemoryPolicyStore) GetPolicyForClient ¶
func (s *MemoryPolicyStore) GetPolicyForClient(ctx context.Context, clientID string) (*RateLimitPolicy, error)
GetPolicyForClient implements PolicyStore.
func (*MemoryPolicyStore) ListClientBindings ¶
func (s *MemoryPolicyStore) ListClientBindings(ctx context.Context) ([]*ClientPolicyBinding, error)
ListClientBindings implements PolicyStore.
func (*MemoryPolicyStore) ListClientsForPolicy ¶
func (s *MemoryPolicyStore) ListClientsForPolicy(ctx context.Context, policyID string) ([]string, error)
ListClientsForPolicy implements PolicyStore.
func (*MemoryPolicyStore) ListPolicies ¶
func (s *MemoryPolicyStore) ListPolicies(ctx context.Context) ([]*RateLimitPolicy, error)
ListPolicies implements PolicyStore.
func (*MemoryPolicyStore) SetDefaultPolicy ¶
func (s *MemoryPolicyStore) SetDefaultPolicy(ctx context.Context, policyID string) error
SetDefaultPolicy implements PolicyStore.
func (*MemoryPolicyStore) UnbindClient ¶
func (s *MemoryPolicyStore) UnbindClient(ctx context.Context, clientID string) error
UnbindClient implements PolicyStore.
func (*MemoryPolicyStore) UpdatePolicy ¶
func (s *MemoryPolicyStore) UpdatePolicy(ctx context.Context, policy *RateLimitPolicy) error
UpdatePolicy implements PolicyStore.
type PolicyStore ¶
type PolicyStore interface {
// Policy CRUD operations
GetPolicy(ctx context.Context, policyID string) (*RateLimitPolicy, error)
ListPolicies(ctx context.Context) ([]*RateLimitPolicy, error)
CreatePolicy(ctx context.Context, policy *RateLimitPolicy) error
UpdatePolicy(ctx context.Context, policy *RateLimitPolicy) error
DeletePolicy(ctx context.Context, policyID string) error
// Default policy
GetDefaultPolicy(ctx context.Context) (*RateLimitPolicy, error)
SetDefaultPolicy(ctx context.Context, policyID string) error
// Client bindings
GetPolicyForClient(ctx context.Context, clientID string) (*RateLimitPolicy, error)
BindClientToPolicy(ctx context.Context, clientID, policyID string) error
UnbindClient(ctx context.Context, clientID string) error
ListClientBindings(ctx context.Context) ([]*ClientPolicyBinding, error)
ListClientsForPolicy(ctx context.Context, policyID string) ([]string, error)
}
PolicyStore defines the interface for managing rate limit policies.
type RateLimitPolicy ¶
type RateLimitPolicy struct {
// ID is the unique identifier for this policy.
ID string `json:"id"`
// Name is a human-readable name for the policy.
Name string `json:"name"`
// Description explains the policy's purpose.
Description string `json:"description,omitempty"`
// Limits defines the rate limits for this policy.
Limits RateLimits `json:"limits"`
// EndpointOverrides allows different limits for specific endpoints.
// Keys are path prefixes (e.g., "/api/v1/uploads").
EndpointOverrides map[string]RateLimits `json:"endpoint_overrides,omitempty"`
// Priority determines precedence when multiple policies apply.
// Higher priority wins. Default is 0.
Priority int `json:"priority,omitempty"`
// Enabled controls whether the policy is active.
Enabled bool `json:"enabled"`
// Metadata holds arbitrary key-value data.
Metadata map[string]string `json:"metadata,omitempty"`
// CreatedAt is when the policy was created.
CreatedAt time.Time `json:"created_at,omitzero"`
// UpdatedAt is when the policy was last modified.
UpdatedAt time.Time `json:"updated_at,omitzero"`
}
RateLimitPolicy defines rate limits that can be applied to API clients.
func DefaultPolicies ¶
func DefaultPolicies() []*RateLimitPolicy
DefaultPolicies returns all predefined policies.
func (*RateLimitPolicy) WithEndpointOverride ¶
func (p *RateLimitPolicy) WithEndpointOverride(pathPrefix string, limits RateLimits) *RateLimitPolicy
WithEndpointOverride returns a copy of the policy with an endpoint override added.
type RateLimits ¶
type RateLimits struct {
// PerSecond is the maximum requests per second.
PerSecond int `json:"per_second,omitempty"`
// PerMinute is the maximum requests per minute.
PerMinute int `json:"per_minute,omitempty"`
// PerHour is the maximum requests per hour.
PerHour int `json:"per_hour,omitempty"`
// PerDay is the maximum requests per day.
PerDay int `json:"per_day,omitempty"`
// BurstSize is the maximum burst allowed.
// If zero, defaults to the most granular rate limit.
BurstSize int `json:"burst_size,omitempty"`
}
RateLimits defines rate limits across multiple time windows. Zero values mean no limit for that window.
func (RateLimits) IsUnlimited ¶
func (r RateLimits) IsUnlimited() bool
IsUnlimited returns true if no rate limits are configured.
func (RateLimits) MostGranularLimit ¶
func (r RateLimits) MostGranularLimit() (rate int, period time.Duration, burst int)
MostGranularLimit returns the most granular non-zero limit from RateLimits. Returns rate, period, and burst.
type UsageRecord ¶
type UsageRecord struct {
// ClientID is the OAuth client that made the requests.
ClientID string `json:"client_id"`
// PrincipalID is the user/principal if applicable.
PrincipalID string `json:"principal_id,omitempty"`
// Endpoint is the API endpoint (optional, for per-endpoint tracking).
Endpoint string `json:"endpoint,omitempty"`
// Period is the time period for this record.
Period time.Time `json:"period"`
// PeriodType is the granularity (minute, hour, day).
PeriodType string `json:"period_type"`
// RequestCount is the number of requests made.
RequestCount int64 `json:"request_count"`
// RateLimitedCount is requests that were rate limited.
RateLimitedCount int64 `json:"rate_limited_count"`
}
UsageRecord represents API usage for a client in a time period.
type UsageStore ¶
type UsageStore interface {
// RecordRequest increments the usage counter for a client.
RecordRequest(ctx context.Context, clientID, principalID, endpoint string, rateLimited bool) error
// GetUsage retrieves usage records for a client.
GetUsage(ctx context.Context, clientID string, from, to time.Time) ([]*UsageRecord, error)
// GetUsageSummary retrieves aggregated usage for a client.
GetUsageSummary(ctx context.Context, clientID string, periodType string, from, to time.Time) (*UsageSummary, error)
}
UsageStore defines the interface for tracking API usage.
type UsageSummary ¶
type UsageSummary struct {
ClientID string `json:"client_id"`
PeriodStart time.Time `json:"period_start"`
PeriodEnd time.Time `json:"period_end"`
TotalRequests int64 `json:"total_requests"`
RateLimitedCount int64 `json:"rate_limited_count"`
UniqueEndpoints int `json:"unique_endpoints"`
UniquePrincipals int `json:"unique_principals"`
}
UsageSummary provides aggregated usage statistics.