Documentation
¶
Overview ¶
Package sdk turns typed Go functions into an Orchard external provider, so an application can expose its own code (create a user, seed a tenant) as scenario actions without handling the protocol by hand.
p := sdk.New("app", "0.1.0")
p.Configure(func(ctx context.Context, c Config) error { ... })
p.Action("app_create_user", "Create a user.", func(ctx context.Context, in CreateUser) (User, error) { ... })
if err := p.Serve(); err != nil {
log.Fatal(err)
}
Attribute and output names, and how values convert, follow encoding/json: a field's name is its json tag, and a type that implements encoding.TextMarshaler (time.Time, most ID types) is a string. A field is optional when it is a pointer or tagged omitempty. A `doc:"..."` tag becomes the attribute's description.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Provider ¶
type Provider struct {
// Description is the provider's intro text in its schema and docs.
Description string
// contains filtered or unexported fields
}
Provider collects the configure function and actions, and serves them.
func New ¶
New returns a provider with no actions. name is the provider's name in its schema; scenarios pick their own local name for it.
func (*Provider) Action ¶
Action registers fn as the action type name. fn has one of these shapes, where In and Out are structs (or pointers to them):
func(context.Context, In) (Out, error) func(context.Context, In) error func(context.Context) (Out, error) func(context.Context) error
In's fields are the action's attributes and Out's fields its outputs. Name it `<provider>_<verb>`, like the builtins. It panics if fn has the wrong shape or name is taken.
func (*Provider) Configure ¶
Configure registers fn, of type func(context.Context, C) error, to receive the scenario's `provider` block. C is a struct whose fields are the block's attributes. It runs once, before any action; open connections there. It panics if fn has the wrong shape.
func (*Provider) Serve ¶
Serve runs the provider. With a `schema` argument, as `orchard plan` runs it, it prints the schema and returns. Otherwise it answers requests on stdin and stdout until Orchard shuts it down.
Anything else writing to stdout would corrupt the protocol, so Serve points os.Stdout at stderr, which Orchard logs.
ponytail: code that writes to file descriptor 1 directly, not through os.Stdout, still corrupts it; redirect the descriptor if that turns up.
func (*Provider) Undo ¶
Undo gives action an automatic teardown: after it succeeds, fn turns its input and output into the input of undoAction, Orchard records that call, and `orchard teardown` runs it. fn takes action's input struct and then its output struct, leaving out either one action doesn't have, and returns undoAction's input struct:
p.Undo("app_create_user", "app_delete_user",
func(in CreateUser, out User) DeleteUser { return DeleteUser{ID: out.ID} })
Returning a nil pointer records no undo for that run. A scenario's `lifecycle { teardown { } }` block or `managed_teardown = false` replaces it. Register both actions first; Undo panics if they're missing or fn doesn't fit them.