18. Shape closures¶
A shape closure is a named set of shapes that consumers, such as code generators, can refer to by id. Closures are declared in model metadata and consumed by tools that need to operate on a discrete subset of the model without anchoring that subset to a service.
18.1. Shape closures vs. service closures¶
A service closure is the set of shapes connected to a service through resources, operations, and members. The membership of a service closure is implicit in the model. It is determined by traversing neighbor relationships from a service shape, and any tool that wants to operate on it just needs the service id.
A shape closure is intentionally decoupled from services. Its shapes are specified by namespace or selector and the result is identified by an id that does not correspond to any shape in the model.
This makes shape closures the right tool when a service is not needed. For example, a code generator may want to generate types without a service or client wrapper. This is also useful for modeling events that aren't part of an operation response.
18.2. shapeClosures metadata¶
Shape closures are declared with the shapeClosures metadata key. The
value is a list of ShapeClosure structures with the following members:
Property |
Type |
Description |
|---|---|---|
id |
|
Required. The namespaced identifier of the closure (for example,
This identifier is not intended to be semantically significant. The requirement for a namespace is intended to reduce the chance for naming collisions, not to suggest the namespace that any generated artifacts must be generated into. |
includeNamespaces |
|
Namespaces whose shapes are included in the closure. |
includeBySelector |
|
A selector whose matched shapes are included in the closure. |
rename |
map of shape ID to |
Disambiguates shape name conflicts in the closure. Map keys are
shape IDs contained in the closure, and map values are the
disambiguated shape names to use in the context of the closure.
Each given shape ID MUST reference a shape contained in the
closure. Each given map value MUST match the
|
A closure MUST define at least one of includeNamespaces or
includeBySelector.
The resolved closure is expanded transitively through directed neighbor
relationships from every shape matched by includeNamespaces or
includeBySelector.
18.3. Example¶
$version: "2"
metadata shapeClosures = [
{
id: "com.example#EventShapes"
includeNamespaces: ["com.example"]
}
]
namespace com.example
structure Event {
message: String
}
Tools that consume a closure use its id to look up the set of shapes to operate on. For example, a code generator might generate types for every shape in the named closure, or the includeClosures build transform might filter the model down to those shapes.