Ir al contenido

Smithy TypeScript API

Filter this guidePick generator option values to hide sections that don't apply.

Smithy es un lenguaje de definición de interfaces independiente del protocolo para crear APIs de manera modelada.

El generador de API TypeScript para Smithy crea una nueva API usando Smithy para la definición del servicio y el SDK de servidor TypeScript para Smithy para la implementación. El generador provee infraestructura como código con CDK o Terraform para desplegar tu servicio en AWS Lambda, expuesto a través de una API REST de AWS API Gateway. Ofrece desarrollo de APIs con seguridad de tipos mediante generación automática de código a partir de modelos Smithy. El manejador generado utiliza AWS Lambda Powertools para TypeScript para observabilidad, incluyendo registro, trazado con AWS X-Ray y métricas de CloudWatch.

Puedes generar una nueva API TypeScript con Smithy de dos formas:

  1. Instale el Nx Console VSCode Plugin si aún no lo ha hecho
  2. Abra la consola Nx en VSCode
  3. Haga clic en Generate (UI) en la sección "Common Nx Commands"
  4. Busque @aws/nx-plugin - ts#api
  5. Complete los parámetros requeridos
    • framework: smithy
  6. Haga clic en Generate
ParámetroTipoPredeterminadoDescripción
name Requeridostring-El nombre de la API (requerido). Se utiliza para generar nombres de clases y rutas de archivos.
framework trpc | smithytrpcEl framework de API a utilizar.
namespace string-El espacio de nombres para la API Smithy (solo aplicable para el framework smithy). Por defecto es el alcance de tu monorepo
integrationPattern isolated | sharedisolatedCómo se generan las integraciones de API Gateway para la API. Elija entre isolated (predeterminado) y shared.
auth iam | cognito | customiamEl método utilizado para autenticar con tu API. Elige entre iam (predeterminado), cognito o custom.
directory stringpackagesEl directorio donde almacenar la aplicación.
subDirectory string-El subdirectorio en el que se coloca el proyecto. Por defecto es el nombre del proyecto.
iac inherit | cdk | terraforminheritEl proveedor de IaC preferido. Por defecto, se hereda de tu selección inicial.
infra rest-lambda | http-lambda | nonerest-lambdaEl tipo de infraestructura a utilizar para desplegar esta API.
preferInstallDependencies booleantrueSi se prefiere instalar las dependencias después de que se ejecute el generador. Establece en false para diferir la instalación cuando se ejecutan múltiples generadores en lote (la instalación aún se ejecuta si es necesario para que los generadores subsecuentes puedan calcular el grafo de proyectos de Nx); instala una vez al final.

El generador crea dos proyectos relacionados en el directorio <directory>/<api-name>:

  • Directoriomodel/ Proyecto del modelo Smithy
    • project.json Configuración del proyecto y objetivos de build
    • smithy-build.json Configuración de build para Smithy
    • build.Dockerfile Configuración de Docker para construir artefactos Smithy
    • Directoriosrc/
      • main.smithy Definición principal del servicio
      • Directoriooperations/
        • echo.smithy Definición de operación de ejemplo
  • Directoriobackend/ Implementación del backend en TypeScript
    • project.json Configuración del proyecto y objetivos de build
    • rolldown.config.ts Configuración de bundling
    • Directoriosrc/
      • handler.ts Manejador de AWS Lambda
      • local-server.ts Servidor local para desarrollo
      • service.ts Implementación del servicio
      • context.ts Definición del contexto del servicio
      • Directoriooperations/
        • echo.ts Implementación de operación de ejemplo
      • Directoriogenerated/ SDK TypeScript generado (creado durante el build)

Dado que este generador crea infraestructura como código según el iacProvider seleccionado, generará un proyecto en packages/common que incluye los constructos CDK o módulos Terraform relevantes.

El proyecto común de infraestructura como código tiene la siguiente estructura:

  • Directoriopackages/common/constructs
    • Directoriosrc
      • Directorioapp/ Constructos para infraestructura específica de un proyecto/generador
        • Directorioapis/
          • <project-name>.ts Constructo CDK para desplegar tu API
      • Directoriocore/ Constructos genéricos reutilizables por los de app
        • Directorioapi/
          • rest-api.ts Constructo CDK para desplegar una API REST
          • utils.ts Utilidades para los constructos de API
      • index.ts Punto de entrada que exporta los constructos de app
    • project.json Objetivos de build y configuración del proyecto

La API Smithy desplegada tiene la siguiente arquitectura, con un Web ACL de AWS WAFv2 frente al stage de API Gateway:

ClientWAFAPI Gateway(REST API)Lambda(Smithy Server SDK)CloudWatch(Logs, Metrics)X-Ray(Traces)

Las operaciones se definen en archivos Smithy dentro del proyecto del modelo. La definición principal del servicio está en main.smithy:

$version: "2.0"
namespace your.namespace
use aws.protocols#restJson1
use smithy.framework#ValidationException
@title("YourService")
@restJson1
service YourService {
version: "1.0.0"
operations: [
Echo,
// Add your operations here
]
errors: [
ValidationException
]
}

Las operaciones individuales se definen en archivos separados en el directorio operations/:

$version: "2.0"
namespace your.namespace
@http(method: "POST", uri: "/echo")
operation Echo {
input: EchoInput
output: EchoOutput
}
structure EchoInput {
@required
message: String
foo: Integer
bar: String
}
structure EchoOutput {
@required
message: String
}

Las implementaciones de operaciones se encuentran en el directorio src/operations/ del proyecto backend. Cada operación se implementa usando los tipos generados del SDK de servidor TypeScript (generados en tiempo de build a partir de tu modelo Smithy).

import { ServiceContext } from '../context.js';
import { Echo as EchoOperation } from '../generated/ssdk/index.js';
export const Echo: EchoOperation<ServiceContext> = async (input) => {
// Your business logic here
return {
message: `Echo: ${input.message}` // type-safe based on your Smithy model
};
};

Las operaciones deben registrarse en la definición del servicio en src/service.ts:

import { ServiceContext } from './context.js';
import { YourServiceService } from './generated/ssdk/index.js';
import { Echo } from './operations/echo.js';
// Import other operations here
// Register operations to the service here
export const Service: YourServiceService<ServiceContext> = {
Echo,
// Add other operations here
};

Puedes definir un contexto compartido para tus operaciones en context.ts:

export interface ServiceContext {
// Powertools tracer, logger and metrics are provided by default
tracer: Tracer;
logger: Logger;
metrics: Metrics;
// Add shared dependencies, database connections, etc.
dbClient: any;
userIdentity: string;
}

Este contexto se pasa a todas las implementaciones de operaciones y puede usarse para compartir recursos como conexiones a bases de datos, configuración o utilidades de registro.

El generador configura registro estructurado usando AWS Lambda Powertools con inyección automática de contexto mediante middleware Middy.

handler.ts
export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
.use(captureLambdaHandler(tracer))
.use(injectLambdaContext(logger))
.use(logMetrics(metrics))
.handler(lambdaHandler);

Puedes acceder al logger desde tus implementaciones de operaciones vía el contexto:

operations/echo.ts
import { ServiceContext } from '../context.js';
import { Echo as EchoOperation } from '../generated/ssdk/index.js';
export const Echo: EchoOperation<ServiceContext> = async (input, ctx) => {
ctx.logger.info('Your log message');
// ...
};

El trazado con AWS X-Ray se configura automáticamente mediante el middleware captureLambdaHandler.

handler.ts
export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
.use(captureLambdaHandler(tracer))
.use(injectLambdaContext(logger))
.use(logMetrics(metrics))
.handler(lambdaHandler);

Puedes añadir subsegmentos personalizados a tus trazas en tus operaciones:

operations/echo.ts
import { ServiceContext } from '../context.js';
import { Echo as EchoOperation } from '../generated/ssdk/index.js';
export const Echo: EchoOperation<ServiceContext> = async (input, ctx) => {
// Creates a new subsegment
const subsegment = ctx.tracer.getSegment()?.addNewSubsegment('custom-operation');
try {
// Your logic here
} catch (error) {
subsegment?.addError(error as Error);
throw error;
} finally {
subsegment?.close();
}
};

Las métricas de CloudWatch se recopilan automáticamente para cada solicitud mediante el middleware logMetrics.

handler.ts
export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
.use(captureLambdaHandler(tracer))
.use(injectLambdaContext(logger))
.use(logMetrics(metrics))
.handler(lambdaHandler);

Puedes añadir métricas personalizadas en tus operaciones:

operations/echo.ts
import { MetricUnit } from '@aws-lambda-powertools/metrics';
import { ServiceContext } from '../context.js';
import { Echo as EchoOperation } from '../generated/ssdk/index.js';
export const Echo: EchoOperation<ServiceContext> = async (input, ctx) => {
ctx.metrics.addMetric("CustomMetric", MetricUnit.Count, 1);
// ...
};

Smithy provee manejo de errores integrado. Puedes definir errores personalizados en tu modelo Smithy:

@error("client")
@httpError(400)
structure InvalidRequestError {
@required
message: String
}

Y registrarlos en tu operación/servicio:

operation MyOperation {
...
errors: [InvalidRequestError]
}

Luego lanzarlos en tu implementación TypeScript:

import { InvalidRequestError } from '../generated/ssdk/index.js';
export const MyOperation: MyOperationHandler<ServiceContext> = async (input) => {
if (!input.requiredField) {
throw new InvalidRequestError({
message: "Required field is missing"
});
}
return { /* success response */ };
};

Cuando tu API está protegida por autenticación, tus operaciones a menudo necesitan saber quién está realizando la llamada. El enfoque recomendado es resolver la identidad del llamante una vez en el handler y pasarla a través del contexto del servicio para su consumo por operaciones específicas.

Modelaremos el caso no autorizado como un error de Smithy para que se serialice a una respuesta 403 adecuada. Agrégalo a tu modelo, por ejemplo en model/src/operations/errors.smithy, y referéncialo en cualquier operación que requiera identidad:

$version: "2.0"
namespace your.namespace
/// Thrown when the calling user cannot be determined
@error("client")
@httpError(403)
structure UnauthorizedError {
@required
message: String
}

Primero, expón la identidad resuelta en el contexto del servicio en src/context.ts. La proporcionamos como una función para que el UnauthorizedError se lance desde dentro de una operación (donde el Server SDK lo serializa a un 403), en lugar de desde el handler:

import { Logger } from '@aws-lambda-powertools/logger';
import { Metrics } from '@aws-lambda-powertools/metrics';
import { Tracer } from '@aws-lambda-powertools/tracer';
export interface Identity {
sub: string;
username: string;
}
/**
* Context provided to all operations.
*/
export interface ServiceContext {
tracer: Tracer;
logger: Logger;
metrics: Metrics;
getIdentity: () => Promise<Identity>;
}

A continuación, escribe el resolver en src/identity.ts. Lanza UnauthorizedError cuando no se puede determinar el llamante. La implementación depende del método auth seleccionado:

auth = iam

Para la autenticación IAM, buscamos el llamante en Cognito usando el sub extraído del evento de API Gateway:

import { CognitoIdentityProvider } from '@aws-sdk/client-cognito-identity-provider';
import type { APIGatewayProxyEvent } from 'aws-lambda';
import { Identity } from './context.js';
import { UnauthorizedError } from './generated/ssdk/index.js';
const cognito = new CognitoIdentityProvider();
export const getIdentity = async (
event: APIGatewayProxyEvent,
): Promise<Identity> => {
const cognitoAuthenticationProvider =
event.requestContext?.identity?.cognitoAuthenticationProvider;
let sub: string | undefined = undefined;
if (cognitoAuthenticationProvider) {
const providerParts = cognitoAuthenticationProvider.split(':');
sub = providerParts[providerParts.length - 1];
}
if (!sub) {
throw new UnauthorizedError({ message: 'Unable to determine calling user' });
}
const { Users } = await cognito.listUsers({
// Assumes user pool id is configured in lambda environment
UserPoolId: process.env.USER_POOL_ID!,
Limit: 1,
Filter: `sub="${sub}"`,
});
if (!Users || Users.length !== 1) {
throw new UnauthorizedError({ message: `No user found with subjectId ${sub}` });
}
return { sub, username: Users[0].Username! };
};
auth = cognito

Con auth: 'cognito', el autorizador de Cognito User Pools de API Gateway verifica el JWT que el llamante proporciona en el encabezado Authorization y coloca las claims verificadas en el evento en event.requestContext.authorizer.claims:

import type { APIGatewayProxyEvent } from 'aws-lambda';
import { Identity } from './context.js';
import { UnauthorizedError } from './generated/ssdk/index.js';
export const getIdentity = async (
event: APIGatewayProxyEvent,
): Promise<Identity> => {
const claims = event.requestContext?.authorizer?.claims as
| Record<string, string>
| undefined;
const sub = claims?.sub;
const username = claims?.username;
if (!sub || !username) {
throw new UnauthorizedError({ message: 'Unable to determine calling user' });
}
return { sub, username };
};

Luego conecta el resolver al contexto en src/handler.ts:

import { Service } from './service.js';
import { getIdentity } from './identity.js';
// ...
const httpResponse = await serviceHandler.handle(httpRequest, {
tracer,
logger,
metrics,
getIdentity: () => getIdentity(event),
});

Ahora podemos usar la identidad resuelta en una operación, por ejemplo en src/operations/echo.ts:

import { ServiceContext } from '../context.js';
import { Echo as EchoOperation } from '../generated/ssdk/index.js';
export const Echo: EchoOperation<ServiceContext> = async (input, ctx) => {
const identity = await ctx.getIdentity();
return { message: `${identity.username} says ${input.message}` };
};

El proyecto del modelo Smithy usa Docker para construir los artefactos Smithy y generar el SDK de servidor TypeScript:

Terminal window
pnpm nx build <model-project>

Este proceso:

  1. Compila el modelo Smithy y lo valida
  2. Genera la especificación OpenAPI a partir del modelo Smithy
  3. Crea el SDK de servidor TypeScript con interfaces de operación con seguridad de tipos
  4. Genera artefactos de build en dist/<model-project>/build/

El proyecto backend copia automáticamente el SDK generado durante la compilación:

Terminal window
pnpm nx copy-ssdk <backend-project>

El generador configura automáticamente un objetivo bundle que utiliza Rolldown para crear un paquete de despliegue:

Terminal window
pnpm nx bundle <project-name>

La configuración de Rolldown se encuentra en rolldown.config.ts, con una entrada por cada bundle a generar. Rolldown gestiona la creación de múltiples bundles en paralelo si están definidos.

El generador configura un servidor local con recarga en caliente:

Terminal window
pnpm nx serve <backend-project>

El generador crea infraestructura como código con CDK o Terraform según el iacProvider seleccionado.

El constructo CDK para desplegar tu API está en la carpeta common/constructs:

import { MyApi } from ':my-scope/common-constructs';
export class ExampleStack extends Stack {
constructor(scope: Construct, id: string) {
// Add the API to your stack
const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
}
}

Esto configura:

  1. Una función AWS Lambda para el servicio Smithy
  2. API Gateway REST API como disparador de la función
  3. Roles y permisos IAM
  4. Grupo de logs de CloudWatch
  5. Configuración de trazado X-Ray
auth = cognito

Para las API REST, el constructo generado asocia una Web ACL de AWS WAFv2 con la etapa de API Gateway de forma predeterminada. La Web ACL utiliza el conjunto de reglas predeterminado administrado por AWS (AWSManagedRulesCommonRuleSet y AWSManagedRulesKnownBadInputsRuleSet), proporcionando protección contra exploits web comunes, incluido el OWASP Top 10. Los registros de solicitudes de WAF se escriben en un grupo de CloudWatch Logs.

Puedes editar el constructo rest-api generado para agregar, eliminar o ajustar reglas (por ejemplo, para agregar reglas basadas en tasas o grupos de reglas administradas adicionales).

Para optar por no participar (por ejemplo, para adjuntar tu propia Web ACL), establece enableWaf en false:

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
enableWaf: false,
});

Para las APIs REST, la infraestructura generada habilita el registro de acceso por defecto, escribiendo una línea JSON estructurada por solicitud en un grupo de CloudWatch Logs dedicado. El grupo de registros está cifrado con una clave KMS administrada por el cliente y se conserva durante un año.

API Gateway escribe registros de acceso utilizando un rol de CloudWatch Logs a nivel de cuenta. Este rol se configura en el ajuste AWS::ApiGateway::Account, que es un singleton por región por cuenta — solo hay un rol para cada API REST en la región. Para gestionar esto de forma segura a través de múltiples stacks desplegados de forma independiente, la infraestructura generada:

  • Crea un rol compartido de CloudWatch Logs y lo configura en la cuenta solo cuando no hay un rol funcional ya establecido, por lo que los despliegues nunca sobrescriben un rol que pertenece a otro stack.
  • Deja el ajuste de la cuenta intacto durante el desmontaje, por lo que destruir un stack nunca deshabilita el registro para otras APIs REST en la región.

El rol de cuenta es gestionado por el constructo ApiGatewayAccount, un singleton con ámbito de stack resuelto a través de ApiGatewayAccount.ensure(scope). Cada etapa de la API REST depende de él, y el rol se configura mediante un recurso personalizado respaldado por Lambda.

Puedes personalizar el formato del registro de acceso pasando deployOptions al construir tu API:

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
deployOptions: {
accessLogFormat: AccessLogFormat.clf(),
},
});

Los constructos CDK de la API REST/HTTP están configurados para proporcionar una interfaz type-safe que define integraciones para cada una de tus operaciones.

Los constructos CDK proporcionan soporte completo de integración con seguridad de tipos como se describe a continuación.

Puedes usar el método estático defaultIntegrations para utilizar el patrón por defecto, que define una función AWS Lambda individual para cada operación:

new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});

Puedes acceder a las funciones AWS Lambda subyacentes a través de la propiedad integrations del constructo de la API, de manera type-safe. Por ejemplo, si tu API define una operación llamada sayHello y necesitas agregar permisos a esta función, puedes hacerlo así:

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
// sayHello está tipado según las operaciones definidas en tu API
api.integrations.sayHello.handler.addToRolePolicy(new PolicyStatement({
effect: Effect.ALLOW,
actions: [...],
resources: [...],
}));

Si tu API usa el patrón shared, el router Lambda compartido se expone como api.integrations.$router:

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
api.integrations.$router.handler.addEnvironment('LOG_LEVEL', 'DEBUG');

Si deseas personalizar las opciones usadas al crear la función Lambda para cada integración por defecto, puedes usar el método withDefaultOptions. Por ejemplo, si quieres que todas tus funciones Lambda residan en una VPC:

const vpc = new Vpc(this, 'Vpc', ...);
new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withDefaultOptions({
vpc,
})
.build(),
});

Para personalizar las opciones usadas al crear la integración por defecto para operaciones específicas (sin afectar a las demás), puedes usar el método withOperationOptions. Por ejemplo, si deseas aumentar el timeout de la función Lambda para solo una operación:

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withOperationOptions({
sayHello: {
timeout: Duration.seconds(60),
},
})
.build(),
});
// Las operaciones seleccionadas siguen siendo integraciones por defecto, por lo que siguen tipadas en consecuencia:
api.integrations.sayHello.handler.addToRolePolicy(new PolicyStatement({ ... }));

Las opciones que especificas se fusionan con las opciones de integración por defecto (y cualquier opción establecida mediante withDefaultOptions). Ten en cuenta que no puedes especificar opciones para operaciones que hayas reemplazado mediante withOverrides, ya que estas ya no usan la integración por defecto.

Encontrarás un error de tipo si la misma operación es objetivo tanto de withOperationOptions como de withOverrides, independientemente del orden en que los llames.

También puedes sobrescribir integraciones para operaciones específicas usando el método withOverrides. Cada override debe especificar una propiedad integration que está tipada al constructo de integración CDK apropiado para la API HTTP o REST. El método withOverrides también es type-safe. Por ejemplo, si quieres sobrescribir una API getDocumentation para apuntar a documentación alojada en un sitio externo:

new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withOverrides({
getDocumentation: {
integration: new HttpIntegration('https://example.com/documentation'),
},
})
.build(),
});

Notarás que la integración sobrescrita ya no tiene una propiedad handler cuando se accede a través de api.integrations.getDocumentation.

Puedes agregar propiedades adicionales a una integración que también estarán tipadas, permitiendo abstraer otros tipos de integración manteniendo el type-safe. Por ejemplo, si creaste una integración S3 para una API REST y luego quieres referenciar el bucket para una operación particular:

const storageBucket = new Bucket(this, 'Bucket', { ... });
const apiGatewayRole = new Role(this, 'ApiGatewayS3Role', {
assumedBy: new ServicePrincipal('apigateway.amazonaws.com'),
});
storageBucket.grantRead(apiGatewayRole);
const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withOverrides({
getFile: {
bucket: storageBucket,
integration: new AwsIntegration({
service: 's3',
integrationHttpMethod: 'GET',
path: `${storageBucket.bucketName}/{fileName}`,
options: {
credentialsRole: apiGatewayRole,
requestParameters: {
'integration.request.path.fileName': 'method.request.querystring.fileName',
},
integrationResponses: [{ statusCode: '200' }],
},
}),
options: {
requestParameters: {
'method.request.querystring.fileName': true,
},
methodResponses: [{
statusCode: '200',
}],
}
},
})
.build(),
});
// Más tarde, quizás en otro archivo, puedes acceder a la propiedad bucket que definimos
// de manera type-safe
api.integrations.getFile.bucket.grantRead(...);

También puedes proveer options en tu integración para sobrescribir opciones de método específicas como autorizadores. Por ejemplo, si deseas usar autenticación con Cognito para tu operación getDocumentation:

new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withOverrides({
getDocumentation: {
integration: new HttpIntegration('https://example.com/documentation'),
options: {
authorizer: new CognitoUserPoolsAuthorizer(...) // para REST, o HttpUserPoolAuthorizer para HTTP API
}
},
})
.build(),
});

Si prefieres, puedes no usar las integraciones por defecto y proveer directamente una para cada operación. Esto es útil si, por ejemplo, cada operación necesita usar un tipo diferente de integración o quieres recibir un error de tipo al agregar nuevas operaciones:

new MyApi(this, 'MyApi', {
integrations: {
sayHello: {
integration: new LambdaIntegration(...),
},
getDocumentation: {
integration: new HttpIntegration(...),
},
},
});

Los constructos de API CDK generados admiten dos patrones de integración:

  • isolated crea una función Lambda por operación. Este es el valor por defecto para las APIs generadas.
  • shared crea un único router Lambda por defecto y lo reutiliza para cada operación a menos que sobrescribas integraciones específicas.

isolated te brinda permisos y configuración más granulares por operación. shared reduce la proliferación de funciones Lambda e integraciones de API Gateway mientras aún permite sobrescritas selectivas.

Por ejemplo, establecer pattern a 'shared' crea una única función en lugar de una por integración:

packages/common/constructs/src/app/apis/my-api.ts
export class MyApi<...> extends ... {
public static defaultIntegrations = (scope: Construct) => {
...
return IntegrationBuilder.rest({
pattern: 'shared',
...
});
};
}

Dado que las operaciones se definen en Smithy, usamos generación de código para proveer metadatos al constructo CDK para integraciones con seguridad de tipos.

Se añade un objetivo generate:<ApiName>-metadata al project.json de los constructos comunes para facilitar esta generación, el cual emite un archivo como packages/common/constructs/src/generated/my-api/metadata.gen.ts. Como esto se genera en tiempo de build, se ignora en control de versiones.

auth = iam

Si seleccionaste autenticación IAM, puedes usar el método grantInvokeAccess para otorgar acceso a tu API:

api.grantInvokeAccess(myIdentityPool.authenticatedRole);

Para invocar tu API desde un sitio web React, puedes usar el generador connection, que provee generación de cliente con seguridad de tipos a partir de tu modelo Smithy.

Usa el generador connection para integrar este proyecto con otros en tu workspace. Las siguientes conexiones involucran este proyecto:

Smithy
React a Smithy APILlama a una API Smithy desde un sitio web React
SmithyAmazon Aurora
API Smithy a Base de Datos RelacionalConecta una API Smithy a una base de datos relacional Aurora
SmithyAmazon DynamoDB
API Smithy a TypeScript DynamoDBConecta una API Smithy a una tabla DynamoDB