Smithy IDL Skill
Smithy is a protocol-agnostic interface definition language (IDL) created by AWS for defining service APIs. It supports generating clients, servers, and documentation from a single model.
File Structure
Every Smithy file has three ordered sections:
$version: "2" // 1. Control section (required) metadata key = "value" // 2. Metadata section (optional) namespace example.service // 3. Shape section (required before shapes) // Shapes and traits defined here
Core Syntax Rules
- •Files MUST be UTF-8 encoded
- •Use
$version: "2"for Smithy 2.0 (current version) - •Commas are optional whitespace (omit them in 2.0)
- •Comments:
//for line comments,///for documentation - •Namespace required before any shapes:
namespace com.example
Shape Types
Simple Types
string MyString integer MyInt boolean MyBool blob MyBlob timestamp MyTimestamp
Enums
enum Status {
PENDING = "pending"
ACTIVE = "active"
INACTIVE = "inactive"
}
intEnum Priority {
LOW = 1
MEDIUM = 2
HIGH = 3
}
Collections
list StringList {
member: String
}
map StringToIntMap {
key: String
value: Integer
}
Structures
structure User {
@required
id: String
name: String
/// Optional with default
active: Boolean = true
}
Unions (tagged unions/discriminated unions)
union PaymentMethod {
creditCard: CreditCard
bankTransfer: BankTransfer
cash: Unit
}
Service Definition
$version: "2"
namespace example.shop
/// E-commerce service for managing products
@title("Shop API")
service ShopService {
version: "2024-01-01"
operations: [
GetProduct
ListProducts
CreateProduct
]
resources: [
Product
]
}
Operations
Define input and output as concrete structures:
/// Get a product by ID
@readonly
@http(method: "GET", uri: "/products/{productId}")
operation GetProduct {
input: GetProductInput
output: GetProductOutput
errors: [
NotFoundError
ValidationError
]
}
@input
structure GetProductInput {
@required
@httpLabel
productId: String
}
@output
structure GetProductOutput {
@required
product: Product
}
Always use concrete structures for input/output rather than inline := syntax. This improves:
- •Reusability across operations
- •Code generation quality
- •Documentation clarity
- •Type sharing between operations
Resources
resource Product {
identifiers: {
productId: String
}
properties: {
name: String
price: Integer
description: String
}
read: GetProduct
create: CreateProduct
update: UpdateProduct
delete: DeleteProduct
list: ListProducts
}
Common Traits
Documentation
/// Triple-slash for shape documentation
@documentation("Alternative documentation trait")
@externalDocumentation(url: "https://docs.example.com")
Constraints
@required // Member must be present
@length(min: 1, max: 100) // String/list length
@range(min: 0, max: 1000) // Numeric range
@pattern("^[a-z]+$") // Regex pattern
@uniqueItems // List has unique items
Nullability and Defaults
structure Example {
@required
requiredField: String // Never null
optionalField: String // Can be null/absent
defaultField: String = "hello" // Has default value
}
HTTP Bindings
@http(method: "POST", uri: "/users")
@httpLabel // Path parameter
@httpQuery("name") // Query parameter
@httpHeader("X-Id") // Header
@httpPayload // Request/response body
Error Traits
@error("client") // 4xx error
@error("server") // 5xx error
@httpError(404) // Specific HTTP status
Mixins
Reduce duplication by sharing members across structures:
@mixin
structure TimestampMixin {
createdAt: Timestamp
updatedAt: Timestamp
}
structure User with [TimestampMixin] {
@required
id: String
name: String
}
Target Elision
Reference resource properties without explicit targets:
resource User {
identifiers: { userId: String }
properties: { name: String, email: String }
}
structure GetUserOutput for User {
$userId // Automatically targets String from resource
$name
$email
}
Converting APIs from URLs
When given a URL to convert to Smithy:
- •Fetch the URL using
web_fetchto retrieve the content - •Identify the format: OpenAPI/Swagger, GraphQL, HTML docs, JSON Schema, etc.
- •Extract: Types, endpoints, parameters, responses, errors
- •Convert to Smithy following patterns in references/conversions.md
Quick Conversion Steps
URL → Fetch → Parse → Extract types/operations → Generate Smithy
For OpenAPI/Swagger:
- •paths → operations with @http traits
- •schemas/definitions → structures
- •parameters → input members with @httpLabel/@httpQuery/@httpHeader
- •responses → output structures and errors
For HTML API docs:
- •Identify endpoint tables/lists
- •Extract request/response examples
- •Infer types from examples
For GraphQL:
- •types → structures
- •queries → @readonly operations
- •mutations → operations
- •enums → enum shapes
Always generate complete, valid Smithy 2.0 with proper namespace, version, and service definition.
Best Practices
- •Always specify version: Start files with
$version: "2" - •Use documentation comments:
///before shapes - •Use concrete input/output structures: Define separate structures with
@input/@outputtraits - •Apply constraints: Use
@required,@length,@rangeappropriately - •Group related shapes: Keep services, operations, and their structures together
- •Use resources for CRUD: Model entities with lifecycle operations as resources
- •Use mixins: Share common fields like timestamps, pagination
Reference Files
- •references/conversions.md: Converting APIs from URLs (OpenAPI, GraphQL, HTML docs, etc.)
- •references/shapes.md: Detailed shape type reference
- •references/traits.md: Complete trait reference with examples
- •references/http-bindings.md: HTTP protocol patterns
- •references/examples.md: Complete service examples