File size: 1,559 Bytes
fea99b3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // Package operation provides an abstraction for RPC-style APIs.
//
// Implementations are generally business logic functions that take a request and return a response.
// Consumers of operations are transport layers, such as HTTP handlers or gRPC services.
//
// The operation layer allows you to separate business logic from transport concerns as well as to compose and reuse transport and operation-agnostic logic.
package operation
import (
"context"
)
// Operation is the fundamental building block of RPC-style APIs.
// It represents a single operation that can be performed by a caller.
type Operation[Request any, Response any] func(ctx context.Context, request Request) (Response, error)
// AsNoResponseOperation wraps a func (context.Context, request Request) error typed function as an operation
// useful for Delete like methods
func AsNoResponseOperation[Request any](f func(ctx context.Context, request Request) error) Operation[Request, any] {
return func(ctx context.Context, request Request) (any, error) {
return nil, f(ctx, request)
}
}
// Compose can be used to chain two operations together (e.g. get something, then update it).
func Compose[Request any, Intermediate any, Response any](op1 Operation[Request, Intermediate], op2 Operation[Intermediate, Response]) Operation[Request, Response] {
return func(ctx context.Context, request Request) (Response, error) {
intermediate, err := op1(ctx, request)
if err != nil {
var defaultResponse Response
return defaultResponse, err
}
return op2(ctx, intermediate)
}
}
|