Servex eliminates HTTP server boilerplate in Go. Focus on business logic while getting production-ready features out of the box.
- 🚀 Zero Boilerplate - Configure once, code business logic
- đź”’ Security First - JWT auth, rate limiting, request filtering, security headers, audit logging
- 🔄 Reverse Proxy / API Gateway - Load balancing, health checks, traffic analysis
- ⚡ Native Compatibility - Works seamlessly with existing
net/httpcode
go get -u github.com/maxbolgarin/servex/v2server, _ := servex.New(servex.ProductionPreset()...)
server.HandleFunc("/hello", helloHandler)
server.StartWithWaitSignals(context.Background(), ":8080", "")func handler(w http.ResponseWriter, r *http.Request) {
ctx := servex.C(w, r)
request, err := servex.ReadJSON[Request](r)
if err != nil {
ctx.BadRequest(err, "invalid request")
return
}
ctx.Response(http.StatusOK, response)
}Quick configurations for common scenarios:
| Preset | Use Case |
|---|---|
DevelopmentPreset() |
Development with minimal setup |
ProductionPreset() |
Production with security, rate limiting, monitoring |
APIServerPreset() |
REST APIs |
WebAppPreset() |
Web applications with security headers |
MicroservicePreset() |
Fast timeouts, minimal security |
HighSecurityPreset() |
Maximum security features |
QuickTLSPreset(cert, key) |
Production + SSL |
| Feature | Configuration Options |
|---|---|
| Authentication | WithAuth(config) - Full JWT auth with databaseWithAuthToken(token) - Simple bearer tokenWithAuthMemoryDatabase() - In-memory user storageWithAuthKey(accessKey, refreshKey) - Custom JWT keysWithAuthTokensDuration(access, refresh) - Token lifetimesWithAuthIssuer(issuer) - JWT issuerWithAuthBasePath(path) - Auth routes prefixWithAuthInitialRoles(roles...) - Default user roles |
| Rate Limiting | WithRPM(requests) - Requests per minuteWithRPS(requests) - Requests per secondWithRequestsPerInterval(requests, interval) - Custom intervalWithBurstSize(size) - Burst allowanceWithRateLimitConfig(config) - Full configurationWithRateLimitExcludePaths(paths...) - Exclude pathsWithRateLimitIncludePaths(paths...) - Include only paths |
| Request Filtering | WithBlockedIPs(ips...) - Block IP rangesWithAllowedIPs(ips...) - Allow only IPsWithBlockedUserAgents(agents...) - Block user agentsWithBlockedUserAgentsRegex(patterns...) - Block by regexWithAllowedHeaders(headers) - Allow headersWithBlockedHeaders(headers) - Block headersWithAllowedQueryParams(params) - Allow query paramsWithBlockedQueryParams(params) - Block query paramsWithFilterConfig(config) - Full configuration |
| Security Headers | WithSecurityHeaders() - Basic headersWithStrictSecurityHeaders() - Strict CSP, HSTSWithContentSecurityPolicy(policy) - Custom CSPWithHSTSHeader(maxAge, includeSubdomains, preload) - HSTS configWithSecurityConfig(config) - Full configuration |
| CSRF Protection | WithCSRFProtection() - Enable CSRFWithCSRFTokenName(name) - Token header nameWithCSRFCookieName(name) - Cookie nameWithCSRFCookieHttpOnly(httpOnly) - HttpOnly flagWithCSRFCookieSecure(secure) - Secure flagWithCSRFTokenEndpoint(endpoint) - Token endpoint |
| CORS | WithCORS() - Enable with defaultsWithCORSAllowOrigins(origins...) - Allowed originsWithCORSAllowMethods(methods...) - Allowed methodsWithCORSAllowHeaders(headers...) - Allowed headersWithCORSAllowCredentials() - Allow credentialsWithCORSMaxAge(seconds) - Preflight cacheWithCORSConfig(config) - Full configuration |
| Compression | WithCompression() - Enable gzipWithCompressionLevel(level) - Level 1-9WithCompressionMinSize(size) - Min size to compressWithCompressionTypes(types...) - Content typesWithCompressionConfig(config) - Full configuration |
| Caching | WithCachePublic(maxAge) - Public cacheWithCachePrivate(maxAge) - Private cacheWithCacheStaticAssets(maxAge) - Static file cacheWithCacheNoCache() - Disable cachingWithCacheControl(control) - Custom Cache-ControlWithCacheConfig(config) - Full configuration |
| Static Files / SPA | WithStaticFiles(dir, prefix) - Serve static filesWithSPAMode(dir, indexFile) - SPA modeWithStaticFileConfig(config) - Full configurationWithStaticFileCache(maxAge, rules...) - Cache rules |
| Reverse Proxy | WithProxyConfig(config) - Full proxy configurationSupports load balancing, health checks, path rewriting |
| HTTPS / TLS | WithCertificate(cert) - TLS certificateWithCertificateFromFile(cert, key) - Load from filesWithHTTPSRedirect() - Redirect HTTP to HTTPSWithHTTPSRedirectTemporary() - 307 redirectWithHTTPSRedirectConfig(config) - Full redirect config |
| Logging & Monitoring | WithLogger(logger) - Custom loggerWithDefaultAuditLogger() - Security audit logsWithAuditLogger(logger) - Custom audit loggerWithDisableRequestLogging() - Disable request logsWithNoLogClientErrors() - Skip 4xx errorsWithLogFields(fields...) - Additional log fields |
| Health & Metrics | WithHealthEndpoint() - Enable /healthWithHealthPath(path) - Custom health pathWithDefaultMetrics(path) - Prometheus metricsWithMetrics(metrics) - Custom metricsWithDisableHealthEndpoint() - Disable health |
| Server Timeouts | WithReadTimeout(duration) - Request read timeoutWithReadHeaderTimeout(duration) - Header read timeoutWithIdleTimeout(duration) - Keep-alive timeoutWithMaxHeaderBytes(size) - Max header size |
| Request Size Limits | WithMaxRequestBodySize(size) - Max body sizeWithMaxJSONBodySize(size) - Max JSON sizeWithMaxFileUploadSize(size) - Max file sizeWithMaxMultipartMemory(size) - Multipart memoryWithRequestSizeLimits() - Enable defaultsWithStrictRequestSizeLimits() - Strict limits |
Built-in JWT authentication with user management:
server, _ := servex.New(
servex.WithAuth(servex.AuthConfig{
Database: authDB,
RolesOnRegister: []servex.UserRole{"user"},
AccessTokenDuration: 15 * time.Minute,
}),
)
// Auto-registers: /auth/login, /auth/register, /auth/refresh, /auth/logout
server.HandleFuncWithAuth("/admin", adminHandler, "admin")Protect all your APIs:
server, _ := servex.New(servex.WithRPM(100)) // 100 requests per minuteOr per-endpoint limits via register after server creation:
locationConfigs := []servex.LocationRateLimitConfig{
{
PathPatterns: []string{"/auth/login"},
Config: servex.RateLimitConfig{
RequestsPerInterval: 5,
Interval: time.Minute,
},
},
}
servex.RegisterLocationBasedRateLimitMiddleware(server.Router(), locationConfigs)Block malicious traffic:
server, _ := servex.New(
servex.WithBlockedIPs("192.0.2.0/24"),
servex.WithBlockedUserAgentsRegex(`(?i).*(bot|crawler).*`),
)L7 reverse proxy with load balancing:
proxyConfig := servex.ProxyConfiguration{
Enabled: true,
Rules: []servex.ProxyRule{
{
PathPrefix: "/api/",
Backends: []servex.Backend{
{URL: "http://backend1:8080", Weight: 2},
{URL: "http://backend2:8080", Weight: 1},
},
LoadBalancing: servex.WeightedRoundRobinStrategy,
StripPrefix: "/api",
},
},
}
server, _ := servex.New(servex.WithProxyConfig(proxyConfig))server, _ := servex.New(
servex.WithStrictSecurityHeaders(), // CSP, HSTS, etc.
servex.WithCSRFProtection(),
)Track security events:
server, _ := servex.New(
servex.WithDefaultAuditLogger(),
servex.WithAuth(authConfig),
)
// Logs: auth events, rate limits, filter blocks, CSRF violationsctx := servex.C(w, r)
// Request
requestID := ctx.RequestID()
apiVersion := ctx.APIVersion() // Extracts 'v1' from /api/v1/...
userID := ctx.Path("id") // Path parameter
sort := ctx.Query("sort") // Query parameter
user, _ := servex.ReadJSON[User](r)
// Response
ctx.Response(http.StatusOK, data)
ctx.BadRequest(err, "invalid input")
ctx.NotFound(err, "not found")
ctx.InternalServerError(err, "error")
// Cookies
cookie, _ := ctx.Cookie("session")
ctx.SetCookie("session", "token", 3600, true, true)Servex provides 100+ options via With... pattern:
server, _ := servex.New(
// Server
servex.WithReadTimeout(30*time.Second),
servex.WithLogger(slog.Default()),
// Security
servex.WithStrictSecurityHeaders(),
servex.WithRPM(1000),
servex.WithBlockedIPs("10.0.0.0/8"),
// Features
servex.WithHealthEndpoint(),
servex.WithDefaultMetrics(),
servex.WithCompression(),
servex.WithCORS(),
// Static Files / SPA
servex.WithSPAMode("build", "index.html"),
)See Complete Configuration Reference for all options.
server.GET("/users", listUsers)
server.POST("/users", createUser)
server.PUT("/users/{id}", updateUser)
server.DELETE("/users/{id}", deleteUser)
// With authentication
server.GetWithAuth("/admin", adminHandler, "admin")
server.PostWithAuth("/api/data", dataHandler, "user")// 1. Basic start (non-blocking)
server.Start(":8080", ":8443")
// 2. With automatic shutdown on context cancel
server.StartWithShutdown(ctx, ":8080", "")
// 3. Wait for signals (Ctrl+C) - blocking
server.StartWithWaitSignals(ctx, ":8080", "")
// 4. Separate HTTP/HTTPS
server.StartHTTP(":8080")
server.StartHTTPS(":8443")View all configuration options (100+)
WithCertificate(cert)- Set TLS certificateWithCertificateFromFile(cert, key)- Load from files
WithReadTimeout(duration)- Request read timeoutWithIdleTimeout(duration)- Keep-alive timeout
WithAuth(config)- JWT authenticationWithAuthMemoryDatabase()- In-memory user databaseWithAuthToken(token)- Simple bearer tokenWithAuthTokensDuration(access, refresh)- Token lifetimes
WithRPM(requests)- Requests per minuteWithRPS(requests)- Requests per secondWithBurstSize(size)- Burst allowanceWithRateLimitKeyFunc(func)- Custom rate limit key
WithBlockedIPs(ips...)- Block IP rangesWithAllowedIPs(ips...)- Allow only specific IPsWithBlockedUserAgents(agents...)- Block user agentsWithBlockedUserAgentsRegex(patterns...)- Block by regex
WithSecurityHeaders()- Basic security headersWithStrictSecurityHeaders()- Strict CSP, HSTSWithCSRFProtection()- CSRF token validationWithContentSecurityPolicy(policy)- Custom CSP
WithCORS()- Enable with defaultsWithCORSAllowOrigins(origins...)- Allowed originsWithCORSAllowMethods(methods...)- Allowed methodsWithCORSAllowCredentials()- Allow credentials
WithCachePublic(maxAge)- Public cacheWithCachePrivate(maxAge)- Private cacheWithCacheStaticAssets(maxAge)- Cache static filesWithCacheNoCache()- Disable caching
WithLogger(logger)- Custom loggerWithDefaultAuditLogger()- Security audit loggingWithHealthEndpoint()- Health check endpointWithDefaultMetrics()- Prometheus metrics
WithCompression()- Gzip compressionWithCompressionLevel(level)- Compression level (1-9)WithMaxRequestBodySize(size)- Limit request size
WithStaticFiles(dir, prefix)- Serve static filesWithSPAMode(dir, index)- Single Page Application mode
WithProxyConfig(config)- Complete proxy configuration
func handler(w http.ResponseWriter, r *http.Request) {
bodyBytes, _ := io.ReadAll(r.Body)
var request Request
json.Unmarshal(bodyBytes, &request)
respBytes, _ := json.Marshal(resp)
w.Header().Set("Content-Type", "application/json")
w.Write(respBytes)
}func handler(w http.ResponseWriter, r *http.Request) {
ctx := servex.C(w, r)
request, _ := servex.ReadJSON[Request](r)
ctx.Response(http.StatusOK, resp)
}See examples/ for complete working examples:
- Basic server
- Authentication
- Rate limiting
- Reverse proxy
- SPA serving
Pull requests and issues welcome! See LICENSE for terms.
MIT License - see LICENSE file.