Documentation
¶
Overview ¶
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.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewLogHandler ¶
NewLogHandler returns a new slog.Handler
Types ¶
type Middleware ¶
type Middleware[Request any, Response any] func(Operation[Request, Response]) Operation[Request, Response]
Middleware is a chainable function that wraps an Operation.
Example ¶
package main import ( "context" "github.com/openmeterio/openmeter/pkg/framework/operation" ) func mw1[Request any, Response any](next operation.Operation[Request, Response]) operation.Operation[Request, Response] { return func(ctx context.Context, request Request) (Response, error) { return next(ctx, request) } } func mwchain[Request any, Response any](op operation.Operation[Request, Response]) operation.Operation[Request, Response] { chain := operation.Chain[Request, Response](mw1) return chain(op) } func main() { mwchain(exampleOperation) }
Output:
func Chain ¶
func Chain[Request any, Response any](outer Middleware[Request, Response], others ...Middleware[Request, Response]) Middleware[Request, Response]
Chain is a helper function for composing middlewares. Requests will traverse them in the order they're declared. That is, the first middleware is treated as the outermost middleware.
type Operation ¶
type Operation[Request any, Response any] func(ctx context.Context, request Request) (Response, error)
Operation is the fundamental building block of RPC-style APIs. It represents a single operation that can be performed by a caller.
Example ¶
package main import ( "context" "errors" "fmt" "github.com/openmeterio/openmeter/pkg/framework/operation" ) type ExampleRequest struct { Name string } type ExampleResponse struct { Greeting string } func exampleOperation(ctx context.Context, request ExampleRequest) (ExampleResponse, error) { if request.Name == "" { return ExampleResponse{}, errors.New("name is required") } return ExampleResponse{Greeting: "Hello, " + request.Name}, nil } func main() { var op operation.Operation[ExampleRequest, ExampleResponse] = exampleOperation resp, err := op(context.Background(), ExampleRequest{Name: "World"}) if err != nil { panic(err) } fmt.Print(resp.Greeting) } // func ExampleOperation() { // var op operation.Operation[ExampleRequest, ExampleResponse] = operationImpl{} // // resp, err := op.Do(context.Background(), ExampleRequest{Name: "World"}) // if err != nil { // panic(err) // } // // fmt.Print(resp.Greeting) // // Output: Hello, World // } // func ExampleOperationFunc() { // var op operation.Operation[ExampleRequest, ExampleResponse] = operation.OperationFunc[ExampleRequest, ExampleResponse](exampleOperation) // // resp, err := op.Do(context.Background(), ExampleRequest{Name: "World"}) // if err != nil { // panic(err) // } // // fmt.Print(resp.Greeting) // // Output: Hello, World // } // // func ExampleNew() { // op := operation.New(exampleOperation) // // resp, err := op.Do(context.Background(), ExampleRequest{Name: "World"}) // if err != nil { // panic(err) // } // // fmt.Print(resp.Greeting) // // Output: Hello, World // }
Output: Hello, World