Documentation
¶
Overview ¶
Package builder generates the doors of an application (REST routes on echo, gRPC services, MCP tools and event functions) from @REST, @GRPC, @MCP and @Function annotations, on top of the fx modules generated by inject.
Index ¶
- func CollectEntries(path string) ([]annotation.Entry, error)
- func Generate(ctx context.Context, src, out, cmd string) error
- func Stale(ctx context.Context, src, out, cmd string) ([]string, error)
- type App
- type Function
- type Generator
- type Handler
- type Kind
- type Middleware
- type Options
- type PackageLoader
- type Receiver
- type Route
- type Server
- type Service
- type Spec
- type Tool
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CollectEntries ¶
func CollectEntries(path string) ([]annotation.Entry, error)
CollectEntries returns the declarations under path, and in the packages they import, annotated with a door (@REST, @GRPC, @MCP, @Function) or with the inject annotations (@Provide, @Inject, @Invoke, @Default, @Config) that build their receivers, and the @Middleware of constructors.
func Generate ¶ added in v1.3.0
Generate writes the inject modules and the doors of the annotations under src to out, and the main of every app to cmd (none when cmd is empty): what cmd/builder does. It writes nothing when an annotation is not valid or the main of an app was written by hand.
func Stale ¶ added in v1.3.0
Stale returns the files Generate would write, change or remove under out and cmd, as slash-separated paths relative to src, sorted; none when the generated code is up to date. It writes nothing, so a test of the application can fail when gen/ or a main is stale:
stale, err := builder.Stale(ctx, ".", "gen", "cmd")
Types ¶
type App ¶
type App struct {
Name string
Servers []Server // sorted by name
Function *Function // nil when the app has no @Function
// Middlewares are the @Middleware of the constructors the doors of the
// app build, sorted by constructor.
Middlewares []Middleware
}
App is one binary: its servers and, optionally, its event function.
type Function ¶
type Function struct {
// Adapter is the adapter of adapter=x, or the first of adapter=[x, y]:
// the one wired when <app>.function.adapter is unset.
Adapter string
// Alternatives are the other adapters of adapter=[x, y], in order, that
// <app>.function.adapter may choose instead. Empty for a single adapter.
Alternatives []string
Handler Handler
Middlewares []string // middleware names, the outermost first
// Providers are the inject constructors of the values the middlewares
// are built with, like the publisher.Driver of publisher. Sorted by key.
Providers []inject.Component
// ClientProviders are the inject constructors of the default clients the
// adapters read with, by client type ("<import path>.<Type>"). inject
// builds the default client of a type no constructor provides.
ClientProviders map[string]inject.Component
}
Function is a @Function annotation: the event handler of a function app, the adapter that feeds it and the middlewares it runs around the handler.
type Generator ¶
type Generator struct {
// contains filtered or unexported fields
}
Generator writes, under OutputDir/builder/<app>, one fx module per door of the app (a REST or gRPC server, or the function) and a modules.go whose Modules() returns all of them and the decorators of the app's @Middleware, written under OutputDir/builder/middleware/<import path>, and under CmdDir/<app> the main that runs them.
func NewGenerator ¶
NewGenerator returns a generator for the spec.
func (*Generator) Generate ¶
Generate writes the doors under OutputDir/builder and the mains under CmdDir, and removes the builder files of previous runs that are no longer produced. Nothing is written when one of them cannot be rendered.
func (*Generator) Render ¶
Render returns the generated files keyed by their slash-separated path relative to OutputDir (builder/<app>/... and builder/middleware/...), without touching the disk.
type Handler ¶
type Handler struct {
Entry annotation.Entry
// Receiver is how a method gets its receiver; nil for a package function.
Receiver *Receiver
}
Handler is the annotated function or method serving a door.
type Middleware ¶
type Middleware struct {
Provider inject.Component // the annotated constructor
Index int // result index of the interface value
Plugins []string // plugin names, the outermost first
Interface *types.Named // the provided interface
// Implementation is the implementation set the constructor is a member
// of (@Default): the decorator runs only when config chooses it. Nil
// for a constructor that is the only provider of its value.
Implementation *inject.Implementation
}
Middleware is a @Middleware annotation: the plugins run around every method of the interface its constructor provides.
type Options ¶
type Options struct {
inject.GeneratorOptions
// CmdDir receives <app>/main.go for every app; it must be inside the
// module. Empty, no main is generated.
CmdDir string
}
Options are the options of the inject generator of the same application, whose modules the doors include, and the directory of the mains.
type PackageLoader ¶
PackageLoader returns the type-checked packages at the import paths, keyed by path. NewSpec uses it to read the interfaces @Middleware decorates.
func LoadPackages ¶
func LoadPackages(dir string) PackageLoader
LoadPackages returns a PackageLoader that loads the packages with go/packages from dir, which must be inside the module that imports them.
type Receiver ¶
type Receiver struct {
Type string // provided type as written in the handler's package: "*Handler" or "Handler"
Provider inject.Component
}
Receiver is the inject component providing the receiver of a handler method.
type Server ¶
type Server struct {
App string
Name string
Kind Kind
Routes []Route // KindREST, sorted by path then method
Services []Service // KindGRPC, sorted by register function
Tools []Tool // KindMCP, sorted by name
// Plugins are the inject constructors of the []Plugin the server is built
// with: the value named after the server, or the default (unnamed) value
// for rest, grpc and mcp. Sorted by key.
Plugins []inject.Component
// PluginsName is the name Plugins are provided under, empty for the
// default value and when there are no Plugins.
PluginsName string
}
Server is one echo, gRPC or MCP server of an app, with its own config path.
type Service ¶
type Service struct {
Register string // register function as written in the constructor's file
Provider inject.Component // the annotated constructor
Index int // result index of the service value
}
Service is a @GRPC annotation: the value provided by an inject constructor, registered with a generated Register<Service>Server function.
type Spec ¶
type Spec struct {
Apps []App // sorted by name
}
Spec is every door declared by the annotations, grouped by application.
func NewSpec ¶
func NewSpec(entries []annotation.Entry, g *graph.Graph[inject.Component], load PackageLoader) (*Spec, error)
NewSpec builds the doors declared by the @REST, @GRPC, @MCP and @Function annotations of entries, and the @Middleware of the constructors each app builds. g is the inject graph of the same entries: it provides the receivers of handler methods and the values of @GRPC constructors. load reads the interfaces @Middleware decorates; it is only called, once, when there is a @Middleware.
It returns NotValid for malformed annotations and for handlers that are unexported, in package main or whose signature does not match their door, NotFound when the receiver of a handler method or a value a @Function middleware needs has no provider, and AlreadyExists for a duplicate route, service or tool, for a second @Function in an app, for two @Middleware that decorate the same interface and for a rest, grpc or mcp server given both a named and an unnamed []Plugin.
func (Spec) DefaultClients ¶ added in v1.6.1
DefaultClients returns the client types ("<import path>.<Type>") the adapters of the functions read with that no inject constructor provides, sorted: inject generates their default client for the function doors.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
builder
command
Command builder generates the inject modules, the door modules and the main of every app from the annotations of an application, in one pass.
|
Command builder generates the inject modules, the door modules and the main of every app from the annotations of an application, in one pass. |
|
examples
|
|
|
simple
Package simple is an application whose doors come from builder annotations: app api serves REST routes on two echo servers (rest and admin), a gRPC health service and the check_stock MCP tool; app worker records the orders of order.created events.
|
Package simple is an application whose doors come from builder annotations: app api serves REST routes on two echo servers (rest and admin), a gRPC health service and the check_stock MCP tool; app worker records the orders of order.created events. |
|
simple/cmd/api
command
Command api runs app api: the doors builder generates in github.com/xgodev/boost/builder/examples/simple/gen/builder/api.
|
Command api runs app api: the doors builder generates in github.com/xgodev/boost/builder/examples/simple/gen/builder/api. |
|
simple/cmd/worker
command
Command worker runs app worker: the doors builder generates in github.com/xgodev/boost/builder/examples/simple/gen/builder/worker.
|
Command worker runs app worker: the doors builder generates in github.com/xgodev/boost/builder/examples/simple/gen/builder/worker. |
|
simple/createorder
Package createorder serves the order routes of app api.
|
Package createorder serves the order routes of app api. |
|
simple/healthcheck
Package healthcheck serves grpc.health.v1.Health on the grpc server of app api.
|
Package healthcheck serves grpc.health.v1.Health on the grpc server of app api. |
|
simple/order
Package order keeps the orders of the example in memory.
|
Package order keeps the orders of the example in memory. |
|
simple/ordercreated
Package ordercreated records the orders of order.created events in app worker.
|
Package ordercreated records the orders of order.created events in app worker. |
|
simple/probe
Package probe answers the liveness probe on the admin server of app api, apart from the public routes.
|
Package probe answers the liveness probe on the admin server of app api, apart from the public routes. |
|
simple/stock
Package stock tells whether an item can be ordered.
|
Package stock tells whether an item can be ordered. |
|
simple/stock/memory
Package memory keeps the stock in memory.
|
Package memory keeps the stock in memory. |
|
simple/stock/remote
Package remote asks a warehouse over HTTP for the stock.
|
Package remote asks a warehouse over HTTP for the stock. |
|
simple/stock/unlimited
Package unlimited is a stock without limits.
|
Package unlimited is a stock without limits. |
|
simple/stocktool
Package stocktool serves the stock tools of app api over MCP.
|
Package stocktool serves the stock tools of app api over MCP. |