{"schemaVersion":1,"id":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation","title":"Smithy: El Lenguaje de Modelado de APIs de AWS y Construcción de Generadores de SDK","description":"Análisis de Smithy, el lenguaje de modelado de APIs protocol-agnostic de AWS, su pipeline de generación de código, validadores personalizados, sistema de traits, y cómo construir un generador de SDK propio desde un modelo Smithy.","language":"es","datePublished":"2025-11-07","dateModified":null,"contentFormat":"text/markdown","content":"API Design\n\n# Smithy: El Lenguaje de Modelado de APIs de AWS y Construcción de Generadores de SDK\n\n2025-11-075 min lectura\n\nLucio Durán\nEngineering Manager & AI Solutions Architect\n\nTambién disponible en: [English](<https://lucioduran.com/blog/smithy-api-modeling-aws-sdk-generation>)\n\n## Por Qué Smithy Sobre OpenAPI\n\nOpenAPI describe APIs HTTP. Eso es tanto su fortaleza como su limitación. Cuando escribirs una spec OpenAPI, se está describiendo paths, métodos, request bodies, y response schemas. El transporte HTTP está metido en el modelo.\n\n[Smithy](<https://smithy.io/>) describe APIs. Punto. El transporte es una concern separada aplicada via protocol traits. Esto significa que el mismo modelo Smithy puede generar un SDK REST/JSON, un cliente gRPC, un cliente event-driven, documentación, y server stubs.\n\nAcá va cómo se ve un modelo Smithy para un servicio simple:\n\n```smithy\n$version: \"2\"\nnamespace com.example.inventory\nuse aws.protocols#restJson1\n\n@restJson1\n@title(\"Inventory Service\")\n@paginated(inputToken: \"nextToken\", outputToken: \"nextToken\", pageSize: \"maxResults\")\nservice InventoryService {\n version: \"2026-01-15\"\n operations: [ListProducts, GetProduct, CreateProduct, UpdateProduct, DeleteProduct]\n resources: [Product]\n}\n\nresource Product {\n identifiers: { productId: ProductId }\n read: GetProduct\n create: CreateProduct\n update: UpdateProduct\n delete: DeleteProduct\n list: ListProducts\n}\n\n@readonly\n@http(method: \"GET\", uri: \"/products/{productId}\")\noperation GetProduct {\n input := {\n @required @httpLabel\n productId: ProductId\n }\n output := {\n @required\n product: ProductShape\n }\n errors: [ProductNotFound, ValidationError]\n}\n\n@http(method: \"POST\", uri: \"/products\")\noperation CreateProduct {\n input := {\n @required name: String\n @required sku: String\n price: BigDecimal\n @length(min: 0, max: 10)\n tags: TagList\n metadata: MetadataMap\n }\n output := { @required product: ProductShape }\n errors: [ConflictError, ValidationError]\n}\n```\n\nObservar varias cosas:\n\n1. **Los recurse es son first-class.** ` Product ` se declara como un recurso con operaciones CRUD mapeadas. Esto no es solo documentación, el generador de código usa las relaciones de recurse es para generar métodos helper como ` product.refresh() ` o ` product.delete() `.\n2. **Las constraints están en el modelo.** ` @range(min: 1, max: 100) ` en ` maxResults ` significa que el SDK generado valida esto client-side antes de hacer un network call.\n3. **La paginación es declarativa.** El trait ` @paginated ` en el servicio y la operación le dice al generador que produzca helpers de auto-paginación.\n4. **Los errores son tipados.** Cada estructura de error mapea a un HTTP status code específico. El SDK generado produce clases de error tipadas que el caller puede catchear específicamente.\n\n## El Sistema de Traits\n\nLa característica más destacada de Smithy son los traits. Un trait es metadata adjunta a cualquier shape que modifica comportamiento o agrega información. [AWS](<https://aws.com/>) define cientos, pero es posible crear los tuyos:\n\n```smithy\n@trait(selector: \"operation\")\nstructure rateLimit {\n @required requestsPerSecond: Integer\n burstSize: Integer\n}\n\n@rateLimit(requestsPerSecond: 100, burstSize: 200)\noperation CreateProduct { ... }\n```\n\nNuestro trait custom ` @rateLimit ` le dice al generador de SDK que agregue rate limiting client-side. Estos no son solo anotaciones, manejan generación de código.\n\n## Validadores Custom\n\nSmithy tiene un pipeline de validación que corre sobre tu modelo antes de la generación de código. Escribimos validadores custom para enforcer nuestros estándares de diseño de API:\n\n```java\npublic final class PaginationValidator extends AbstractValidator {\n @Override\n public List<ValidationEvent> validate(Model model) {\n List<ValidationEvent> events = new ArrayList<>();\n\n for (OperationShape op : model.getOperationShapes()) {\n if (op.getId().getName().startsWith(\"List\")\n && !op.hasTrait(PaginatedTrait.class)) {\n events.add(danger(op,\n \"List operations must use the @paginated trait. \"\n + \"Operation: \" + op.getId()));\n }\n }\n\n for (StructureShape struct : model.getStructureShapes()) {\n boolean hasCreatedAt = struct.getMember(\"createdAt\").isPresent();\n boolean hasUpdatedAt = struct.getMember(\"updatedAt\").isPresent();\n if (hasCreatedAt && !hasUpdatedAt) {\n events.add(danger(struct,\n \"Structures with 'createdAt' must also have 'updatedAt'.\"));\n }\n }\n return events;\n }\n}\n```\n\nEste validador corre como parte de ` smithy build ` y falla el build si alguna operación de listado no está paginada o si los campos de auditoría de timestamps están incompletos. Atrapó tres configuraciones de paginación faltantes en nuestros modelos en la primera semana.\n\n## Armando un Generador de SDK Custom\n\nEl poder real viene cuando armars tu propio generador de código. El framework codegen de Smithy te da un modelo, un set de integraciones, y usted producís archivos. El TypeScript generado se ve así:\n\n```typescript\n// Generated by smithy-typescript-codegen - DO NOT EDIT\nexport interface Product {\n productId: string;\n name: string;\n sku: string;\n price?: number;\n tags?: string[];\n metadata?: Record<string, string>;\n createdAt: Date;\n updatedAt?: Date;\n}\n\nexport class ProductNotFoundError extends ServiceError {\n readonly name = 'ProductNotFound';\n readonly statusCode = 404;\n readonly productId?: string;\n}\n\nexport class InventoryServiceClient {\n private readonly http: HttpClient;\n\n constructor(config: ClientConfig) {\n this.http = new HttpClient(config);\n }\n\n async getProduct(input: GetProductInput, options?: RequestOptions): Promise<GetProductOutput> {\n if (!input.productId) throw new ValidationError('productId is required');\n return this.http.request({\n method: 'GET',\n path: `/products/${encodeURIComponent(input.productId)}`,\n ...options,\n });\n }\n\n async *paginateListProducts(\n input: ListProductsInput = {},\n options?: RequestOptions\n ): AsyncGenerator<Product[], void, undefined> {\n let nextToken = input.nextToken;\n do {\n const response = await this.listProducts({ ...input, nextToken }, options);\n yield response.products;\n nextToken = response.nextToken;\n } while (nextToken);\n }\n}\n```\n\nEl paginador se genera automáticamente porque ` ListProducts ` tiene el trait ` @paginated `. Las clases de error se generan porque la operación declara ` errors: [ProductNotFound, ValidationError] `. La lógica de validación se genera desde los traits ` @required ` y ` @range `.\n\n## El Pipeline de Build\n\nNuestro pipeline completo:\n\n```json\n{\n \"version\": \"1.0\",\n \"sources\": [\"model\"],\n \"plugins\": {\n \"openapi\": {\n \"service\": \"com.example.inventory#InventoryService\",\n \"protocol\": \"aws.protocols#restJson1\"\n },\n \"typescript-sdk\": {\n \"service\": \"com.example.inventory#InventoryService\",\n \"packageName\": \"@example/inventory-sdk\"\n },\n \"python-sdk\": {\n \"service\": \"com.example.inventory#InventoryService\",\n \"packageName\": \"example-inventory\"\n }\n }\n}\n```\n\nUn solo comando ` smithy build ` genera cuatro SDKs, una spec OpenAPI, y valida el modelo contra nuestros estándares. Los SDKs generados se publican a registries internos via CI. Cuando un ingeniero cambia el modelo Smithy y mergea, los cuatro SDKs se regeneran, se testean contra el servicio corriendo, y se publican, automáticamente.\n\n## ¿Valió la Pena?\n\nEl setup inicial tomó unas tres semanas, una semana aprendiendo Smithy, una semana armando los generadores de código, una semana cableando CI/CD. Desde entonces:\n\n- Zero drift entre SDKs y la API real\n- Operaciones nuevas van de cambio en el modelo a SDK publicado en 12 minutos\n- Los validadores custom previnieron 14 inconsistencias de diseño de API antes de que llegaran a producción\n- El onboarding de ingenieros al SDK es trivial, el código generado es consistente entre todos los servicios\n\nLa curva de aprendizaje de Smithy es más empinada que la de OpenAPI, y el toolchain Java-centric es un dolor si tu equipo no está cómodo con la JVM. Pero para generación de SDKs multi-lenguaje con type safety y validación baked-in, nada se le acerca. La inversión se paga sola en un trimestre.\n\n## Preguntas frecuentes\n\n### ¿Cómo se compara Smithy con OpenAPI?\n\nSmithy es protocol-agnostic (modela APIs, no endpoints HTTP), soporta modelado basado en recursos, tiene un sistema de traits built-in para extensibilidad, y genera SDKs más limpios. OpenAPI es más ampliamente adoptado, tiene mejor tooling para documentación REST, y es el estándar para APIs HTTP-specific. Smithy puede generar specs OpenAPI desde sus modelos.\n\n### ¿Puedo usar Smithy para proyectos que no sean de AWS?\n\nAbsolutamente. Smithy es un proyecto open-source bajo Apache 2.0. Aunque AWS lo usa internamente para todos sus servicios, el lenguaje y el tooling son completamente de propósito general. Es posible definir cualquier API, usar cualquier protocol binding, y generar SDKs para cualquier lenguaje.\n\n### ¿Para qué lenguajes puede Smithy generar SDKs?\n\nAWS mantiene oficialmente generadores para TypeScript, Python, Java, Go, Rust, C++, Swift, Kotlin, Ruby y PHP. La comunidad tiene generadores para C# y Dart. También es posible construir generadores personalizados usando el framework smithy-codegen.\n\n## Tips\n\n1. **LuchoTip:** El trait ` @paginated ` de Smithy es mucho más potente de lo que aparenta. Definirlo una vez en las operaciones de listado permite al generador de SDK producir automáticamente iteradores sincrónicos y helpers de paginación async. No construir un patrón de paginación propio.\n2. **LuchoTip:** Utilizar el trait ` @examples ` de Smithy en cada operación. Sirven como documentación, pero más importante, el generador de código puede convertirlos en scaffolding de tests de integración que validan el SDK contra respuestas reales de la API.\n3. **LuchoTip:** Al escribir validadores personalizados, siempre implementar ` AbstractValidator<Shape> ` en vez de verificar shapes manualmente en un plugin. Los validadores se componen correctamente en el pipeline de validación y sus diagnósticos aparecen en IDEs con source locations correctas.\n\n- smithy\n- api-design\n- aws\n- sdk-generation\n- code-generation\n- openapi\n- protocol-buffers\n- idl\n\n[Volver al Blog](<https://lucioduran.com/es/blog>)","headings":[{"level":1,"text":"Smithy: El Lenguaje de Modelado de APIs de AWS y Construcción de Generadores de SDK","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#title"},{"level":2,"text":"Por Qué Smithy Sobre OpenAPI","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#por-qu-smithy-sobre-openapi"},{"level":2,"text":"El Sistema de Traits","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#el-sistema-de-traits"},{"level":2,"text":"Validadores Custom","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#validadores-custom"},{"level":2,"text":"Armando un Generador de SDK Custom","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#armando-un-generador-de-sdk-custom"},{"level":2,"text":"El Pipeline de Build","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#el-pipeline-de-build"},{"level":2,"text":"¿Valió la Pena?","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#vali-la-pena"},{"level":2,"text":"Preguntas frecuentes","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#questions"},{"level":3,"text":"¿Cómo se compara Smithy con OpenAPI?","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#question-1"},{"level":3,"text":"¿Puedo usar Smithy para proyectos que no sean de AWS?","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#question-2"},{"level":3,"text":"¿Para qué lenguajes puede Smithy generar SDKs?","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#question-3"},{"level":2,"text":"Tips","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#article-tips"}],"sections":[{"heading":"Smithy: El Lenguaje de Modelado de APIs de AWS y Construcción de Generadores de SDK","level":1,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation","content":"API Design"},{"heading":"Smithy: El Lenguaje de Modelado de APIs de AWS y Construcción de Generadores de SDK","level":1,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#title","content":"2025-11-075 min lectura\n\nLucio Durán\nEngineering Manager & AI Solutions Architect\n\nTambién disponible en: [English](<https://lucioduran.com/blog/smithy-api-modeling-aws-sdk-generation>)"},{"heading":"Por Qué Smithy Sobre OpenAPI","level":2,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#por-qu-smithy-sobre-openapi","content":"OpenAPI describe APIs HTTP. Eso es tanto su fortaleza como su limitación. Cuando escribirs una spec OpenAPI, se está describiendo paths, métodos, request bodies, y response schemas. El transporte HTTP está metido en el modelo.\n\n[Smithy](<https://smithy.io/>) describe APIs. Punto. El transporte es una concern separada aplicada via protocol traits. Esto significa que el mismo modelo Smithy puede generar un SDK REST/JSON, un cliente gRPC, un cliente event-driven, documentación, y server stubs.\n\nAcá va cómo se ve un modelo Smithy para un servicio simple:\n\n```smithy\n$version: \"2\"\nnamespace com.example.inventory\nuse aws.protocols#restJson1\n\n@restJson1\n@title(\"Inventory Service\")\n@paginated(inputToken: \"nextToken\", outputToken: \"nextToken\", pageSize: \"maxResults\")\nservice InventoryService {\n version: \"2026-01-15\"\n operations: [ListProducts, GetProduct, CreateProduct, UpdateProduct, DeleteProduct]\n resources: [Product]\n}\n\nresource Product {\n identifiers: { productId: ProductId }\n read: GetProduct\n create: CreateProduct\n update: UpdateProduct\n delete: DeleteProduct\n list: ListProducts\n}\n\n@readonly\n@http(method: \"GET\", uri: \"/products/{productId}\")\noperation GetProduct {\n input := {\n @required @httpLabel\n productId: ProductId\n }\n output := {\n @required\n product: ProductShape\n }\n errors: [ProductNotFound, ValidationError]\n}\n\n@http(method: \"POST\", uri: \"/products\")\noperation CreateProduct {\n input := {\n @required name: String\n @required sku: String\n price: BigDecimal\n @length(min: 0, max: 10)\n tags: TagList\n metadata: MetadataMap\n }\n output := { @required product: ProductShape }\n errors: [ConflictError, ValidationError]\n}\n```\n\nObservar varias cosas:\n\n1. **Los recurse es son first-class.** ` Product ` se declara como un recurso con operaciones CRUD mapeadas. Esto no es solo documentación, el generador de código usa las relaciones de recurse es para generar métodos helper como ` product.refresh() ` o ` product.delete() `.\n2. **Las constraints están en el modelo.** ` @range(min: 1, max: 100) ` en ` maxResults ` significa que el SDK generado valida esto client-side antes de hacer un network call.\n3. **La paginación es declarativa.** El trait ` @paginated ` en el servicio y la operación le dice al generador que produzca helpers de auto-paginación.\n4. **Los errores son tipados.** Cada estructura de error mapea a un HTTP status code específico. El SDK generado produce clases de error tipadas que el caller puede catchear específicamente."},{"heading":"El Sistema de Traits","level":2,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#el-sistema-de-traits","content":"La característica más destacada de Smithy son los traits. Un trait es metadata adjunta a cualquier shape que modifica comportamiento o agrega información. [AWS](<https://aws.com/>) define cientos, pero es posible crear los tuyos:\n\n```smithy\n@trait(selector: \"operation\")\nstructure rateLimit {\n @required requestsPerSecond: Integer\n burstSize: Integer\n}\n\n@rateLimit(requestsPerSecond: 100, burstSize: 200)\noperation CreateProduct { ... }\n```\n\nNuestro trait custom ` @rateLimit ` le dice al generador de SDK que agregue rate limiting client-side. Estos no son solo anotaciones, manejan generación de código."},{"heading":"Validadores Custom","level":2,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#validadores-custom","content":"Smithy tiene un pipeline de validación que corre sobre tu modelo antes de la generación de código. Escribimos validadores custom para enforcer nuestros estándares de diseño de API:\n\n```java\npublic final class PaginationValidator extends AbstractValidator {\n @Override\n public List<ValidationEvent> validate(Model model) {\n List<ValidationEvent> events = new ArrayList<>();\n\n for (OperationShape op : model.getOperationShapes()) {\n if (op.getId().getName().startsWith(\"List\")\n && !op.hasTrait(PaginatedTrait.class)) {\n events.add(danger(op,\n \"List operations must use the @paginated trait. \"\n + \"Operation: \" + op.getId()));\n }\n }\n\n for (StructureShape struct : model.getStructureShapes()) {\n boolean hasCreatedAt = struct.getMember(\"createdAt\").isPresent();\n boolean hasUpdatedAt = struct.getMember(\"updatedAt\").isPresent();\n if (hasCreatedAt && !hasUpdatedAt) {\n events.add(danger(struct,\n \"Structures with 'createdAt' must also have 'updatedAt'.\"));\n }\n }\n return events;\n }\n}\n```\n\nEste validador corre como parte de ` smithy build ` y falla el build si alguna operación de listado no está paginada o si los campos de auditoría de timestamps están incompletos. Atrapó tres configuraciones de paginación faltantes en nuestros modelos en la primera semana."},{"heading":"Armando un Generador de SDK Custom","level":2,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#armando-un-generador-de-sdk-custom","content":"El poder real viene cuando armars tu propio generador de código. El framework codegen de Smithy te da un modelo, un set de integraciones, y usted producís archivos. El TypeScript generado se ve así:\n\n```typescript\n// Generated by smithy-typescript-codegen - DO NOT EDIT\nexport interface Product {\n productId: string;\n name: string;\n sku: string;\n price?: number;\n tags?: string[];\n metadata?: Record<string, string>;\n createdAt: Date;\n updatedAt?: Date;\n}\n\nexport class ProductNotFoundError extends ServiceError {\n readonly name = 'ProductNotFound';\n readonly statusCode = 404;\n readonly productId?: string;\n}\n\nexport class InventoryServiceClient {\n private readonly http: HttpClient;\n\n constructor(config: ClientConfig) {\n this.http = new HttpClient(config);\n }\n\n async getProduct(input: GetProductInput, options?: RequestOptions): Promise<GetProductOutput> {\n if (!input.productId) throw new ValidationError('productId is required');\n return this.http.request({\n method: 'GET',\n path: `/products/${encodeURIComponent(input.productId)}`,\n ...options,\n });\n }\n\n async *paginateListProducts(\n input: ListProductsInput = {},\n options?: RequestOptions\n ): AsyncGenerator<Product[], void, undefined> {\n let nextToken = input.nextToken;\n do {\n const response = await this.listProducts({ ...input, nextToken }, options);\n yield response.products;\n nextToken = response.nextToken;\n } while (nextToken);\n }\n}\n```\n\nEl paginador se genera automáticamente porque ` ListProducts ` tiene el trait ` @paginated `. Las clases de error se generan porque la operación declara ` errors: [ProductNotFound, ValidationError] `. La lógica de validación se genera desde los traits ` @required ` y ` @range `."},{"heading":"El Pipeline de Build","level":2,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#el-pipeline-de-build","content":"Nuestro pipeline completo:\n\n```json\n{\n \"version\": \"1.0\",\n \"sources\": [\"model\"],\n \"plugins\": {\n \"openapi\": {\n \"service\": \"com.example.inventory#InventoryService\",\n \"protocol\": \"aws.protocols#restJson1\"\n },\n \"typescript-sdk\": {\n \"service\": \"com.example.inventory#InventoryService\",\n \"packageName\": \"@example/inventory-sdk\"\n },\n \"python-sdk\": {\n \"service\": \"com.example.inventory#InventoryService\",\n \"packageName\": \"example-inventory\"\n }\n }\n}\n```\n\nUn solo comando ` smithy build ` genera cuatro SDKs, una spec OpenAPI, y valida el modelo contra nuestros estándares. Los SDKs generados se publican a registries internos via CI. Cuando un ingeniero cambia el modelo Smithy y mergea, los cuatro SDKs se regeneran, se testean contra el servicio corriendo, y se publican, automáticamente."},{"heading":"¿Valió la Pena?","level":2,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#vali-la-pena","content":"El setup inicial tomó unas tres semanas, una semana aprendiendo Smithy, una semana armando los generadores de código, una semana cableando CI/CD. Desde entonces:\n\n- Zero drift entre SDKs y la API real\n- Operaciones nuevas van de cambio en el modelo a SDK publicado en 12 minutos\n- Los validadores custom previnieron 14 inconsistencias de diseño de API antes de que llegaran a producción\n- El onboarding de ingenieros al SDK es trivial, el código generado es consistente entre todos los servicios\n\nLa curva de aprendizaje de Smithy es más empinada que la de OpenAPI, y el toolchain Java-centric es un dolor si tu equipo no está cómodo con la JVM. Pero para generación de SDKs multi-lenguaje con type safety y validación baked-in, nada se le acerca. La inversión se paga sola en un trimestre."},{"heading":"Preguntas frecuentes","level":2,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#questions","content":""},{"heading":"¿Cómo se compara Smithy con OpenAPI?","level":3,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#question-1","content":"Smithy es protocol-agnostic (modela APIs, no endpoints HTTP), soporta modelado basado en recursos, tiene un sistema de traits built-in para extensibilidad, y genera SDKs más limpios. OpenAPI es más ampliamente adoptado, tiene mejor tooling para documentación REST, y es el estándar para APIs HTTP-specific. Smithy puede generar specs OpenAPI desde sus modelos."},{"heading":"¿Puedo usar Smithy para proyectos que no sean de AWS?","level":3,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#question-2","content":"Absolutamente. Smithy es un proyecto open-source bajo Apache 2.0. Aunque AWS lo usa internamente para todos sus servicios, el lenguaje y el tooling son completamente de propósito general. Es posible definir cualquier API, usar cualquier protocol binding, y generar SDKs para cualquier lenguaje."},{"heading":"¿Para qué lenguajes puede Smithy generar SDKs?","level":3,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#question-3","content":"AWS mantiene oficialmente generadores para TypeScript, Python, Java, Go, Rust, C++, Swift, Kotlin, Ruby y PHP. La comunidad tiene generadores para C# y Dart. También es posible construir generadores personalizados usando el framework smithy-codegen."},{"heading":"Tips","level":2,"url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#article-tips","content":"1. **LuchoTip:** El trait ` @paginated ` de Smithy es mucho más potente de lo que aparenta. Definirlo una vez en las operaciones de listado permite al generador de SDK producir automáticamente iteradores sincrónicos y helpers de paginación async. No construir un patrón de paginación propio.\n2. **LuchoTip:** Utilizar el trait ` @examples ` de Smithy en cada operación. Sirven como documentación, pero más importante, el generador de código puede convertirlos en scaffolding de tests de integración que validan el SDK contra respuestas reales de la API.\n3. **LuchoTip:** Al escribir validadores personalizados, siempre implementar ` AbstractValidator<Shape> ` en vez de verificar shapes manualmente en un plugin. Los validadores se componen correctamente en el pipeline de validación y sus diagnósticos aparecen en IDEs con source locations correctas.\n\n- smithy\n- api-design\n- aws\n- sdk-generation\n- code-generation\n- openapi\n- protocol-buffers\n- idl\n\n[Volver al Blog](<https://lucioduran.com/es/blog>)"}],"links":[{"text":"English","url":"https://lucioduran.com/blog/smithy-api-modeling-aws-sdk-generation"},{"text":"Smithy","url":"https://smithy.io/"},{"text":"AWS","url":"https://aws.com/"},{"text":"Volver al Blog","url":"https://lucioduran.com/es/blog"}],"structuredData":[{"@context":"https://schema.org","@graph":[{"@type":"BlogPosting","@id":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation#article","mainEntityOfPage":{"@type":"WebPage","@id":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation"},"headline":"Smithy: El Lenguaje de Modelado de APIs de AWS y Construcción de Generadores de SDK","description":"Análisis de Smithy, el lenguaje de modelado de APIs protocol-agnostic de AWS, su pipeline de generación de código, validadores personalizados, sistema de traits, y cómo construir un generador de SDK propio desde un modelo Smithy.","datePublished":"2025-11-07","author":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"publisher":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"image":"https://lucioduran.com/favicons/og-default.png","url":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation","inLanguage":"es","isPartOf":{"@id":"https://lucioduran.com/blog#blog"},"articleSection":"API Design","keywords":"smithy, api-design, aws, sdk-generation, code-generation, openapi, protocol-buffers, idl","wordCount":976,"timeRequired":"PT5M","workTranslation":[{"@type":"BlogPosting","inLanguage":"en","url":"https://lucioduran.com/blog/smithy-api-modeling-aws-sdk-generation"}]},{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Inicio","item":"https://lucioduran.com/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https://lucioduran.com/es/blog"},{"@type":"ListItem","position":3,"name":"Smithy: El Lenguaje de Modelado de APIs de AWS y Construcción de Generadores de SDK","item":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation"}]},{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"¿Cómo se compara Smithy con OpenAPI?","acceptedAnswer":{"@type":"Answer","text":"Smithy es protocol-agnostic (modela APIs, no endpoints HTTP), soporta modelado basado en recursos, tiene un sistema de traits built-in para extensibilidad, y genera SDKs más limpios. OpenAPI es más ampliamente adoptado, tiene mejor tooling para documentación REST, y es el estándar para APIs HTTP-specific. Smithy puede generar specs OpenAPI desde sus modelos."}},{"@type":"Question","name":"¿Puedo usar Smithy para proyectos que no sean de AWS?","acceptedAnswer":{"@type":"Answer","text":"Absolutamente. Smithy es un proyecto open-source bajo Apache 2.0. Aunque AWS lo usa internamente para todos sus servicios, el lenguaje y el tooling son completamente de propósito general. Es posible definir cualquier API, usar cualquier protocol binding, y generar SDKs para cualquier lenguaje."}},{"@type":"Question","name":"¿Para qué lenguajes puede Smithy generar SDKs?","acceptedAnswer":{"@type":"Answer","text":"AWS mantiene oficialmente generadores para TypeScript, Python, Java, Go, Rust, C++, Swift, Kotlin, Ruby y PHP. La comunidad tiene generadores para C# y Dart. También es posible construir generadores personalizados usando el framework smithy-codegen."}}]}]}],"contentHash":"8c329babbfa26b5e257abc1d3cd2aac9243b8204e3ff222b7311ffcb4fc73c8f","provenance":{"method":"Deterministic serialization of the server-rendered main element","source":"https://lucioduran.com/es/blog/smithy-api-modeling-aws-sdk-generation","hashAlgorithm":"sha256","hashScope":"JSON document fields before contentHash and provenance","sourceHTMLBytes":56589,"contentBytes":10220}}
