events

package module
v0.0.0-...-a780941 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2016 License: Apache-2.0 Imports: 2 Imported by: 0

README

Domain Events

GoDoc

This is a package with several implementations for handling Domain events. In Domain Driven Design, a domain event is a way of indicating that some event has happened that has relevance to the domain.

This specific package provides the interfaces for interacting with these events as a part of a larger application.

Installation

go get gitlab.com/rnewton/domain-events

Usage

This library is designed to take advantage of a Four-layered Architecture. The specific publishers/subscribers in-use are a infrastructure concern. These are injected into the application layer as dependencies and the domain layer handles the hooks for when events are triggered.

Hooks

In order to have your entity trigger a domain event automatically, you need to implement the appropriate interface as below:

  • BeforeCreate() *events.Event
  • AfterCreate() *events.Event
  • BeforeUpdate() *events.Event
  • AfterUpdate() *events.Event
  • BeforeDelete() *events.Event
  • AfterDelete() *events.Event

It'll look something like:

package domain

import (
    "time"

    "gitlab.com/rnewton/domain-events"
)

type Something struct {
    All    string
    Sorts  string
    Of     string
    Params string
}

func (s *Something) AfterUpdate() *events.Event {
    return &events.Event{
        UUID:      "Something of significance",
        CreatedAt: time.Now(),
        Name:      "SomethingUpdated",
        Data:      map[string]string{
            "anything": "that we want to capture",
            "can":      "be reflected in this because",
            "type":     "is interface{}"
        },
    }
}

Then generate the repository using the evt tool.

evt -e domain/model/something/something.go -r infrastructure/persistence/db/something_repository_gen.go

It'll create a SomethingRepository for you that automatically hooks up the change hooks. In your service locator, instantiate the repository you generated:

func (c *Container) SomethingRepository() *db.SomethingRepository {
    if c.somethingRepo == nil {
        c.somethingRepo := &db.SomethingRepository{
            DB:  c.Database(),
            Pub: c.DomainEventsPublisher(),
        }
    }

    return c.somethingRepo
}

And when you call SomethingRepository.Save(*Something), it'll automatically call *Something.AfterUpdate for you. It does this without reflection because you've already generated the code. This means it's very quick!

The generated file is overwritten every time you run evt so it shouldn't be modified. If you need your repository to have custom behavior, create another file that implements the new methods you need. The generated repository is exported and can be extended with new func (r *SomethingRepository) YourMethod definitions.

Listen for the events elsewhere. Say a background job cli:

package main

import (
    "fmt"
    "infrastructure"

    "gitlab.com/rnewton/domain-events"
)

func handleSomethingUpdated(event *events.Event) error {
    fmt.Println("It's all good!")
    return nil
}

func main() {
    ...
    listener := container.DomainEventsListener()
    listener.RegisterHandler("SomethingUpdated", handleSomethingUpdated)

    listener.Listen()
}

Documentation

Overview

Package events provides interfaces for publishing and handling domain events in Go. In Domain Driven Design, a domain event is a way of indicating that some event has happened that has relevance to the domain.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AfterCreateHook

type AfterCreateHook interface {
	AfterCreate() *Event
}

AfterCreateHook is used for entities to trigger events after being created

type AfterDeleteHook

type AfterDeleteHook interface {
	AfterDelete() *Event
}

AfterDeleteHook is used for entities to trigger events after being deleted

type AfterUpdateHook

type AfterUpdateHook interface {
	AfterUpdate() *Event
}

AfterUpdateHook is used for entities to trigger events after being updated

type BeforeCreateHook

type BeforeCreateHook interface {
	BeforeCreate() *Event
}

BeforeCreateHook is used for entities to trigger events before being created

type BeforeDeleteHook

type BeforeDeleteHook interface {
	BeforeDelete() *Event
}

BeforeDeleteHook is used for entities to trigger events before being deleted

type BeforeUpdateHook

type BeforeUpdateHook interface {
	BeforeUpdate() *Event
}

BeforeUpdateHook is used for entities to trigger events before being updated

type ErrorHandler

type ErrorHandler func(error)

ErrorHandler defines the function signature required for handling errors

type Event

type Event struct {
	UUID      string      `json:"uuid"`
	CreatedAt time.Time   `json:"created_at"`
	Name      string      `json:"name"`
	Data      interface{} `json:"data"`
}

Event is a generic wrapper for all domain events

func NewEvent

func NewEvent(name string, payload interface{}) *Event

NewEvent creates a new event with the given name and payload. The UUID and CreatedAt fields are filled in automatically so that the infrastructure concerns of doing so are removed from the domain

type EventHandler

type EventHandler func(*Event) error

EventHandler defines the function signature required for handling events

type Listener

type Listener interface {
	// RegisterHandler registers an event handler for events of the given string name
	RegisterHandler(string, EventHandler)

	// Listen spawns a non-blocking goroutine to listen for new events
	Listen(ErrorHandler)

	// Halt stops the listen goroutine
	Halt()
}

Listener defines the interface required for listening for new events and handling them

type Publisher

type Publisher interface {
	// Publish pushes out the given event to the configured messaging interface
	Publish(*Event) error
}

Publisher describes the interface for pushing events

Directories

Path Synopsis
evt
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL