Skip to content
Cloud application library for Golang
Go
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples
pkg
.gitignore
LICENSE.md
README.md
discovery.go
discovery_test.go
go.mod
go.sum

README.md

Cloud Application Framework

This library aims to expose a common set of interfaces for handling common cloud platform tasks. Such as queuing messages, publishing events, calling cloud functions etc.

This library is AWS centric, however, can by modified and extended to support others. Using the interfaces and configuration options shown below.

Being AWS centric, the default options are:

  • Locator / Service Discovery: AWS Cloudmap
  • Request: AWS Lambda
  • Pubsub: AWS SNS
  • Queue: AWS SQS
  • Automate: AWS SSM

Registering a service - Cloudformation

For the Cloudmap locator, the easiest way to register a service is through Cloudformation (or Terraform etc):

CloudMapService:
  Type: AWS::ServiceDiscovery::Service
  Properties:
    Description: User service
    Name: users
    NamespaceId: <namespace-id-here>

CreateUserInstance:
  Type: "AWS::ServiceDiscovery::Instance"
  Properties:
    InstanceAttributes:
      arn: create-user
      handler: create-job-run
      type: function
    InstanceId: create-user
    ServiceId:
      Ref: CloudMapService

Use with default settings

func main() {
  d := discover.NewDiscovery()

  token, err := d.Queue("acme-prod.my-service->my-queue", types.Request{
    Body: []byte("{}"),
  }, nil)
  ...
}

Use with custom integrations

func main() {
  ...
  d := discover.NewDiscovery(
    discover.SetQueue(NewKafkaAdapter(kafkaClient)),
    discover.SetPubsub(NewNATSAdapter(natsClient)),
    discover.SetLocator(NewConsulLocator(consul)),
  )
}

Request

d := discover.NewDiscovery()
d.Request("my-namespace.users->create-user", types.Request{
  Body: []byte("{ \"hello\": \"world\" }"),
}, opts)

Queue

d := discover.NewDiscovery()
d.Queue("my-namespace.my-service->my-queue", types.Request{
  Body: jsonString,
}, nil)

go func() {
  messages, err := d.Listen("my-namespace.my-service->my-queue", opts)
  for message := range message {
    log.Println(string(message.Body))
  }
}()

Pubsub

d := discovery.NewDiscovery()
d.Publish("my-namespace.my-service->my-event", types.Request{
  Body: jsonEvent,
})

Automate

d := discovery.NewDiscovery()
d.Automate("my-namespace.my-service->my-script", types.Request{
  Body: jsonEvent,
})

Custom integrations

You can customise the behaviour and create your own integrations by conforming to the following interfaces, and use the SetLocator, SetQueue, SetPubsub, SetAutomate and SetFunction methods when creating an instance of the Discovery library.

Locator interface

Discover(signature *types.Signature) (*types.Service, error)

Queue interface

// QueueAdapter -
type QueueAdapter interface {

	// Queue a message, return a token or message id
	Queue(service *types.Service, request types.Request, opts types.Options) (string, error)
	Listen(service *types.Service, opts types.Options) (<-chan *types.Response, error)
}

Function interface

// FunctionAdapter -
type FunctionAdapter interface {
	Call(service *types.Service, request types.Request, opts types.Options) (*types.Response, error)
}

AutomateAdapter interface

// AutomateAdapter -
type AutomateAdapter interface {
	Execute(service *types.Service, request types.Request, opts types.Options) (*types.Response, error)
}

PubsubAdapter interface

// PubsubAdapter -
type PubsubAdapter interface {
	Publish(service *types.Service, request types.Request, opts types.Options) error
	Subscribe(service *types.Service, opts types.Options) (<-chan *types.Response, error)
}

Acknowledgements: inspired by the amazing work at Micro

You can’t perform that action at this time.