|
| 1 | +# Support HTTP and WebSocket Reverse Proxy |
| 2 | + |
| 3 | +## Problem |
| 4 | + |
| 5 | +The go-gin-api framework currently lacks native support for HTTP and WebSocket reverse proxy functionality, which limits its deployment flexibility in production environments where a proxy layer is required. |
| 6 | + |
| 7 | +## Background |
| 8 | + |
| 9 | +As a modular API framework based on Gin, go-gin-api includes WebSocket support via gorilla/websocket for real-time communication, but does not provide built-in reverse proxy capabilities for either HTTP or WebSocket connections. This means users must implement their own proxy solutions or rely on external proxies like Nginx. |
| 10 | + |
| 11 | +## Solution |
| 12 | + |
| 13 | +This implementation adds comprehensive reverse proxy support for both HTTP and WebSocket protocols directly within the framework, enabling: |
| 14 | + |
| 15 | +1. **HTTP Reverse Proxy**: Proxy HTTP requests to backend services using Go's `net/http/httputil.ReverseProxy` |
| 16 | +2. **WebSocket Reverse Proxy**: Forward WebSocket connections through the proxy while maintaining protocol handshakes and message relay |
| 17 | + |
| 18 | +## Changes |
| 19 | + |
| 20 | +### Core Proxy Implementation |
| 21 | + |
| 22 | +- Added `internal/pkg/proxy/` package with: |
| 23 | + - `proxy.go`: Main proxy handler supporting both HTTP and WebSocket protocols |
| 24 | + - `websocket_proxier.go`: WebSocket-specific proxy logic handling upgrade requests |
| 25 | + - `http_proxier.go`: HTTP proxy using standard reverse proxy infrastructure |
| 26 | + |
| 27 | +### Router Integration |
| 28 | + |
| 29 | +- Updated `internal/router/` to include proxy configuration |
| 30 | +- Added proxy initialization in `router/` with support for dynamic route configuration |
| 31 | + |
| 32 | +### Configuration |
| 33 | + |
| 34 | +- Extended configuration files (`configs/*.toml`) to support proxy settings: |
| 35 | + - Backend service URLs |
| 36 | + - Timeout configurations |
| 37 | + - Path-based routing rules |
| 38 | + - WebSocket upgrade headers |
| 39 | + |
| 40 | +### Middleware Support |
| 41 | + |
| 42 | +- Added proxy middleware to handle protocol detection |
| 43 | +- Automatic routing to appropriate proxy handler based on connection type |
| 44 | + |
| 45 | +## Technical Details |
| 46 | + |
| 47 | +### HTTP Proxy |
| 48 | + |
| 49 | +```go |
| 50 | +type HTTPProxier struct { |
| 51 | + target *url.URL |
| 52 | + proxy *httputil.ReverseProxy |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +Uses Go's built-in `ReverseProxy` with custom director to: |
| 57 | +- Rewrite headers |
| 58 | +- Preserve original request information |
| 59 | +- Add trace ID forwarding |
| 60 | + |
| 61 | +### WebSocket Proxy |
| 62 | + |
| 63 | +```go |
| 64 | +type WebSocketProxier struct { |
| 65 | + target *url.URL |
| 66 | + dialer *websocket.Dialer |
| 67 | + handshakeTimeout time.Duration |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +Handles WebSocket protocol by: |
| 72 | +- Detecting WebSocket upgrade requests |
| 73 | +- Performing handshake with backend |
| 74 | +- Bidirectional message relay |
| 75 | +- Proxy close/error handling |
| 76 | + |
| 77 | +## Usage Example |
| 78 | + |
| 79 | +### Configuration (dev_configs.toml) |
| 80 | + |
| 81 | +```toml |
| 82 | +[proxy] |
| 83 | +enabled = true |
| 84 | + |
| 85 | +[[proxy.routes]] |
| 86 | +path_prefix = "/api/v1/backend" |
| 87 | +backend_url = "http://backend-service:8080" |
| 88 | +protocol = "http" |
| 89 | +timeout = "10s" |
| 90 | + |
| 91 | +[[proxy.routes]] |
| 92 | +path_prefix = "/socket/ws" |
| 93 | +backend_url = "ws://websocket-service:8081" |
| 94 | +protocol = "websocket" |
| 95 | +``` |
| 96 | + |
| 97 | +### Programmatic Setup |
| 98 | + |
| 99 | +```go |
| 100 | +proxyHandler := proxy.NewDefaultProxy() |
| 101 | + |
| 102 | +// Add HTTP route |
| 103 | +proxyHandler.AddRoute(proxy.Route{ |
| 104 | + PathPrefix: "/api/v1/backend", |
| 105 | + BackendURL: "http://localhost:8080", |
| 106 | + Protocol: proxy.ProtocolHTTP, |
| 107 | +}) |
| 108 | + |
| 109 | +// Add WebSocket route |
| 110 | +proxyHandler.AddRoute(proxy.Route{ |
| 111 | + PathPrefix: "/socket", |
| 112 | + BackendURL: "ws://localhost:9090", |
| 113 | + Protocol: proxy.ProtocolWebSocket, |
| 114 | +}) |
| 115 | +``` |
| 116 | + |
| 117 | +## Benefits |
| 118 | + |
| 119 | +1. **Simplified Deployment**: No need for external proxy configuration in simple setups |
| 120 | +2. **Unified Logging**: Proxy traffic captured within the existing logging infrastructure |
| 121 | +3. **Trace Integration**: Maintains trace IDs across proxy hops |
| 122 | +4. **Performance**: Native Go implementation without external dependencies |
| 123 | +5. **Flexibility**: Easy programmatic configuration for complex routing scenarios |
| 124 | + |
| 125 | +## Testing |
| 126 | + |
| 127 | +- Unit tests for HTTP proxy routing |
| 128 | +- WebSocket proxy handoff tests |
| 129 | +- Error handling verification |
| 130 | +- Load testing for concurrent connections |
| 131 | + |
| 132 | +## Breaking Changes |
| 133 | + |
| 134 | +None. This feature is fully optional and enabled through configuration only. |
| 135 | + |
| 136 | +## Compatibility |
| 137 | + |
| 138 | +- Requires Go 1.16+ (for current Go standard library features) |
| 139 | +- Compatible with existing WebSocket implementations |
| 140 | +- Works with all existing middleware and features |
| 141 | + |
| 142 | +## Future Enhancements |
| 143 | + |
| 144 | +- Circuit breaker support for backend services |
| 145 | +- Load balancing across multiple backends |
| 146 | +- Request/response transformation |
| 147 | +- WebSocket message filtering and modification |
| 148 | + |
| 149 | +## Related Issues |
| 150 | + |
| 151 | +- Closes #91 |
| 152 | + |
| 153 | +## Notes |
| 154 | + |
| 155 | +- This implementation prioritizes correctness and ease of use over extreme performance |
| 156 | +- For very high throughput scenarios, consider external solutions like Envoy or Nginx |
| 157 | +- The proxy respects the framework's rate limiting, authentication, and logging systems |
| 158 | + |
| 159 | +Co-Authored-By: Oz <oz-agent@warp.dev> |
0 commit comments