godiator

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Apr 24, 2021 License: GPL-3.0 Imports: 4 Imported by: 3

README

godiator

Easy to use mediator implementation in Golang. Provides in-process messaging ability to your apps.

Installation

You should install godiator via Go package manager:

$ go get -v https://github.com/baranius/godiator

Usage

Use GetInstance() method to get godiator object. Take a look to complete API reference for details.

type GetItemController struct {
	g godiator.IGodiator
}

func NewGetItemController() *GetItemController {
	return &GetItemController{g: godiator.GetInstance()}
}

Handlers

Handlers are the main objects that runs your business logic.

A handler is a struct that contains Handle method.

Handle method should get a request object and return a tuple of response object and error.

type (
	SampleRequest struct{
		PayloadString *string
	}

	SampleResponse struct{
		ResultString *string
	}

	SampleHandler struct{
	}
)

//Registering handlers in godiator requires an init function.
func NewSampleHandler() interface{} {
	return &SampleHandler{}
}

func (h *SampleHandler) Handle(request *SampleRequest) (*SampleResponse, error){
	return &SampleResponse{ResultString: request.PayloadString}, nil
}

Handle method can take additional parameters

type (
	SampleRequest struct{
	    PayloadString *string
	}

	SampleResponse struct{
	    ResultString *string
	}

	SampleHandler struct{
	}
)

func NewSampleHandler() interface{} {
	return &SampleHandler{}
}

func (h *SampleHandler) Handle(request *SampleRequest, ctx context.Context) (*SampleResponse, error){
	return &SampleResponse{ResultString: request.PayloadString}, nil
}
Registering Handlers

Register method takes request model and handler's initializer method as arguments.

func RegisterHandlers() {
    g := godiator.GetInstance()
    
    g.Register(&SampleRequest{}, NewSampleHandler)
}
Calling Handlers

Calling Send method with request object executes the related handler.

type GetItemController struct {
    g godiator.IGodiator
}

func NewGetItemController() *GetItemController {
    return &GetItemController{g: godiator.GetInstance()}
}

func (c *GetItemController) GetItem() {
    payloadValue := "sample_value"
    request := &SampleRequest{PayloadString: &payloadValue}
    
    response, err := c.g.Send(request)

    // If your handle method takes additional parameters, don't forget to pass them to 'Send'
    response, err := c.g.Send(request, context.TODO())
}

Subscriptions

Subscriptions are observers. They operate quite similar to message broadcasting.

type (
	SubscriptionRequest struct {
        PayloadString *string
    }
    
    SubscriptionHandler struct {}
) 

func NewSubscriptionHandler() interface{} {
	return &SubscriptionHandler{}
}

func (n *SubscriptionHandler) Handle(request interface{}) {
	r := request.(*SubscriptionRequest)
	fmt.Printf("Subscription called with payload : '%v'", *r.PayloadString)
}
Registering Subscriptions

RegisterSubscription method takes request model and related handler(s).

func RegisterSubscriptions() {
    g := godiator.GetInstance()
    
    g.RegisterSubscription(&SubscriptionRequest{}, NewSubscriptionHandler, NewSubscriptionHandlerA, NewSubscriptionHandlerB)
}
Calling Subscriptions

Calling Publish method with request object notifies the related handler(s).

type GetItemController struct {
    g godiator.IGodiator
}

func NewGetItemController() *GetItemController {
    return &GetItemController{g: godiator.GetInstance()}
}

func (c *GetItemController) GetItem() {
    payloadValue := "sample_value"
    request := &SubscriptionRequest{PayloadString: &payloadValue}
    
    c.g.Publish(request)
}

Pipelines

Pipelines are interceptors that runs before each handler call.

They should be derived from godiator.Pipeline struct and include a Handle method just like handlers.

Important: params ...interface{} is optional. But you should define them in your Pipeline's Handle method

type ValidationPipeline struct {
	godiator.Pipeline
}

func (p *ValidationPipeline) Handle(request interface{}, params ...interface{}) (interface{}, error) {
	r := request.(*handler.SampleRequest)

	if r.PayloadString == nil {
		return nil, errors.New("PayloadString_should_not_be_null")
	}

	return p.Next().Handle(request, params...)
}
Registering Pipelines

Call RegisterPipeline method to register pipelines.

Important: Pipelines run in the definition order.

func RegisterPipelines() {
    g := godiator.GetInstance()
    
    g.RegisterPipeline(&ValidationPipeline{}) // Will run first
    g.RegisterPipeline(&SomeOtherPipeline{})
}

Mocking

You can mock Send and Notify methods of godiator via MockGodiator.

The only thing you need to do is delegating OnSend or OnNotify methods.

OnSend
mockGodiator := MockGodiator{}

mockGodiator.OnSend = func(request interface{}, params ...interface{}) (i interface{}, err error){
    return &Response{}, nil
}
OnNotify
mockGodiator := MockGodiator{}

mockGodiator.OnNotify = func(request interface{}, params ...interface{}) {
    fmt.Print("Called")
}

API

Godiator
RegisterPipeline(h IPipeline)
  • h: A struct derived from godiator.Pipeline
Register(request interface{}, handler func()interface{})
  • request: Interface
  • handler: Initialize function which returns Handler instance
RegisterSubscription(request interface{}, handler func()interface{})
  • request: Interface
  • handler: Initialize function which returns Subscription handler instance
Send(request interface{}, params ...interface{}) (interface{}, error)
  • request: Handler's request model
  • params (optional): Optional list of objects
Publish(request interface{}, params ...interface{})
  • request: Handler's request model
  • params (optional): Optional list of objects
Handler
Handle(request interface{}, params ...interface{}) (interface{}, error)
  • request: Handler's request model
  • params (optional): Optional list of objects
Subscription
Publish(request interface{}, params ...interface{})
  • request: Handler's request model
  • params (optional): Optional list of objects
Pipeline
Handle(request interface{}, params ...interface{}) (interface{}, error)
  • request: Handler's request model
  • params (optional): Optional list of objects

Contribution

You're very welcome to contribute the project. Please feel free to contribute or asking questions.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type IGodiator

type IGodiator interface {
	GetHandlerResponse(request interface{}) interface{}
	RegisterPipeline(h IPipeline)
	Register(request interface{}, handler func() interface{})
	RegisterSubscription(request interface{}, handler ...func() interface{})
	Send(request interface{}, params ...interface{}) (interface{}, error)
	Publish(request interface{}, params ...interface{})
}

func GetInstance

func GetInstance() IGodiator

Init Singleton

type IPipeline

type IPipeline interface {
	Next() IPipeline
	SetNext(handler IPipeline)
	Handle(request interface{}, params ...interface{}) (interface{}, error)
}

type MockGodiator

type MockGodiator struct {
	OnSend    OnSend
	OnPublish OnPublish
}

func (*MockGodiator) GetHandlerResponse

func (mock *MockGodiator) GetHandlerResponse(request interface{}) interface{}

func (*MockGodiator) Publish

func (mock *MockGodiator) Publish(request interface{}, params ...interface{})

func (*MockGodiator) Register

func (mock *MockGodiator) Register(request interface{}, handler func() interface{})

func (*MockGodiator) RegisterPipeline

func (mock *MockGodiator) RegisterPipeline(h IPipeline)

func (*MockGodiator) RegisterSubscription

func (mock *MockGodiator) RegisterSubscription(request interface{}, handler ...func() interface{})

func (*MockGodiator) Send

func (mock *MockGodiator) Send(request interface{}, params ...interface{}) (interface{}, error)

type OnPublish

type OnPublish func(request interface{}, params ...interface{})

type OnSend

type OnSend func(request interface{}, params ...interface{}) (interface{}, error)

type Pipeline

type Pipeline struct {
	// contains filtered or unexported fields
}

func (*Pipeline) Handle

func (h *Pipeline) Handle(request interface{}, params ...interface{}) (interface{}, error)

func (*Pipeline) Next

func (h *Pipeline) Next() IPipeline

func (*Pipeline) SetNext

func (h *Pipeline) SetNext(handler IPipeline)

Jump to

Keyboard shortcuts

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