Skip to main content
The Registry API provides interfaces for service registration and discovery, enabling dynamic service-to-service communication.

Interfaces

Registrar

Service registrar interface for registering and deregistering services.
type Registrar interface {
    Register(ctx context.Context, service *ServiceInstance) error
    Deregister(ctx context.Context, service *ServiceInstance) error
}
Register
func(ctx context.Context, service *ServiceInstance) error
Registers a service instance with the registry
Deregister
func(ctx context.Context, service *ServiceInstance) error
Deregisters a service instance from the registry

Discovery

Service discovery interface for finding services.
type Discovery interface {
    GetService(ctx context.Context, serviceName string) ([]*ServiceInstance, error)
    Watch(ctx context.Context, serviceName string) (Watcher, error)
}
GetService
func(ctx context.Context, serviceName string) ([]*ServiceInstance, error)
Returns all service instances for the given service name from memory
Watch
func(ctx context.Context, serviceName string) (Watcher, error)
Creates a watcher for monitoring service changes

Watcher

Service watcher interface for monitoring service changes.
type Watcher interface {
    Next() ([]*ServiceInstance, error)
    Stop() error
}
Next
func() ([]*ServiceInstance, error)
Returns services in two cases:
  1. The first time watching and the service instance list is not empty
  2. Any service instance changes are detected
Blocks until a change occurs or context is canceled.
Stop
func() error
Closes the watcher and releases resources

Types

ServiceInstance

Represents a service instance in the registry.
type ServiceInstance struct {
    ID        string            `json:"id"`
    Name      string            `json:"name"`
    Version   string            `json:"version"`
    Metadata  map[string]string `json:"metadata"`
    Endpoints []string          `json:"endpoints"`
}
ID
string
Unique instance ID as registered
Name
string
Service name as registered
Version
string
Version of the compiled service
Metadata
map[string]string
Key-value pair metadata associated with the service instance
Endpoints
[]string
Endpoint addresses of the service instance. Schema examples:
  • http://127.0.0.1:8000?isSecure=false
  • grpc://127.0.0.1:9000?isSecure=false
Methods:
func (i *ServiceInstance) String() string
func (i *ServiceInstance) Equal(o any) bool

Usage Examples

Registering a Service

package main

import (
    "context"
    "github.com/go-kratos/kratos/v2"
    "github.com/go-kratos/kratos/v2/registry"
)

func main() {
    // Create registrar (e.g., Consul, Etcd, Nacos)
    r := consul.New(consulClient)
    
    app := kratos.New(
        kratos.ID("service-001"),
        kratos.Name("user-service"),
        kratos.Version("v1.0.0"),
        kratos.Metadata(map[string]string{
            "region": "us-west",
            "zone":   "zone-a",
        }),
        kratos.Server(httpSrv, grpcSrv),
        kratos.Registrar(r),
    )
    
    if err := app.Run(); err != nil {
        panic(err)
    }
}

Service Discovery

package main

import (
    "context"
    "fmt"
    "github.com/go-kratos/kratos/v2/registry"
)

func discoverService(discovery registry.Discovery, serviceName string) {
    ctx := context.Background()
    
    // Get service instances
    instances, err := discovery.GetService(ctx, serviceName)
    if err != nil {
        panic(err)
    }
    
    for _, inst := range instances {
        fmt.Printf("Found instance: %s\n", inst.ID)
        fmt.Printf("  Name: %s\n", inst.Name)
        fmt.Printf("  Version: %s\n", inst.Version)
        fmt.Printf("  Endpoints: %v\n", inst.Endpoints)
        fmt.Printf("  Metadata: %v\n", inst.Metadata)
    }
}

Watching Service Changes

func watchService(discovery registry.Discovery, serviceName string) {
    ctx := context.Background()
    
    watcher, err := discovery.Watch(ctx, serviceName)
    if err != nil {
        panic(err)
    }
    defer watcher.Stop()
    
    for {
        instances, err := watcher.Next()
        if err != nil {
            fmt.Printf("Watch error: %v\n", err)
            return
        }
        
        fmt.Printf("Service %s updated: %d instances\n", serviceName, len(instances))
        for _, inst := range instances {
            fmt.Printf("  - %s: %v\n", inst.ID, inst.Endpoints)
        }
    }
}

Custom Service Instance

func createServiceInstance() *registry.ServiceInstance {
    return &registry.ServiceInstance{
        ID:      "user-service-001",
        Name:    "user-service",
        Version: "v1.0.0",
        Metadata: map[string]string{
            "region":    "us-west",
            "zone":      "zone-a",
            "weight":    "100",
            "protocol":  "grpc",
            "namespace": "production",
        },
        Endpoints: []string{
            "grpc://192.168.1.10:9000?isSecure=false",
            "http://192.168.1.10:8000?isSecure=false",
        },
    }
}

Service Instance Comparison

func compareInstances(inst1, inst2 *registry.ServiceInstance) {
    if inst1.Equal(inst2) {
        fmt.Println("Instances are equal")
    } else {
        fmt.Println("Instances differ")
    }
    
    // String representation
    fmt.Printf("Instance: %s\n", inst1.String()) // Output: user-service-001
}

Integration with gRPC Client

import (
    "github.com/go-kratos/kratos/v2/transport/grpc"
    "github.com/go-kratos/kratos/v2/registry"
)

func newGRPCClient(discovery registry.Discovery) {
    conn, err := grpc.DialInsecure(
        context.Background(),
        grpc.WithEndpoint("discovery:///user-service"),
        grpc.WithDiscovery(discovery),
    )
    if err != nil {
        panic(err)
    }
    defer conn.Close()
    
    // Use connection
    client := pb.NewUserServiceClient(conn)
}

Health Check Metadata

func registerWithHealthCheck(r registry.Registrar) {
    instance := &registry.ServiceInstance{
        ID:      "service-001",
        Name:    "user-service",
        Version: "v1.0.0",
        Metadata: map[string]string{
            "health_check_path":     "/health",
            "health_check_interval": "10s",
            "health_check_timeout":  "3s",
        },
        Endpoints: []string{
            "http://127.0.0.1:8000",
        },
    }
    
    ctx := context.Background()
    if err := r.Register(ctx, instance); err != nil {
        panic(err)
    }
}

Registry Implementations

Kratos supports various service registry implementations:
  • Consul: github.com/go-kratos/kratos/contrib/registry/consul/v2
  • Etcd: github.com/go-kratos/kratos/contrib/registry/etcd/v2
  • Nacos: github.com/go-kratos/kratos/contrib/registry/nacos/v2
  • Kubernetes: github.com/go-kratos/kratos/contrib/registry/kubernetes/v2
  • Eureka: github.com/go-kratos/kratos/contrib/registry/eureka/v2
  • Zookeeper: github.com/go-kratos/kratos/contrib/registry/zookeeper/v2
  • Polaris: github.com/go-kratos/kratos/contrib/registry/polaris/v2
Example with Consul:
import (
    consulAPI "github.com/hashicorp/consul/api"
    "github.com/go-kratos/kratos/contrib/registry/consul/v2"
)

// Create Consul client
config := consulAPI.DefaultConfig()
config.Address = "127.0.0.1:8500"
client, err := consulAPI.NewClient(config)
if err != nil {
    panic(err)
}

// Create registry
r := consul.New(client)

// Use with Kratos app
app := kratos.New(
    kratos.Name("user-service"),
    kratos.Registrar(r),
)

Build docs developers (and LLMs) love