Skip to content

adnvilla/dispatcher-go

Repository files navigation

dispatcher-go

License GitHub Actions Codecov Go Report Card

Overview

Introducing dispatcher, a lightweight and extensible command dispatcher for Golang designed to simplify the handling of requests and responses with support for validation and context-based operations.

Features

  • Request and Response Handling: Define and register handlers for custom request types that can execute logic and return structured responses.
  • Notification Support: Publish events to multiple handlers for decoupled event-driven architecture.
  • Context Support: All operations are executed with Go's context.Context, enabling better control over request lifecycles and cancellation.
  • Validation Integration: Optionally implement Validator for request validation, ensuring that invalid requests are caught before processing.
  • Type Safety: Utilizes Go generics and reflection to ensure type-safe handler registration and execution.
  • Simple API: Easy-to-use functions for registering handlers, sending requests, and resetting the dispatcher state.

API Highlights

  • RegisterHandler: Register a new handler for a specific request type.
  • Send: Send a request and receive a response, with automatic validation if the handler implements Validator.
  • RegisterNotificationHandler: Register a new handler for a specific notification type. Support multiple handlers per notification.
  • Publish: Publish a notification to all registered handlers.
  • ResetRequestHandler: Clear all registered request handlers.
  • ResetNotificationHandler: Clear all registered notification handlers.

Usage Example

package main

import (
    "context"
    "fmt"
    dispatcher "github.com/adnvilla/dispatcher-go"
)

type MyRequest struct {
    Message string
}

type MyResponse struct {
    Success bool
}

type MyHandler struct{}

func (h *MyHandler) Handle(ctx context.Context, request MyRequest) (MyResponse, error) {
    return MyResponse{Success: true}, nil
}

func (h *MyHandler) Validate(ctx context.Context, request MyRequest) error {
    if request.Message == "" {
        return fmt.Errorf("message cannot be empty")
    }
    return nil
}

func main() {
    ctx := context.Background()
    handler := &MyHandler{}
    dispatcher.RegisterHandler(ctx, handler)

    response, err := dispatcher.Send[MyRequest, MyResponse](ctx, MyRequest{Message: "Hello, world!"})
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Response:", response)
    }

    dispatcher.ResetRequestHandler()
}

Notification Example

package main

import (
    "context"
    "fmt"
    dispatcher "github.com/adnvilla/dispatcher-go"
)

type MyNotification struct {
    Message string
}

type MyNotificationHandler struct{}

func (h *MyNotificationHandler) Handle(ctx context.Context, notification MyNotification) error {
    fmt.Println("Notification received:", notification.Message)
    return nil
}

func main() {
    ctx := context.Background()
    handler := &MyNotificationHandler{}
    dispatcher.RegisterNotificationHandler(ctx, handler)

    err := dispatcher.Publish(ctx, MyNotification{Message: "Something happened!"})
    if err != nil {
        fmt.Println("Error:", err)
    }

    dispatcher.ResetNotificationHandler()
}

Known Issues

  • Limited error reporting for handler type mismatches.
  • Performance optimizations are planned for future releases.

Future Enhancements

  • Improved logging and error handling.
  • Support for middleware to add cross-cutting concerns such as logging and metrics.
  • Additional examples and documentation.

About

Golang dispatcher

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors