Skip to content

Request Context

The RequestContext in comby provides a structured container for metadata and execution parameters related to a specific Command or Query request. It is designed to enhance contextual awareness during execution, supporting distributed systems and event-driven architectures.

The RequestContext encapsulates details about the sender, including the tenant, identity, account, and session unique identifiers, which represent the entity initiating the request. These fields ensure traceability and accountability within multi-tenant systems.

Optional fields like TargetTenantUuid and TargetAggregateUuid specify the target entities for the request, allowing precise routing and processing. Execution parameters such as ExecuteTimeout, ExecuteWaitToFinish, and Attributes provide fine-grained control over how the request is handled. For example, these fields allow for skipping authorization checks (if using comby default), setting a timeout for command execution, or specifying whether the system should wait for command completion.

Traceability is further enhanced with the TraceId, a unique identifier for tracking the request across distributed systems. (Please note TraceId is not used yet). Developers can also use the MetaData map to store additional user-defined key-value pairs, offering flexibility for handling custom context-specific data.

The RequestContext can be instantiated using the NewRequestContext function, which initializes the MetaData field as an empty map. This map supports common data types like strings, integers, floats, and booleans, and can be manipulated using the SetMetaData, GetMetaData, and GetMetaDataMap methods. These methods enable developers to add, retrieve, or inspect custom metadata associated with a request.

By associating the RequestContext with commands and queries, comby ensures that requests carry all necessary context for accurate and efficient processing in distributed and multi-tenant environments. This design provides a balance of structure, traceability, and extensibility, making it easier to maintain and scale applications.

In comby an RequestContext is defined as an struct as follows:

go
type RequestContext struct {
	// sender context: who is executing the command
	SenderTenantUuid   string `json:"senderTenantUuid,omitempty"`
	SenderIdentityUuid string `json:"senderIdentityUuid,omitempty"`
	SenderAccountUuid  string `json:"senderAccountUuid,omitempty"`
	SenderSessionUuid  string `json:"senderSessionUuid,omitempty"`

	// (optional) what is the target aggregate for this request
	// Note: The TargetAggregateUuid is in the RequestContext because not every command
	// or query refers to a specific aggregate and therefore it would be wrong to put
	// the AggregateUuid in the interface.
	// Simple example: The list of tenants does not have an AggregateUuid to point to.
	// but retrieving a specific tenant does.
	TargetAggregateUuid string `json:"targetAggregateUuid,omitempty"`

	// (optional) what is the target aggregate version for this request.
	// TargetAggregateVersion is the current version of an aggregate that the command
	// is intended to update. This ensures the command operates on the correct model state.
	// If the model has been updated by another command (i.e., its version has changed),
	// the current command will be rejected to prevent conflicts. The user must then create a
	// new command using the latest model version.
	TargetAggregateVersion int64 `json:"targetAggregateVersion,omitempty"`

	// (optional) sets timeout for execution
	ExecuteTimeout int64 `json:"executeTimeout,omitempty"`

	// (optional) execute context: should the command wait for completion?
	// If set to true, the command can be waited for completion with Facade's 'WaitForCmd' method.
	ExecuteWaitToFinish bool `json:"executeWaitToFinish,omitempty"`

	// (optional) trace context: what is the trace id for this request
	TraceId int64 `json:"traceId,omitempty"`

	// (optional) additional user specific data
	Attributes *AttributeMap `json:"attributes,omitempty"`
}

Usage

Example usage:

go
import "github.com/gradientzero/comby/v2"
import "github.com/gradientzero/comby/v2/domain/auth"

cmd := comby.NewCommand(...)
reqCtx := comby.NewRequestContext()
reqCtx.ExecuteWaitToFinish = true
reqCtx.Attributes.Set(auth.ExecuteSkipAuthorization, true)
cmd.SetReqCtx(reqCtx)