This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Interfaces

Define interfaces to extend microservices

1 - Client Server

Go Micro uses a client/server model for RPC communication between services.
  • The client is used to make requests to other services.
  • The server handles incoming requests.

Both client and server are pluggable and support middleware wrappers for additional functionality.

Example Usage

Here’s how to define a simple handler and register it with a Go Micro server:

package main

import (
    "context"
    "go-micro.dev/v6"
    "log"
)

type Greeter struct{}

func (g *Greeter) Hello(ctx context.Context, req *struct{}, rsp *struct{Msg string}) error {
    rsp.Msg = "Hello, world!"
    return nil
}

func main() {
    service := micro.NewService("greeter",
    )
    service.Init()
    micro.RegisterHandler(service.Server(), new(Greeter))
    if err := service.Run(); err != nil {
        log.Fatal(err)
    }
}

2 - Registry

The registry is responsible for service discovery in Go Micro. It allows services to register themselves and discover other services.

Registry

Features

  • Service registration and deregistration
  • Service lookup
  • Watch for changes

Implementations

Go Micro supports multiple registry backends, including:

  • MDNS (default)
  • Consul
  • Etcd
  • NATS

You can configure the registry when initializing your service.

Plugins Location

Registry plugins live in this repository under go-micro.dev/v6/registry/<plugin> (e.g., consul, etcd, nats). Import the desired package and pass it via micro.Registry(...).

Configure via environment

MICRO_REGISTRY=etcd MICRO_REGISTRY_ADDRESS=127.0.0.1:2379 micro server

Common variables:

  • MICRO_REGISTRY: selects the registry implementation (mdns, consul, etcd, nats).
  • MICRO_REGISTRY_ADDRESS: comma-separated list of registry addresses.

Backend-specific variables:

  • Etcd: ETCD_USERNAME, ETCD_PASSWORD for authenticated clusters.

Example Usage

Here’s how to use a custom registry (e.g., Consul) in your Go Micro service:

package main

import (
    "go-micro.dev/v6"
    "go-micro.dev/v6/registry/consul"
)

func main() {
    reg := consul.NewRegistry()
    service := micro.NewService("registry-example",
        micro.Registry(reg),
    )
    service.Init()
    service.Run()
}

3 - Broker

The broker provides pub/sub messaging for Go Micro services.

Broker

Features

  • Publish messages to topics
  • Subscribe to topics
  • Multiple broker implementations

Implementations

Supported brokers include:

  • HTTP (default)
  • NATS (go-micro.dev/v6/broker/nats)
  • RabbitMQ (go-micro.dev/v6/broker/rabbitmq)
  • Memory (go-micro.dev/v6/broker/memory)

Plugins are scoped under go-micro.dev/v6/broker/<plugin>.

Configure the broker in code or via environment variables.

Example Usage

Here’s how to use the broker in your Go Micro service:

package main

import (
    "go-micro.dev/v6"
    "go-micro.dev/v6/broker"
    "log"
)

func main() {
    service := micro.NewService("publisher")
    service.Init()

    // Publish a message
    if err := broker.Publish("topic", &broker.Message{Body: []byte("hello world")}); err != nil {
        log.Fatal(err)
    }

    // Subscribe to a topic
    _, err := broker.Subscribe("topic", func(p broker.Event) error {
        log.Printf("Received message: %s", string(p.Message().Body))
        return nil
    })
    if err != nil {
        log.Fatal(err)
    }

    // Run the service
    if err := service.Run(); err != nil {
        log.Fatal(err)
    }
}

Configure a specific broker in code

NATS:

import (
    "go-micro.dev/v6"
    bnats "go-micro.dev/v6/broker/nats"
)

func main() {
    b := bnats.NewNatsBroker()
    svc := micro.NewService("publisher", micro.Broker(b))
    svc.Init()
    svc.Run()
}

RabbitMQ:

import (
    "go-micro.dev/v6"
    "go-micro.dev/v6/broker/rabbitmq"
)

func main() {
    b := rabbitmq.NewBroker()
    svc := micro.NewService("publisher", micro.Broker(b))
    svc.Init()
    svc.Run()
}

Configure via environment

Using the built-in configuration flags/env vars (no code changes):

MICRO_BROKER=nats MICRO_BROKER_ADDRESS=nats://127.0.0.1:4222 go run main.go

Common variables:

  • MICRO_BROKER: selects the broker implementation (http, nats, rabbitmq, memory).
  • MICRO_BROKER_ADDRESS: comma-separated list of broker addresses.

Notes:

  • NATS addresses should be prefixed with nats://.
  • RabbitMQ addresses typically use amqp://user:pass@host:5672.

4 - Transport

The transport layer is responsible for communication between services.

Transport

Features

  • Pluggable transport implementations
  • Secure and efficient communication

Implementations

Supported transports include:

  • HTTP (default)
  • NATS (go-micro.dev/v6/transport/nats)
  • gRPC (go-micro.dev/v6/transport/grpc)
  • Memory (go-micro.dev/v6/transport/memory)

Important: Transport vs Native gRPC

The gRPC transport uses gRPC as an underlying communication protocol, similar to how NATS or RabbitMQ might be used. It does not provide native gRPC compatibility with tools like grpcurl or standard gRPC clients generated by protoc.

If you need native gRPC compatibility (to use grpcurl, polyglot gRPC clients, etc.), you must use the gRPC server and client packages instead:

import (
    grpcServer "go-micro.dev/v6/server/grpc"
    grpcClient "go-micro.dev/v6/client/grpc"
)

service := micro.NewService("myservice",
    micro.Server(grpcServer.NewServer()),
    micro.Client(grpcClient.NewClient()),
)

See Native gRPC Compatibility for a complete guide.

Plugins are scoped under go-micro.dev/v6/transport/<plugin>.

You can specify the transport when initializing your service or via env vars.

Example Usage

Here’s how to use a custom transport (e.g., gRPC) in your Go Micro service:

package main

import (
    "go-micro.dev/v6"
    "go-micro.dev/v6/transport/grpc"
)

func main() {
    t := grpc.NewTransport()
    service := micro.NewService("transport-example",
        micro.Transport(t),
    )
    service.Init()
    service.Run()
}

NATS transport:

import (
    "go-micro.dev/v6"
    tnats "go-micro.dev/v6/transport/nats"
)

func main() {
    t := tnats.NewTransport()
    service := micro.NewService("transport-example", micro.Transport(t))
    service.Init()
    service.Run()
}

Configure via environment

MICRO_TRANSPORT=nats MICRO_TRANSPORT_ADDRESS=nats://127.0.0.1:4222 go run main.go

Common variables:

  • MICRO_TRANSPORT: selects the transport implementation (http, nats, grpc, memory).
  • MICRO_TRANSPORT_ADDRESS: comma-separated list of transport addresses.

5 - Store

The store provides a pluggable interface for data storage in Go Micro.

Features

  • Key-value storage
  • Multiple backend support

Implementations

Supported stores include:

  • Memory (default)
  • File (go-micro.dev/v6/store/file)
  • MySQL (go-micro.dev/v6/store/mysql)
  • Postgres (go-micro.dev/v6/store/postgres)
  • NATS JetStream KV (go-micro.dev/v6/store/nats-js-kv)

Plugins are scoped under go-micro.dev/v6/store/<plugin>.

Configure the store in code or via environment variables.

Example Usage

Here’s how to use the store in your Go Micro service:

package main

import (
    "go-micro.dev/v6"
    "go-micro.dev/v6/store"
    "log"
)

func main() {
    service := micro.NewService("store-example")
    service.Init()

    // Write a record
    if err := store.Write(&store.Record{Key: "foo", Value: []byte("bar")}); err != nil {
        log.Fatal(err)
    }

    // Read a record
    recs, err := store.Read("foo")
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Read value: %s", string(recs[0].Value))
}

Configure a specific store in code

Postgres:

import (
    "go-micro.dev/v6"
    postgres "go-micro.dev/v6/store/postgres"
)

func main() {
    st := postgres.NewStore()
    svc := micro.NewService("store-example", micro.Store(st))
    svc.Init()
    svc.Run()
}

NATS JetStream KV:

import (
    "go-micro.dev/v6"
    natsjskv "go-micro.dev/v6/store/nats-js-kv"
)

func main() {
    st := natsjskv.NewStore()
    svc := micro.NewService("store-example", micro.Store(st))
    svc.Init()
    svc.Run()
}

Configure via environment

MICRO_STORE=postgres MICRO_STORE_ADDRESS=postgres://user:pass@127.0.0.1:5432/db \
MICRO_STORE_DATABASE=micro MICRO_STORE_TABLE=micro \
go run main.go

Common variables:

  • MICRO_STORE: selects the store implementation (memory, file, mysql, postgres, nats-js-kv).
  • MICRO_STORE_ADDRESS: connection/address string for the store (plugin-specific format).
  • MICRO_STORE_DATABASE: logical database or namespace (plugin-specific).
  • MICRO_STORE_TABLE: logical table/bucket (plugin-specific).

6 - Plugins

Plugins are scoped under each interface directory within this repository. To use a plugin, import it directly from the corresponding interface subpackage and pass it to your service via options.

Common interfaces and locations:

  • Registry: go-micro.dev/v6/registry/* (e.g. consul, etcd, nats, mdns)
  • Broker: go-micro.dev/v6/broker/* (e.g. nats, rabbitmq, http, memory)
  • Transport: go-micro.dev/v6/transport/* (e.g. nats, default http)
  • Server: go-micro.dev/v6/server/* (e.g. grpc for native gRPC compatibility)
  • Client: go-micro.dev/v6/client/* (e.g. grpc for native gRPC compatibility)
  • Store: go-micro.dev/v6/store/* (e.g. postgres, mysql, nats-js-kv, memory)
  • Auth, Cache, etc. follow the same pattern under their respective directories.

Registry Examples

Consul:

import (
    "go-micro.dev/v6"
    "go-micro.dev/v6/registry/consul"
)

func main() {
    reg := consul.NewConsulRegistry()
    svc := micro.NewService("plugin-example",
        micro.Registry(reg),
    )
    svc.Init()
    svc.Run()
}

Etcd:

import (
    "go-micro.dev/v6"
    "go-micro.dev/v6/registry/etcd"
)

func main() {
    reg := etcd.NewRegistry()
    svc := micro.NewService("plugin-example", micro.Registry(reg))
    svc.Init()
    svc.Run()
}

Broker Examples

NATS:

import (
    "go-micro.dev/v6"
    bnats "go-micro.dev/v6/broker/nats"
)

func main() {
    b := bnats.NewNatsBroker()
    svc := micro.NewService("plugin-example", micro.Broker(b))
    svc.Init()
    svc.Run()
}

RabbitMQ:

import (
    "go-micro.dev/v6"
    "go-micro.dev/v6/broker/rabbitmq"
)

func main() {
    b := rabbitmq.NewBroker()
    svc := micro.NewService("plugin-example", micro.Broker(b))
    svc.Init()
    svc.Run()
}

Transport Example (NATS)

import (
    "go-micro.dev/v6"
    tnats "go-micro.dev/v6/transport/nats"
)

func main() {
    t := tnats.NewTransport()
    svc := micro.NewService("plugin-example", micro.Transport(t))
    svc.Init()
    svc.Run()
}

gRPC Server/Client (Native gRPC Compatibility)

For native gRPC compatibility (required for grpcurl, polyglot gRPC clients, etc.), use the gRPC server and client plugins. Note: This is different from the gRPC transport.

import (
    "go-micro.dev/v6"
    grpcServer "go-micro.dev/v6/server/grpc"
    grpcClient "go-micro.dev/v6/client/grpc"
)

func main() {
    svc := micro.NewService("plugin-example",
        micro.Server(grpcServer.NewServer()),
        micro.Client(grpcClient.NewClient()),
    )
    svc.Init()
    svc.Run()
}

See Native gRPC Compatibility for a complete guide.

Store Examples

Postgres:

import (
    "go-micro.dev/v6"
    postgres "go-micro.dev/v6/store/postgres"
)

func main() {
    st := postgres.NewStore()
    svc := micro.NewService("plugin-example", micro.Store(st))
    svc.Init()
    svc.Run()
}

NATS JetStream KV:

import (
    "go-micro.dev/v6"
    natsjskv "go-micro.dev/v6/store/nats-js-kv"
)

func main() {
    st := natsjskv.NewStore()
    svc := micro.NewService("plugin-example", micro.Store(st))
    svc.Init()
    svc.Run()
}

Notes

  • Defaults: If you don’t set an implementation, Go Micro uses sensible in-memory or local defaults (e.g., mDNS for registry, HTTP transport, memory broker/store).
  • Options: Each plugin exposes constructor options to configure addresses, credentials, TLS, etc.
  • Imports: Only import the plugin you need; this keeps binaries small and dependencies explicit.