Aller au contenu

API Smithy TypeScript

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

Smithy est un langage de définition d’interface indépendant des protocoles pour créer des API de manière modélisée.

Le générateur d’API Smithy TypeScript crée une nouvelle API en utilisant Smithy pour la définition des services, et le SDK serveur Smithy TypeScript pour l’implémentation. Le générateur fournit une infrastructure IaC avec CDK ou Terraform pour déployer votre service sur AWS Lambda, exposé via une API REST AWS API Gateway. Il permet un développement d’API fortement typé avec génération automatique de code à partir des modèles Smithy. Le gestionnaire généré utilise AWS Lambda Powertools pour TypeScript pour l’observabilité, incluant la journalisation, le traçage AWS X-Ray et les métriques CloudWatch.

Vous pouvez générer une nouvelle API Smithy TypeScript de deux manières :

  1. Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
  2. Ouvrez la console Nx dans VSCode
  3. Cliquez sur Generate (UI) dans la section "Common Nx Commands"
  4. Recherchez @aws/nx-plugin - ts#api
  5. Remplissez les paramètres requis
    • framework: smithy
  6. Cliquez sur Generate
ParamètreTypePar défautDescription
name Requisstring-Le nom de l'API (requis). Utilisé pour générer les noms de classes et les chemins de fichiers.
framework trpc | smithytrpcLe framework d'API à utiliser.
namespace string-L'espace de noms pour l'API Smithy (applicable uniquement pour le framework smithy). Par défaut, correspond à la portée de votre monorepo
integrationPattern isolated | sharedisolatedComment les intégrations API Gateway sont générées pour l'API. Choisissez entre isolated (par défaut) et shared.
auth iam | cognito | customiamLa méthode utilisée pour s'authentifier auprès de votre API. Choisissez entre iam (par défaut), cognito ou custom.
directory stringpackagesLe répertoire dans lequel stocker l'application.
subDirectory string-Le sous-répertoire dans lequel le projet est placé. Par défaut, il s'agit du nom du projet.
iac inherit | cdk | terraforminheritLe fournisseur IaC préféré. Par défaut, celui-ci est hérité de votre sélection initiale.
infra rest-lambda | http-lambda | nonerest-lambdaLe type d'infrastructure à utiliser pour déployer cette API.
preferInstallDependencies booleantrueIndique s'il faut privilégier l'installation des dépendances après l'exécution du générateur. Définir à false pour différer l'installation lors de l'exécution de plusieurs générateurs en lot (une installation s'exécute quand même si nécessaire pour que les générateurs suivants puissent calculer le graphe de projet Nx) ; installer une seule fois à la fin.

Le générateur crée deux projets associés dans le répertoire <directory>/<api-name> :

  • Répertoiremodel/ Projet de modèle Smithy
    • project.json Configuration du projet et cibles de build
    • smithy-build.json Configuration de build Smithy
    • build.Dockerfile Configuration Docker pour la construction des artefacts Smithy
    • Répertoiresrc/
      • main.smithy Définition principale du service
      • Répertoireoperations/
        • echo.smithy Exemple de définition d’opération
  • Répertoirebackend/ Implémentation TypeScript du backend
    • project.json Configuration du projet et cibles de build
    • rolldown.config.ts Configuration de bundle
    • Répertoiresrc/
      • handler.ts Gestionnaire AWS Lambda
      • local-server.ts Serveur de développement local
      • service.ts Implémentation du service
      • context.ts Définition du contexte du service
      • Répertoireoperations/
        • echo.ts Exemple d’implémentation d’opération
      • Répertoiregenerated/ SDK TypeScript généré (créé pendant le build)

Comme ce générateur crée une infrastructure as code selon votre choix de iacProvider, il génère un projet dans packages/common incluant les constructs CDK ou modules Terraform pertinents.

Le projet d’infrastructure as code commun est structuré comme suit :

  • Répertoirepackages/common/constructs
    • Répertoiresrc
      • Répertoireapp/ Constructs pour l’infrastructure spécifique à un projet/générateur
        • Répertoireapis/
          • <project-name>.ts Construct CDK pour déployer votre API
      • Répertoirecore/ Constructs génériques réutilisés par ceux dans app
        • Répertoireapi/
          • rest-api.ts Construct CDK pour déployer une API REST
          • utils.ts Utilitaires pour les constructs d’API
      • index.ts Point d’entrée exportant les constructs de app
    • project.json Cibles de build et configuration du projet

L’API Smithy déployée a l’architecture suivante, avec une Web ACL AWS WAFv2 devant l’étape API Gateway :

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

Les opérations sont définies dans des fichiers Smithy au sein du projet de modèle. La définition principale du service se trouve dans 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,
// Ajoutez vos opérations ici
]
errors: [
ValidationException
]
}

Les opérations individuelles sont définies dans des fichiers séparés dans le répertoire 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
}

Les implémentations d’opérations se trouvent dans le répertoire src/operations/ du projet backend. Chaque opération est implémentée en utilisant les types générés par le SDK serveur TypeScript (généré au moment du build à partir de votre modèle Smithy).

import { ServiceContext } from '../context.js';
import { Echo as EchoOperation } from '../generated/ssdk/index.js';
export const Echo: EchoOperation<ServiceContext> = async (input) => {
// Votre logique métier ici
return {
message: `Echo: ${input.message}` // fortement typé selon votre modèle Smithy
};
};

Les opérations doivent être enregistrées dans la définition du service dans src/service.ts :

import { ServiceContext } from './context.js';
import { YourServiceService } from './generated/ssdk/index.js';
import { Echo } from './operations/echo.js';
// Importez d'autres opérations ici
// Enregistrez les opérations dans le service ici
export const Service: YourServiceService<ServiceContext> = {
Echo,
// Ajoutez d'autres opérations ici
};

Vous pouvez définir un contexte partagé pour vos opérations dans context.ts :

export interface ServiceContext {
// Tracer, logger et metrics Powertools sont fournis par défaut
tracer: Tracer;
logger: Logger;
metrics: Metrics;
// Ajoutez des dépendances partagées, connexions DB, etc.
dbClient: any;
userIdentity: string;
}

Ce contexte est passé à toutes les implémentations d’opérations et peut être utilisé pour partager des ressources comme des connexions de base de données, de la configuration ou des utilitaires de journalisation.

Le générateur configure la journalisation structurée avec AWS Lambda Powertools et l’injection automatique de contexte via un middleware Middy.

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

Vous pouvez accéder au logger depuis vos implémentations d’opérations via le contexte :

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('Votre message de log');
// ...
};

Le traçage AWS X-Ray est configuré automatiquement via le middleware captureLambdaHandler.

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

Vous pouvez ajouter des sous-segments personnalisés à vos traces dans vos opérations :

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) => {
// Crée un nouveau sous-segment
const subsegment = ctx.tracer.getSegment()?.addNewSubsegment('custom-operation');
try {
// Votre logique ici
} catch (error) {
subsegment?.addError(error as Error);
throw error;
} finally {
subsegment?.close();
}
};

Les métriques CloudWatch sont collectées automatiquement pour chaque requête via le middleware logMetrics.

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

Vous pouvez ajouter des métriques personnalisées dans vos opérations :

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 fournit une gestion d’erreurs intégrée. Vous pouvez définir des erreurs personnalisées dans votre modèle Smithy :

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

Et les enregistrer dans votre opération/service :

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

Puis les lever dans votre implémentation TypeScript :

import { InvalidRequestError } from '../generated/ssdk/index.js';
export const MyOperation: MyOperationHandler<ServiceContext> = async (input) => {
if (!input.requiredField) {
throw new InvalidRequestError({
message: "Champ requis manquant"
});
}
return { /* réponse de succès */ };
};

Lorsque votre API est protégée par authentification, vos opérations ont souvent besoin de savoir qui appelle. L’approche recommandée consiste à résoudre l’identité de l’appelant une fois dans le gestionnaire et à la transmettre via le contexte de service pour consommation par des opérations spécifiques.

Nous allons modéliser le cas non autorisé comme une erreur Smithy afin qu’elle se sérialise en une réponse 403 appropriée. Ajoutez-la à votre modèle, par exemple dans model/src/operations/errors.smithy, et référencez-la sur toute opération qui nécessite une identité :

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

Tout d’abord, exposez l’identité résolue sur le contexte de service dans src/context.ts. Nous la fournissons sous forme de fonction afin que l’UnauthorizedError soit levée depuis une opération (où le SDK serveur la sérialise en 403), plutôt que depuis le gestionnaire :

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>;
}

Ensuite, écrivez le résolveur dans src/identity.ts. Il lève UnauthorizedError lorsque l’appelant ne peut pas être déterminé. L’implémentation dépend de votre méthode auth sélectionnée :

auth = iam

Pour l’authentification IAM, nous recherchons l’appelant dans Cognito en utilisant le sub extrait de l’événement 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

Avec auth: 'cognito', l’autorisateur Cognito User Pools d’API Gateway vérifie le JWT que l’appelant fournit dans l’en-tête Authorization et place les revendications vérifiées sur l’événement à 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 };
};

Ensuite, intégrez le résolveur dans le contexte dans 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),
});

Nous pouvons maintenant utiliser l’identité résolue dans une opération, par exemple dans 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}` };
};

Le projet de modèle Smithy utilise Docker pour construire les artefacts Smithy et générer le SDK serveur TypeScript :

Terminal window
pnpm nx build <model-project>

Ce processus :

  1. Compile le modèle Smithy et le valide
  2. Génère une spécification OpenAPI à partir du modèle Smithy
  3. Crée le SDK serveur TypeScript avec des interfaces d’opération fortement typées
  4. Produit les artefacts de build dans dist/<model-project>/build/

Le projet backend copie automatiquement le SDK généré pendant la compilation :

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

Le générateur configure automatiquement une cible bundle qui utilise Rolldown pour créer un package de déploiement :

Terminal window
pnpm nx bundle <project-name>

La configuration de Rolldown se trouve dans rolldown.config.ts, avec une entrée par bundle à générer. Rolldown gère la création de plusieurs bundles en parallèle si définis.

Le générateur configure un serveur de développement local avec rechargement à chaud :

Terminal window
pnpm nx serve <backend-project>

Le générateur crée une infrastructure CDK ou Terraform selon votre choix de iacProvider.

Le construct CDK pour déployer votre API se trouve dans le dossier common/constructs :

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

Ceci configure :

  1. Une fonction AWS Lambda pour le service Smithy
  2. Une API REST API Gateway comme déclencheur
  3. Les rôles et permissions IAM
  4. Un groupe de logs CloudWatch
  5. La configuration de traçage X-Ray
auth = cognito

Pour les API REST, le construct généré associe par défaut une Web ACL AWS WAFv2 à l’étape API Gateway. La Web ACL utilise l’ensemble de règles par défaut géré par AWS (AWSManagedRulesCommonRuleSet et AWSManagedRulesKnownBadInputsRuleSet), offrant une protection contre les exploits web courants, y compris le Top 10 OWASP. Les journaux de requêtes WAF sont écrits dans un groupe CloudWatch Logs.

Vous pouvez modifier le construct rest-api généré pour ajouter, supprimer ou ajuster des règles (par exemple, pour ajouter des règles basées sur le taux ou des groupes de règles gérées supplémentaires).

Pour désactiver cette fonctionnalité (par exemple, pour attacher votre propre Web ACL), définissez enableWaf sur false :

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

Pour les API REST, l’infrastructure générée active la journalisation des accès par défaut, écrivant une ligne JSON structurée par requête dans un groupe CloudWatch Logs dédié. Le groupe de journaux est chiffré avec une clé KMS gérée par le client et conservé pendant un an.

API Gateway écrit les journaux d’accès en utilisant un rôle CloudWatch Logs au niveau du compte. Ce rôle est configuré sur le paramètre AWS::ApiGateway::Account, qui est un singleton par région par compte — il n’y a qu’un seul rôle pour chaque API REST dans la région. Pour gérer cela en toute sécurité à travers plusieurs stacks déployées indépendamment, l’infrastructure générée :

  • Crée un rôle CloudWatch Logs partagé et le configure sur le compte uniquement lorsqu’aucun rôle fonctionnel n’est déjà défini, de sorte que les déploiements n’écrasent jamais un rôle appartenant à une autre stack.
  • Laisse le paramètre du compte intact lors du démontage, de sorte que la destruction d’une stack ne désactive jamais la journalisation pour les autres API REST dans la région.

Le rôle du compte est géré par le construct ApiGatewayAccount, un singleton à portée de stack résolu via ApiGatewayAccount.ensure(scope). Chaque stage d’API REST en dépend, et le rôle est configuré par une ressource personnalisée basée sur Lambda.

Vous pouvez personnaliser le format du journal d’accès en passant deployOptions lors de la construction de votre API :

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

Les constructs CDK pour l’API REST/HTTP sont configurés pour fournir une interface typée permettant de définir des intégrations pour chacune de vos opérations.

Les constructs CDK offrent un support complet d’intégration typée comme décrit ci-dessous.

Vous pouvez utiliser la méthode statique defaultIntegrations pour utiliser le modèle par défaut, qui définit une fonction AWS Lambda individuelle pour chaque opération :

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

Vous pouvez accéder aux fonctions AWS Lambda sous-jacentes via la propriété integrations du construct API, de manière typée. Par exemple, si votre API définit une opération nommée sayHello et que vous devez ajouter des permissions à cette fonction, vous pouvez le faire comme suit :

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
// sayHello est typé selon les opérations définies dans votre API
api.integrations.sayHello.handler.addToRolePolicy(new PolicyStatement({
effect: Effect.ALLOW,
actions: [...],
resources: [...],
}));

Si votre API utilise le modèle shared, la fonction Lambda router partagée est exposée via api.integrations.$router :

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

Si vous souhaitez personnaliser les options utilisées lors de la création des fonctions Lambda pour chaque intégration par défaut, vous pouvez utiliser la méthode withDefaultOptions. Par exemple, si vous voulez que toutes vos fonctions Lambda résident dans un VPC :

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

Pour personnaliser les options utilisées pour créer l’intégration par défaut pour des opérations spécifiques (sans affecter les autres), vous pouvez utiliser la méthode withOperationOptions. Par exemple, si vous souhaitez augmenter le timeout de la fonction Lambda pour une seule opération :

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withOperationOptions({
sayHello: {
timeout: Duration.seconds(60),
},
})
.build(),
});
// Les opérations sélectionnées restent des intégrations par défaut, elles sont donc toujours typées en conséquence :
api.integrations.sayHello.handler.addToRolePolicy(new PolicyStatement({ ... }));

Les options que vous spécifiez sont fusionnées avec les options d’intégration par défaut (et toutes les options définies via withDefaultOptions). Notez que vous ne pouvez pas spécifier d’options pour les opérations que vous avez remplacées via withOverrides, car celles-ci n’utilisent plus l’intégration par défaut.

Vous rencontrerez une erreur de type si la même opération est ciblée à la fois par withOperationOptions et withOverrides, quel que soit l’ordre dans lequel vous les appelez.

Vous pouvez aussi surcharger les intégrations pour des opérations spécifiques en utilisant la méthode withOverrides. Chaque surcharge doit spécifier une propriété integration typée selon le construct CDK d’intégration approprié pour l’API HTTP ou REST. La méthode withOverrides est également typée. Par exemple, si vous voulez rediriger une API getDocumentation vers une documentation hébergée sur un site externe :

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

Vous remarquerez que l’intégration surchargée n’a plus de propriété handler lorsqu’on y accède via api.integrations.getDocumentation.

Vous pouvez ajouter des propriétés supplémentaires à une intégration qui seront également typées, permettant d’abstraire d’autres types d’intégration tout en conservant le typage. Par exemple, si vous avez créé une intégration S3 pour une API REST et que vous souhaitez référencer le bucket pour une opération particulière :

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(),
});
// Plus tard, peut-être dans un autre fichier, vous pouvez accéder à la propriété bucket
// que nous avons définie de manière typée
api.integrations.getFile.bucket.grantRead(...);

Vous pouvez aussi fournir des options dans votre intégration pour surcharger des options de méthode spécifiques comme les autorisations. Par exemple, si vous souhaitez utiliser l’authentification Cognito pour votre opération getDocumentation :

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

Si vous préférez, vous pouvez choisir de ne pas utiliser les intégrations par défaut et fournir directement une intégration pour chaque opération. Ceci est utile si, par exemple, chaque opération nécessite un type d’intégration différent ou si vous voulez obtenir une erreur de type lors de l’ajout de nouvelles opérations :

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

Les constructs d’API CDK générés supportent deux modèles d’intégration :

  • isolated crée une fonction Lambda par opération. C’est le modèle par défaut pour les API générées.
  • shared crée une seule fonction Lambda router par défaut et la réutilise pour chaque opération sauf si vous surchargez des intégrations spécifiques.

isolated vous donne des permissions et une configuration plus granulaires par opération. shared réduit la prolifération des fonctions Lambda et des intégrations API Gateway tout en permettant des surcharges sélectives.

Par exemple, définir pattern sur 'shared' crée une fonction unique au lieu d’une par intégration :

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

Comme les opérations sont définies dans Smithy, nous utilisons la génération de code pour fournir des métadonnées au construct CDK pour des intégrations fortement typées.

Une cible generate:<ApiName>-metadata est ajoutée au project.json des constructs communs pour faciliter cette génération, produisant un fichier comme packages/common/constructs/src/generated/my-api/metadata.gen.ts. Ce fichier étant généré au build, il est ignoré dans le contrôle de version.

auth = iam

Si vous avez sélectionné l’authentification IAM, vous pouvez utiliser la méthode grantInvokeAccess pour accorder l’accès à votre API :

api.grantInvokeAccess(myIdentityPool.authenticatedRole);

Pour invoquer votre API depuis un site React, vous pouvez utiliser le générateur connection, qui fournit un client fortement typé généré à partir de votre modèle Smithy.

Utilisez le générateur connection pour intégrer ce projet avec d’autres dans votre espace de travail. Les connexions suivantes impliquent ce projet :

Smithy
React vers Smithy APIAppeler une API Smithy depuis un site React
SmithyAmazon Aurora
API Smithy vers Base de données relationnelleConnecter une API Smithy à une base de données relationnelle Aurora
SmithyAmazon DynamoDB
API Smithy vers TypeScript DynamoDBConnecter une API Smithy à une table DynamoDB