api

package
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2025 License: MIT Imports: 17 Imported by: 0

README

API Package

Build REST APIs and microservices with flexible middleware and functional configuration.

Features

  • Rate limiting - IP, token, and user-based rate limiting with configurable limits
  • CORS support - Simple CORS middleware for cross-origin requests
  • JWT enrichment - Extract and inject JWT claims into request context
  • Health endpoints - Built-in health and status endpoints
  • Functional configuration - Clean, composable configuration with functional options

Quick Start

package main

import (
    "net/http"
    
    "github.com/go-chi/chi/v5"
    "github.com/Okja-Engineering/go-service-kit/pkg/api"
)

func main() {
    router := chi.NewRouter()
    
    // Add rate limiting
    config := api.NewRateLimiterConfig(
        api.WithRequestsPerSecond(10.0),
        api.WithBurst(20),
    )
    router.Use(api.RateLimitByIP(config))
    
    // Add CORS
    router.Use(api.SimpleCORSMiddleware)
    
    // Add health endpoints
    api.AddHealthEndpoints(router)
    api.AddMetricsEndpoints(router)
    
    // Your routes
    router.Get("/api/users", handleGetUsers)
    
    http.ListenAndServe(":8080", router)
}

Rate Limiting

Configuration
// Create rate limiter config with functional options
config := api.NewRateLimiterConfig(
    api.WithRequestsPerSecond(5.0),    // 5 requests per second
    api.WithBurst(10),                 // Allow bursts of 10
    api.WithWindow(1 * time.Minute),   // 1-minute window
)
Rate Limiting Strategies
By IP Address
router.Use(api.RateLimitByIP(config))
By JWT Token
router.Use(api.RateLimitByToken(config))
By User ID
router.Use(api.RateLimitByUserID(config))
Rate Limit Headers

Responses include rate limit information:

  • X-RateLimit-Limit: Maximum requests per window
  • X-RateLimit-Remaining: Remaining requests
  • X-RateLimit-Reset: Reset time (RFC3339)

Middleware

CORS
router.Use(api.SimpleCORSMiddleware)
JWT Enrichment
// Extract user_id from JWT sub claim
router.Use(api.JWTRequestEnricher("user_id", "sub"))

Health Endpoints

// Add standard health and metrics endpoints
api.AddHealthEndpoints(router)
api.AddMetricsEndpoints(router)

API Reference

Rate Limiting
type RateLimiterConfig struct {
    RequestsPerSecond float64
    Burst             int
    Window            time.Duration
}

type RateLimitOption func(*RateLimiterConfig)

func NewRateLimiterConfig(options ...RateLimitOption) *RateLimiterConfig
func WithRequestsPerSecond(rps float64) RateLimitOption
func WithBurst(burst int) RateLimitOption
func WithWindow(window time.Duration) RateLimitOption
Middleware Functions
func RateLimitByIP(config *RateLimiterConfig) func(next http.Handler) http.Handler
func RateLimitByToken(config *RateLimiterConfig) func(next http.Handler) http.Handler
func RateLimitByUserID(config *RateLimiterConfig) func(next http.Handler) http.Handler
func SimpleCORSMiddleware(next http.Handler) http.Handler
func JWTRequestEnricher(fieldName string, claim string) func(next http.Handler) http.Handler
Endpoint Functions
func AddHealthEndpoints(router chi.Router)
func AddMetricsEndpoints(router chi.Router)

Examples

Complete Microservice Setup
package main

import (
    "net/http"
    "time"
    
    "github.com/go-chi/chi/v5"
    "github.com/Okja-Engineering/go-service-kit/pkg/api"
)

func main() {
    router := chi.NewRouter()
    
    // Configure rate limiting
    rateLimitConfig := api.NewRateLimiterConfig(
        api.WithRequestsPerSecond(100.0),
        api.WithBurst(200),
        api.WithWindow(1 * time.Minute),
    )
    
    // Add middleware
    router.Use(api.RateLimitByIP(rateLimitConfig))
    router.Use(api.SimpleCORSMiddleware)
    router.Use(api.JWTRequestEnricher("user_id", "sub"))
    
    // Add health endpoints
    api.AddHealthEndpoints(router)
    api.AddMetricsEndpoints(router)
    
    // API routes
    router.Route("/api/v1", func(r chi.Router) {
        r.Get("/users", handleGetUsers)
        r.Post("/users", handleCreateUser)
        r.Get("/users/{id}", handleGetUser)
    })
    
    http.ListenAndServe(":8080", router)
}
Custom Rate Limiting
// Different limits for different endpoints
publicConfig := api.NewRateLimiterConfig(
    api.WithRequestsPerSecond(50.0),
    api.WithBurst(100),
)

privateConfig := api.NewRateLimiterConfig(
    api.WithRequestsPerSecond(10.0),
    api.WithBurst(20),
)

// Public endpoints
router.Group(func(r chi.Router) {
    r.Use(api.RateLimitByIP(publicConfig))
    r.Get("/public/data", handlePublicData)
})

// Private endpoints
router.Group(func(r chi.Router) {
    r.Use(api.RateLimitByUserID(privateConfig))
    r.Get("/private/profile", handlePrivateProfile)
})

Best Practices

  1. Configure rate limits appropriately - Balance security with usability
  2. Use user-based limiting for authenticated endpoints - More precise than IP-based
  3. Add health endpoints - Essential for monitoring and load balancers
  4. Group related middleware - Apply different rate limits to different endpoint groups
  5. Monitor rate limit headers - Use them for client-side rate limiting

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Base

type Base struct {
	ServiceName string
	Healthy     bool
	Version     string
	BuildInfo   string
}

func NewBase

func NewBase(name, ver, info string, healthy bool) *Base

func (*Base) AddHealthEndpoint

func (b *Base) AddHealthEndpoint(r chi.Router, path string)

func (*Base) AddMetricsEndpoint

func (b *Base) AddMetricsEndpoint(r chi.Router, path string)

func (*Base) AddOKEndpoint

func (b *Base) AddOKEndpoint(r chi.Router, path string)

func (*Base) AddStatusEndpoint

func (b *Base) AddStatusEndpoint(r chi.Router, path string)

func (*Base) JWTRequestEnricher

func (b *Base) JWTRequestEnricher(fieldName string, claim string) func(next http.Handler) http.Handler

func (*Base) RateLimitByIP

func (b *Base) RateLimitByIP(config *RateLimiterConfig) func(next http.Handler) http.Handler

RateLimitByIP creates middleware that rate limits by IP address

func (*Base) RateLimitByToken

func (b *Base) RateLimitByToken(config *RateLimiterConfig) func(next http.Handler) http.Handler

RateLimitByToken creates middleware that rate limits by JWT token or API key

func (*Base) RateLimitByUserID

func (b *Base) RateLimitByUserID(config *RateLimiterConfig) func(next http.Handler) http.Handler

RateLimitByUserID creates middleware that rate limits by user ID from JWT

func (*Base) ReturnErrorJSON

func (b *Base) ReturnErrorJSON(w http.ResponseWriter, err error)

func (*Base) ReturnJSON

func (b *Base) ReturnJSON(w http.ResponseWriter, data interface{})

func (*Base) ReturnOKJSON

func (b *Base) ReturnOKJSON(w http.ResponseWriter)

func (*Base) ReturnText

func (b *Base) ReturnText(w http.ResponseWriter, msg string)

func (*Base) SimpleCORSMiddleware

func (b *Base) SimpleCORSMiddleware(next http.Handler) http.Handler

func (*Base) StartServer

func (b *Base) StartServer(port int, router chi.Router, timeout time.Duration)

type RateLimitOption added in v0.0.3

type RateLimitOption func(*RateLimiterConfig)

RateLimitOption is a functional option for configuring rate limiting

func WithBurst added in v0.0.3

func WithBurst(burst int) RateLimitOption

WithBurst sets the burst limit

func WithRequestsPerSecond added in v0.0.3

func WithRequestsPerSecond(rps float64) RateLimitOption

WithRequestsPerSecond sets the requests per second limit

func WithWindow added in v0.0.3

func WithWindow(window time.Duration) RateLimitOption

WithWindow sets the time window for rate limiting

type RateLimiterConfig

type RateLimiterConfig struct {
	RequestsPerSecond float64
	Burst             int
	Window            time.Duration
}

RateLimiterConfig holds configuration for rate limiting

func DefaultRateLimiterConfig

func DefaultRateLimiterConfig() *RateLimiterConfig

DefaultRateLimiterConfig provides sensible defaults

func NewRateLimiterConfig added in v0.0.3

func NewRateLimiterConfig(options ...RateLimitOption) *RateLimiterConfig

NewRateLimiterConfig creates a new rate limiter config with options

type Status

type Status struct {
	Service      string `json:"service"`
	Healthy      bool   `json:"healthy"`
	Version      string `json:"version"`
	BuildInfo    string `json:"buildInfo"`
	Hostname     string `json:"hostname"`
	OS           string `json:"os"`
	Architecture string `json:"architecture"`
	CPUCount     int    `json:"cpuCount"`
	GoVersion    string `json:"goVersion"`
	ClientAddr   string `json:"clientAddr"`
	ServerHost   string `json:"serverHost"`
	Uptime       string `json:"uptime"`
}

Jump to

Keyboard shortcuts

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