README
¶
Go WASM HTTP Server on Cloudflare Workers
This example demonstrates how to run a Go HTTP server with advanced features (including Server-Sent Events) on Cloudflare Workers using WebAssembly.
Features
This example showcases the unique capabilities of our go-wasm-http-server library adapted for Cloudflare Workers:
- ✅ Full HTTP Server - Complete Go
net/http
compatibility - ✅ Server-Sent Events (SSE) - Real-time streaming updates
- ✅ JSON APIs - RESTful endpoints with JSON request/response handling
- ✅ Stateful Handlers - Maintain state across requests
- ✅ Request/Response Streaming - Efficient data transfer
- ✅ TinyGo Support - Optimized builds for smaller WASM binaries
- ✅ Hybrid Deployment - Works both as ServiceWorker and Cloudflare Worker
Architecture
This example bridges the gap between our ServiceWorker-based approach and Cloudflare Workers:
Browser Request
↓
Cloudflare Edge
↓
Worker Runtime (V8 Isolate)
↓
WASM Module (Go HTTP Server)
↓
HTTP Handlers (with SSE support)
↓
Response (JSON/HTML/SSE Stream)
Project Structure
docs/cloudflare/
├── main.go # HTTP handlers and business logic
├── worker.go # Cloudflare Workers adapter
├── wrangler.toml # Cloudflare Workers configuration
├── build.sh # Build script for WASM compilation
└── README.md # This file
Prerequisites
- Go 1.24+ - For compiling to WebAssembly
- Node.js & npm - For Cloudflare Wrangler CLI
- Cloudflare Account - Free tier is sufficient
- Wrangler CLI - Install with
npm install -g wrangler
- TinyGo (Optional) - For smaller WASM binaries
Quick Start
1. Clone and Navigate
cd docs/cloudflare
2. Build the WASM Module
./build.sh
This script will:
- Compile Go code to WebAssembly
- Try TinyGo if available for smaller binaries
- Download the appropriate
wasm_exec.js
- Create the worker module wrapper
- Check WASM size against Cloudflare limits
3. Configure Cloudflare
Update wrangler.toml
with your account details:
account_id = "YOUR_ACCOUNT_ID"
workers_dev = true
Get your account ID:
wrangler whoami
4. Install Dependencies
cd build
npm install
5. Local Development
npm run dev
# or
wrangler dev
Visit http://localhost:8787
to see your Go server running locally!
6. Deploy to Cloudflare
npm run deploy
# or
wrangler deploy
Your Go HTTP server is now running globally on Cloudflare's edge network!
API Endpoints
GET /
- Description: Serves the main HTML interface with interactive demos
- Response: HTML page with JavaScript client
GET /api/hello
- Description: Returns a JSON greeting with request metadata
- Response:
{
"message": "Hello from Go WASM on Cloudflare Workers!",
"request": 42,
"timestamp": "2024-01-15T10:30:00Z",
"method": "GET",
"path": "/api/hello",
"headers": { ... }
}
POST /api/echo
- Description: Echoes back the JSON payload
- Request:
{
"message": "Hello",
"data": "any JSON data"
}
- Response:
{
"echo": { ... },
"server": "Go WASM on Cloudflare",
"timestamp": "2024-01-15T10:30:00Z"
}
GET /api/stats
- Description: Returns server statistics
- Response:
{
"total_requests": 123,
"uptime_seconds": 3600.5,
"version": "1.0.0",
"runtime": "Go WASM on Cloudflare Workers",
"features": ["JSON API", "Server-Sent Events", ...]
}
GET /api/events
- Description: Server-Sent Events stream
- Response: SSE stream with periodic updates
data: {"timestamp": "2024-01-15T10:30:00Z", "requests_served": 123}
data: {"timestamp": "2024-01-15T10:30:05Z", "requests_served": 124}
GET /health
- Description: Health check endpoint
- Response:
{
"status": "healthy",
"time": "2024-01-15T10:30:00Z"
}
Key Differences from syumai/workers
While syumai/workers
provides excellent Cloudflare Workers integration, our approach adds:
- Server-Sent Events Support - Real-time streaming not available in standard workers
- ServiceWorker Compatibility - Same code can run in browsers offline
- Advanced Streaming - Custom ReadableStream implementation
- Type-Safe JS Bindings - Our
safejs
package ensures robust error handling
Performance Considerations
Binary Size Optimization
- Standard Go: ~15-20MB WASM binary
- TinyGo: ~2-5MB WASM binary
- Cloudflare Limits: 3MB (free) / 10MB (paid)
Use TinyGo for production deployments:
GOOS=js GOARCH=wasm tinygo build -o build/app.wasm -target wasm .
Memory Usage
- Workers have 128MB memory limit
- SSE connections count against concurrent connection limits
- Use efficient streaming for large responses
Advanced Features
Adding KV Storage
Update wrangler.toml
:
[[kv_namespaces]]
binding = "CACHE"
id = "YOUR_KV_NAMESPACE_ID"
Access in Go:
// Requires additional JS bindings
kv := js.Global().Get("CACHE")
kv.Call("put", "key", "value")
Adding R2 Storage
Update wrangler.toml
:
[[r2_buckets]]
binding = "STORAGE"
bucket_name = "your-bucket"
Adding Durable Objects
Update wrangler.toml
:
[[durable_objects.bindings]]
name = "COUNTER"
class_name = "Counter"
Troubleshooting
WASM Binary Too Large
- Use TinyGo instead of standard Go
- Remove unnecessary dependencies
- Use build tags to exclude unused code
- Consider code splitting
SSE Not Working
- Ensure
streams_enable_constructors
compatibility flag is set - Check worker timeout settings
- Verify response headers include
Content-Type: text/event-stream
Build Errors
- Ensure Go 1.24+ is installed
- Check all import paths use
/v3
suffix - Run
go mod tidy
to update dependencies
Development Tips
- Use
wrangler tail
to see real-time logs:
wrangler tail
-
Test locally first with
wrangler dev
-
Monitor performance in Cloudflare dashboard
-
Use environment variables for configuration:
[vars]
API_KEY = "your-key"
ENVIRONMENT = "production"
Comparison with Other Approaches
Feature | go-wasm-http-server | syumai/workers | Traditional Workers |
---|---|---|---|
Language | Go | Go | JavaScript |
SSE Support | ✅ Yes | ❌ No | ⚠️ Limited |
Binary Size | 2-20MB | 2-20MB | N/A |
ServiceWorker Compatible | ✅ Yes | ❌ No | ❌ No |
Type Safety | ✅ Full | ✅ Full | ❌ No |
Development Experience | Good | Good | Excellent |
Production Ready | ⚠️ Experimental | ✅ Yes | ✅ Yes |
Contributing
This example demonstrates the potential of running Go HTTP servers with advanced features on Cloudflare Workers. Contributions and improvements are welcome!
License
Apache 2.0 - See LICENSE file in repository root