Service Weaver is a programming framework for writing and deploying cloud applications.
Read the DocsSplit your application into components written as regular Go interfaces. Don't fuss with any networking or serialization code. Focus on your business logic.
type Adder interface {
Add(context.Context, int, int) (int, error)
}
type adder struct {
weaver.Implements[Adder]
}
func (adder) Add(_ context.Context, x, y int) (int, error) {
return x + y, nil
}
Call your components using regular Go method calls. No need for RPCs or HTTP requests. Forget about versioning issues. The type system guarantees components are compatible.
var adder Adder = ... // See documentation
sum, err := adder.Add(ctx, 1, 2)
Test your app locally and deploy it to the cloud. Service Weaver lets you think about what your code does without worrying about where it's running.
$ go test . # Test locally.
$ go run . # Run locally.
$ weaver ssh deploy weaver.toml # Run on multiple machines.
$ weaver gke deploy weaver.toml # Run on Google Cloud.
$ weaver kube deploy weaver.toml # Run on Kubernetes.
Run your components wherever you want: in the same process or on different machines. Run as many replicas as you want; scale up or down to match load.
Co-located components communicate via direct method call. Remote components communicate using highly-efficient custom serialization and RPC protocols.
// Automatically encoded and decoded.
type pair struct {
weaver.AutoMarshal
x, y int32
}
Deploy to the cloud without tons of boilerplate configuration. Here's a working config file to deploy a Service Weaver application across two regions in Google Cloud. It's less than ten lines long.
[serviceweaver]
binary = "./example"
[gke]
regions = ["us-west1", "us-east1"]
listeners.example = {is_public = true, hostname = "example.com"},
Service Weaver has libraries for logging, metrics, and tracing. This telemetry is automatically integrated into the cloud where you deploy.
var count = metrics.NewCounter(
"example_count",
"An example of a Service Weaver counter",
)
func main() {
count.Add(1)
// ...
}
Shard requests across different component replicas.
type Cache interface {
Get(ctx context.Context, key string) (string, error)
Put(ctx context.Context, key, val string) error
}
// router defines how Cache methods are routed.
type router struct{}
func (router) Get(_ context.Context, k string) string {
return k
}
func (router) Put(_ context.Context, k, _ string) string {
return k
}