zoobzio February 17, 2025 Edit this page

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