Smithy Projects
Smithy is an interface definition language for describing services and the data they exchange. The Smithy project generator creates a project containing a Smithy model.
There are two kinds of Smithy project:
- Service (
--type=service) — a model which defines a service and its operations. This is what thets#api --framework=smithygenerator creates for you alongside a TypeScript implementation. - Shape library (
--type=shapes) — a model which defines reusable shapes but no service. Connect a shape library to your Smithy projects to share shapes between them, rather than duplicating the definitions in each.
Generate a Smithy Project
Section titled “Generate a Smithy Project”- Install the Nx Console VSCode Plugin if you haven't already
- Open the Nx Console in VSCode
- Click
Generate (UI)in the "Common Nx Commands" section - Search for
@aws/nx-plugin - smithy#project - Fill in the required parameters
- name: my-shapes
- Click
Generate
pnpm nx g @aws/nx-plugin:smithy#project --name=my-shapesyarn nx g @aws/nx-plugin:smithy#project --name=my-shapesnpx nx g @aws/nx-plugin:smithy#project --name=my-shapesbunx nx g @aws/nx-plugin:smithy#project --name=my-shapesYou can also perform a dry-run to see what files would be changed
pnpm nx g @aws/nx-plugin:smithy#project --name=my-shapes --dry-runyarn nx g @aws/nx-plugin:smithy#project --name=my-shapes --dry-runnpx nx g @aws/nx-plugin:smithy#project --name=my-shapes --dry-runbunx nx g @aws/nx-plugin:smithy#project --name=my-shapes --dry-runOptions
Section titled “Options”| Parameter | Type | Default | Description |
|---|---|---|---|
| name Required | string | - | Smithy project name |
| type | service | shapes | service | The type of Smithy project to create. Choose between service (a model with a service shape, ready for an implementation) and shapes (a shape library of reusable shapes, shared between multiple Smithy projects). |
| serviceName | string | - | The name of your Smithy service. Uses the supplied name by default. Not applicable to shape libraries. |
| namespace | string | - | The namespace for the Smithy API. Defaults to your monorepo scope |
| directory | string | packages | Parent directory where the Smithy project is placed. |
| subDirectory | string | - | The sub directory the Smithy project is placed in. By default this is the project name. |
| preferInstallDependencies | boolean | true | Whether to prefer installing dependencies after the generator runs. Set to false to defer installing when batching multiple generators (an install still runs if needed so subsequent generators can compute the Nx project graph); install once at the end. |
Generator Output
Section titled “Generator Output”Shape Library
Section titled “Shape Library”Directorymy-shapes
Directorysrc
- main.smithy Your shared shape definitions
- smithy-build.json Smithy build configuration
- build.Dockerfile Builds and validates the model
- project.json Project configuration and build targets
A shape library defines shapes and nothing else:
$version: "2.0"
namespace com.example
structure Customer { @required id: String
name: String email: String}Since a shape library has no service, its smithy-build.json configures no code generation — building it validates the model and assembles it into a single JSON model file at dist/<my-shapes>/build/model/model.json.
Service
Section titled “Service”Directorymy-service
Directorysrc
- main.smithy Your service definition
Directoryoperations
- echo.smithy An example operation
- smithy-build.json Smithy build configuration, including code generation
- build.Dockerfile Builds the model, OpenAPI spec and TypeScript Server SDK
- project.json Project configuration and build targets
A service model defines a service shape and the operations it exposes:
$version: "2.0"
namespace com.example
use aws.protocols#restJson1
@title("MyService")@restJson1service MyService { version: "1.0.0" operations: [ Echo ]}Building a service project generates an OpenAPI specification and a TypeScript Server SDK into dist/<my-service>/build/.
Building
Section titled “Building”Smithy projects build using Docker, which runs the Smithy CLI to validate your model:
pnpm nx build my-shapesyarn nx build my-shapesnpx nx build my-shapesbunx nx build my-shapesDepending on a Shape Library
Section titled “Depending on a Shape Library”Building a shape library writes an assembled model to dist/<my-shapes>/build/model/model.json. This single file contains every shape the library defines, along with any it depends on, so a consumer only ever declares the libraries it references directly.
To depend on a shape library from another Smithy project, make three changes to the consuming project:
-
Smithy projects build inside a container, and the build is given the workspace root as a named build context. Add a
COPYto the consuming project’sbuild.Dockerfile, alongside where its own sources are copied in:# Copy project filesCOPY smithy-build.json .COPY src srcCOPY --from=workspace dist/packages/my-shapes/build/model/model.json deps/my-shapes.json -
Add the copied file to
importsin the consuming project’ssmithy-build.json:{"version": "1.0","sources": ["src/"],"imports": ["deps/my-shapes.json"],...} -
Add the library’s
buildtarget as a dependency of the consuming project’scompiletarget in itsproject.json, so the model exists before the consumer builds:{"targets": {"compile": {"dependsOn": ["@my-scope/my-shapes:build"],...}}}
Your model can now reference the library’s shapes with use:
$version: "2.0"
namespace com.example.api
use com.example.shared#Customer
structure GetCustomerOutput { @required customer: Customer}Shape libraries can depend on other shape libraries the same way. Since each library’s built model already contains its own dependencies, you only need to repeat these steps for the libraries you reference directly. A library reached by more than one path is resolved once — Smithy ignores duplicate but equivalent shape definitions.