# README
service
The intention behind the service package is to allow a client to get a service up and running by passing in a configuration struct.
Supported features
- readiness handler (can be required by k8s)
- CORS - default configuration if enabled or supplied override configuration
- Logging.
- The default prometheus metrics endpoint.
- Listening on HTTP or HTTPS.
- Rate limiting.
- Adding new handlers.
- Adding new middleware.
- Adding an auth handler.
API
//NewService will setup a new service based on the config and return this service.
func NewService(cfg *Config) (*Service, error)
//Run will run the service in the foreground and exit when the HTTP server exits
func (s *Service) Run() error
Types
//Config will hold the configuration of the service.
type Config struct {
ListenAddress string //Address in the format [host/ip]:port. Mandatory
LogLevel string //INFO,FATAL,ERROR,WARN, DEBUG, TRACE
Cors *CorsConfig //Optional cors config
ReadinessCheck bool //Set to true to add a readiness handler at /readiness.
Handlers []Handler //Array of handlers. N.B. At least one handler is required.
CertConfig *ServerCertificateConfig //Optional TLS configuration
RateLimit *RateLimitConfig //Optional rate limiting config
MiddlewareHandlers []MiddlewareHandler //Optional middleware handlers which will be run on every request
Metrics bool //Optional. If true a prometheus metrics endpoint will be exposed at /metrics/
ErrorHandler *MiddlewareHandler //Optional. If true a handler will be added to the end of the chain.
}
// Handler will hold all the callback handlers to be registered. N.B. gin will be used.
type Handler struct {
Method string // HTTP method or service.AnyMethod to support all limits.
Path string // The path the endpoint runs on.
Group string // Optional - specify a group (used to control which middlewares will run)
Handler func(c *gin.Context) // The handler to be used.
RateLimitConfig *HandlerRateLimitConfig // Optional rate limiting config specifically for the handler.
}
//MiddlewareHandler will hold all the middleware and whether
type MiddlewareHandler struct {
Groups []string //Optional - what group should this middleware run on. Empty means the default route.
Handler func(c *gin.Context) //The handler to be used.
}
//ServerCertificateConfig holds detail of the certificate config to be used
type ServerCertificateConfig struct {
CertificateFile string //The TLS certificate file.
KeyFile string //The TLS private key file.
}
//RateLimitConfig specifies the rate limiting config
type RateLimitConfig struct {
Groups []string //Optional - which group(s) should the rate limiting run on. Empty means the default route.
Limit int //The number of requests allowed within the timeframe.
Within int //The timeframe(seconds) the requests are allowed in.
}
//CorsConfig specifies the CORS related config
type CorsConfig struct {
Groups []string //Optional - which group(s) should the CORS config run on. Empty means the default route.
Enabled bool //Whether CORS is enabled or not.
OverrideCfg *cors.Config //Optional. This is only required if you do not want to use the default CORS configuration.
}
// HandlerRateLimitConfig holds the rate limiting config fo a sepecific handler.
type HandlerRateLimitConfig struct {
Limit int // The number of requests allowed within the timeframe.
Within int // The timeframe(seconds) the requests are allowed in.
}
//Service will be the actual structure returned.
type Service struct {
*http.Server //Anonymous embedded struct to allow access to http server methods.
config *Config //The config.
}
Notes
- The cors config and the handlers are based on the gin framework : https://github.com/gin-gonic/gin.
- Rate limiting is done by the library github.com/cnjack/throttle.
- Rate limiting can be added to a handler or on a per group basis.
- The group principle is based on Gin routergroups. The idea behind it is that not all middleware needs to run on all requests so the middleware in a group will only run against an endpoint in that group. This is applied to cors, rate limiting and any middleware in general.
- See internal/examples/service/main.go for an example of how to use the service package to generate a service.
TODO: - Consider adding GRPC.
- Consider adding GraphQL.
- Flesh out more with logging.
- Look at potentially not using gin (it does the work for you so not a high priority).
# Functions
NewService will setup a new service based on the config and return this service.
# Constants
AnyMethod should be passed when a handler wants to support any HTTP method.
ReadinessEndpoint is the default URL for a readiness endpoint.
# Structs
Config will hold the configuration of the service.
CorsConfig specifies the CORS related config.
Handler will hold all the callback handlers to be registered.
HandlerRateLimitConfig holds the rate limiting config fo a sepecific handler.
MiddlewareHandler will hold a middleware handler and the groups on which it should be registered.
RateLimitConfig specifies the rate limiting config.
ServerCertificateConfig holds detail of the certificate config to be used.
Service will be the actual structure returned.