event

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2025 License: MIT Imports: 3 Imported by: 0

README

Contributions Welcome Release

Event Package

This directory contains the Event Handling Framework for Go applications, designed to streamline event-driven workflows in backend services. It provides a generic and modular way to handle event messages with flexible payloads and versioning support.

Introduction

The Event Package provides a robust framework for handling event messages in Go applications. It allows for:

  • Defining and processing event messages with flexible, user-defined payload types.
  • Integration with HTTP frameworks (like Gin) via a generic EventHandler interface.
  • Separation of concerns: event message parsing, business logic handling, and HTTP integration are modular and distinct.
  • This package promotes reusable patterns across services to maintain consistency in event handling across your projects.

Features

  • User-Defined Payload Types: Utilizes Go generics to allow flexible payload structures for event messages.
  • Generic Interface for Event Processing: Provides a flexible EventHandler interface for defining how events are processed.
  • Modular Design: Separates event message logic, event handler logic, and HTTP integration for clean and maintainable code.
  • HTTP Integration: Includes helper functions for integrating with popular web frameworks like Gin.

Documentation

Go Reference

For detailed API documentation, examples, and usage patterns, visit the Go Package Documentation.

Usage

Defining Event Messages

To define an event, the framework expects a JSON structure with an event type, timestamp, and a flexible payload. The payload section of the event can be a user-defined structure, providing the flexibility to handle different kinds of events.

example

{
  "event_type": "user_created",
  "timestamp": "2024-08-20T05:21:19.143357839Z",
  "payload": {
    "user_id": "12345",
    "username": "johndoe"
  },
  "metadata": {
    "source": "user_service",
    "version": "1.0"
  }
}
  • event_type: A string indicating the type of event.
  • timestamp: An RFC3339 formatted timestamp.
  • payload: An object containing the event data. This is where generics come into play, allowing for flexible payload types.
  • metadata: An object containing metadata about the event, including the version.
Defining Your Payload

Using Go's generics, you can define your own payload type to represent the data for each event:

// event_payload.go
package your_package

type UserCreatedPayload struct {
    UserID   string `json:"user_id"`
    Username string `json:"username"`
}
Creating an Event Handler

The event framework uses a generic EventHandler interface to process events.

type EventHandler[T any] interface {
	BeforeHandle(ctx context.Context, msg EventMessage[T]) error
	AfterHandle(ctx context.Context, msg EventMessage[T], eventResult error) error
	UnmarshalEventMessage(data []byte) (EventMessage[T], error)
}

The event framework is designed to be extensible. You can create custom event handlers to handle specific scenarios, such as events with callbacks, or complex retry mechanisms. For examples of custom handlers, see: custom_handler/callback/handler.go

Implementing Business Logic

Define your business logic function that processes the event payload.

// handlers.go
package your_package

import (
    "github.com/gin-gonic/gin"
    "https://github.com/kittipat1413/go-common/framework/event"
)

func MyBusinessLogic(ctx *gin.Context, msg event.EventMessage[UserCreatedPayload]) error {
    payload := msg.GetPayload()

    // Process the event
    log.Printf("User created: %s with ID %s", payload.Username, payload.UserID)

    // Return nil on success, or an error if something goes wrong
    return nil
}
Integrating with HTTP Frameworks (e.g., Gin)

If you are using a web framework like Gin, you can integrate the event framework with the NewGinEventHandler, which creates a gin.HandlerFunc. This handler can then be injected into your Gin routes. The handler requires an EventHandler instance to process the event.

// main.go

import (
    "github.com/gin-gonic/gin"
    "https://github.com/kittipat1413/go-common/framework/handler"
)

func main() {
    router := gin.Default()

    // Initialize EventHandler as before

    // Create the Gin handler
    ginHandler := handler.NewGinEventHandler(MyBusinessLogic, eventHandler)

    // Register the route with the Gin router
    router.POST("/event", ginHandler)

    // Optionally, register a route to handle callbacks
    router.GET("/callback", CallbackHandler)

    router.Run(":8080")
}

Example

You can find a complete working example in the repository under framework/event/example.

Documentation

Index

Constants

View Source
const (
	// MetadataKeyVersion is the key for the event message version.
	// It indicates the version of the event schema for compatibility checks.
	MetadataKeyVersion = "version"

	// MetadataKeySource is the key for the event message source.
	// It indicates where the event originated from (e.g., "user-service", "payment-api").
	MetadataKeySource = "source"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type BaseEventMessage

type BaseEventMessage[T any] struct {
	EventType string            `json:"event_type"` // Type of event (e.g., "user.created")
	Timestamp time.Time         `json:"timestamp"`  // When the event occurred
	Payload   T                 `json:"payload"`    // Typed business data
	Metadata  map[string]string `json:"metadata"`   // Additional context and headers
}

BaseEventMessage provides a standard implementation of EventMessage[T]. It supports JSON marshaling/unmarshaling and includes common event fields like type, timestamp, payload, and metadata.

This struct can be used directly or embedded in custom event message types for consistent event structure across applications.

func (*BaseEventMessage[T]) GetEventType

func (m *BaseEventMessage[T]) GetEventType() string

GetEventType returns the event type identifier. Used for event routing and handler selection.

func (*BaseEventMessage[T]) GetMetadata

func (m *BaseEventMessage[T]) GetMetadata() map[string]string

GetMetadata returns event metadata and context information. Includes version, source, correlation IDs, and other contextual data.

func (*BaseEventMessage[T]) GetPayload

func (m *BaseEventMessage[T]) GetPayload() T

GetPayload returns the typed event business data. Contains the actual information relevant to the event.

func (*BaseEventMessage[T]) GetTimestamp

func (m *BaseEventMessage[T]) GetTimestamp() time.Time

GetTimestamp returns when the event occurred. Essential for event ordering and temporal processing.

func (*BaseEventMessage[T]) GetVersion

func (m *BaseEventMessage[T]) GetVersion() string

GetVersion extracts the version from metadata using MetadataKeyVersion. Returns empty string if version is not set in metadata.

type EventHandler

type EventHandler[T any] interface {
	// BeforeHandle performs pre-processing before the main event handling logic.
	// Used for validation, authentication, enrichment, or preparation tasks.
	BeforeHandle(ctx context.Context, msg EventMessage[T]) error

	// AfterHandle performs post-processing after the main event handling logic.
	// Runs regardless of main processing success/failure, suitable for cleanup,
	// callbacks, logging, and side effects.
	AfterHandle(ctx context.Context, msg EventMessage[T], eventResult error) error

	// UnmarshalEventMessage converts raw event data into a typed EventMessage.
	// Handles deserialization from various formats (JSON, XML, protobuf, etc.)
	// and returns strongly-typed event message for processing.
	UnmarshalEventMessage(data []byte) (EventMessage[T], error)
}

EventHandler defines the interface for processing events with lifecycle hooks. Implementations provide custom logic for event unmarshaling, pre-processing, and post-processing while maintaining consistent event handling patterns.

Lifecycle Flow:

  1. UnmarshalEventMessage() - Convert raw data to typed event message
  2. BeforeHandle() - Pre-processing and validation
  3. [External event processing logic]
  4. AfterHandle() - Post-processing and cleanup

type EventMessage

type EventMessage[T any] interface {
	// GetVersion returns the event schema version for compatibility checks.
	// Used to handle different versions of the same event type.
	GetVersion() string

	// GetEventType returns the type of event (e.g., "user.created", "order.updated").
	// Used for routing and processing logic.
	GetEventType() string

	// GetTimestamp returns when the event occurred.
	// Used for ordering, TTL checks, and temporal processing.
	GetTimestamp() time.Time

	// GetPayload returns the typed event data containing business information.
	// The type T is determined by the EventHandler's generic parameter.
	GetPayload() T

	// GetMetadata returns event metadata and context as key-value pairs.
	// Contains additional information like source, correlation IDs, etc.
	GetMetadata() map[string]string
}

EventMessage defines the interface for accessing event data and metadata. This interface provides a consistent way to retrieve event information regardless of the underlying message format or source (HTTP, message queue, webhook, etc.).

The interface uses generics to provide type-safe access to event payloads while maintaining flexibility for different event types and sources.

func BaseEventMessageUnmarshaller

func BaseEventMessageUnmarshaller[T any](data []byte) (EventMessage[T], error)

BaseEventMessageUnmarshaller unmarshals JSON data into a BaseEventMessage[T]. This is a convenience function for creating BaseEventMessage instances from JSON bytes.

Parameters:

  • data: JSON bytes containing event data

Returns:

  • EventMessage[T]: Unmarshaled event message
  • error: JSON parsing error if data is invalid

Example:

data := []byte(`{"event_type":"user.created","timestamp":"2023-01-01T00:00:00Z","payload":{"id":123},"metadata":{"source":"api"}}`)
msg, err := BaseEventMessageUnmarshaller[User](data)

Directories

Path Synopsis
custom_handler
example
gin_callback command
Package event_handler_mocks is a generated GoMock package.
Package event_handler_mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

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