Quickstart
This guide walks through creating two nodes: a provider that exposes a service, and a consumer that calls it.
Installation
go get github.com/zoobz-io/aegis
Requires Go 1.24+.
Basic Usage
A minimal node with automatic certificate generation:
package main
import "github.com/zoobz-io/aegis"
func main() {
node, err := aegis.NewNodeBuilder().
WithID("my-node").
WithName("My Node").
WithAddress("localhost:8443").
WithCertDir("./certs").
Build()
if err != nil {
panic(err)
}
node.StartServer()
defer node.Shutdown()
// Node is now accepting mTLS connections
select {}
}
On first run, aegis generates a CA and node certificate in ./certs. Subsequent runs load existing certificates.
Declaring Services
Nodes can declare which services they provide:
node, _ := aegis.NewNodeBuilder().
WithID("identity-1").
WithName("Identity Server").
WithAddress("localhost:8443").
WithServices(aegis.ServiceInfo{Name: "identity", Version: "v1"}).
WithCertDir("./certs").
Build()
Other nodes can then query for providers:
providers := node.Topology.GetServiceProviders("identity", "v1")
// Returns []NodeInfo with addresses of nodes providing identity.v1
See the Services Guide for registering gRPC service implementations.
Connecting to Peers
Add peers to enable topology synchronization:
err := node.AddPeer(aegis.PeerInfo{
ID: "other-node",
Type: aegis.NodeTypeGeneric,
Address: "other-host:8443",
})
Peers connect using mTLS. Once connected, topology syncs automatically.
Calling Services
Use ServiceClientPool to call services across the mesh:
pool := aegis.NewServiceClientPool(node)
defer pool.Close()
// Create typed client for a specific service
client := aegis.NewServiceClient(pool, "identity", "v1", identity.NewIdentityServiceClient)
// Get connection (round-robin across providers)
identityClient, err := client.Get(ctx)
if err != nil {
return err
}
resp, err := identityClient.ValidateSession(ctx, &identity.ValidateSessionRequest{
Token: token,
})
See Service Client for connection pooling details.
Health Checks
Nodes track their health status:
// Set health directly
node.SetHealth(aegis.HealthStatusHealthy, "All systems operational", nil)
// Or use a health checker
checker := aegis.NewFunctionHealthChecker("database", func(ctx context.Context) error {
return db.Ping(ctx)
})
node.CheckHealth(ctx, checker)
Next Steps
- Concepts — Mental models for nodes, peers, and topology
- Architecture — How mTLS and topology sync work internally
- Services Guide — Registering domain services