Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Usare un AWS AppSync API con AWS CDK
Suggerimento
Prima di utilizzare ilCDK, ti consigliamo CDK di consultare la documentazione ufficiale insieme AWS AppSync ai CDKriferimenti.
Ti consigliamo inoltre di assicurarti che AWS CLIle tue NPM
In questa sezione, creeremo una semplice CDK applicazione in grado di aggiungere e recuperare elementi da una tabella DynamoDB. Questo vuole essere un esempio di avvio rapido che utilizza parte del codice delle sezioni Progettazione dello schema, Collegamento di una fonte di dati e Configurazione dei resolvers (). JavaScript
Configurazione di un progetto CDK
avvertimento
Questi passaggi potrebbero non essere completamente accurati a seconda dell'ambiente. Partiamo dal presupposto che sul sistema siano installate le utilità necessarie, un modo per interfacciarsi con AWS i servizi e configurazioni corrette.
Il primo passo è l'installazione di. AWS CDK Nel tuoCLI, puoi inserire il seguente comando:
npm install -g aws-cdk
Successivamente, è necessario creare una directory di progetto, quindi accedervi. Un esempio di set di comandi per creare e navigare in una directory è:
mkdir example-cdk-app cd example-cdk-app
Successivamente, devi creare un'app. Il nostro servizio utilizza principalmente TypeScript. Nella directory del progetto, inserisci il seguente comando:
cdk init app --language typescript
Quando esegui questa operazione, verrà installata un'CDKapp con i relativi file di inizializzazione:
La struttura del tuo progetto potrebbe essere simile a questa:
Noterai che abbiamo diverse directory importanti:
-
bin
: Il file bin iniziale creerà l'app. Non lo tratteremo in questa guida. -
lib
: La directory lib contiene i tuoi file stack. Potete pensare ai file stack come a singole unità di esecuzione. I costrutti saranno all'interno dei nostri file stack. Fondamentalmente, si tratta di risorse per un servizio che verrà attivato AWS CloudFormation quando l'app verrà distribuita. È qui che avverrà la maggior parte della nostra codifica. -
node_modules
: Questa directory è creata NPM e contiene tutte le dipendenze dei pacchetti che sono state installate utilizzando ilnpm
comando.
Il nostro file stack iniziale può contenere qualcosa del genere:
import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; // import * as sqs from 'aws-cdk-lib/aws-sqs'; export class ExampleCdkAppStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // The code that defines your stack goes here // example resource // const queue = new sqs.Queue(this, 'ExampleCdkAppQueue', { // visibilityTimeout: cdk.Duration.seconds(300) // }); } }
Questo è il codice standard per creare uno stack nella nostra app. La maggior parte del nostro codice in questo esempio rientrerà nell'ambito di questa classe.
Per verificare che il file stack si trovi nell'app, nella directory dell'app, esegui il seguente comando nel terminale:
cdk ls
Dovrebbe apparire un elenco dei tuoi stack. In caso contrario, potrebbe essere necessario ripetere i passaggi o consultare la documentazione ufficiale per ricevere assistenza.
Se desideri creare le modifiche al codice prima della distribuzione, puoi sempre eseguire il seguente comando nel terminale:
npm run build
Inoltre, per vedere le modifiche prima della distribuzione:
cdk diff
Prima di aggiungere il codice al file stack, eseguiremo un bootstrap. Il bootstrap ci consente di fornire le risorse necessarie CDK prima della distribuzione dell'app. Ulteriori informazioni su questo processo sono disponibili qui. Per creare un bootstrap, il comando è:
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
Suggerimento
Questo passaggio richiede diverse IAM autorizzazioni nel tuo account. Il tuo bootstrap verrà negato se non li hai. In tal caso, potrebbe essere necessario eliminare le risorse incomplete causate dal bootstrap, ad esempio il bucket S3 che genera.
Bootstrap genererà diverse risorse. Il messaggio finale sarà simile al seguente:
Questa operazione viene eseguita una volta per account per regione, quindi non dovrai farlo spesso. Le risorse principali del bootstrap sono lo AWS CloudFormation stack e il bucket Amazon S3.
Il bucket Amazon S3 viene utilizzato per archiviare file e IAM ruoli che concedono le autorizzazioni necessarie per eseguire le distribuzioni. Le risorse richieste sono definite in uno AWS CloudFormation stack, chiamato stack bootstrap, che di solito viene denominato. CDKToolkit
Come ogni AWS CloudFormation stack, appare nella AWS CloudFormation console una volta distribuito:
Lo stesso si può dire per il bucket:
Per importare i servizi di cui abbiamo bisogno nel nostro file stack, possiamo usare il seguente comando:
npm install aws-cdk-lib # V2 command
Suggerimento
Se hai problemi con la V2, puoi installare le singole librerie usando i comandi V1:
npm install @aws-cdk/aws-appsync @aws-cdk/aws-dynamodb
Non lo consigliamo perché la V1 è obsoleta.
Implementazione di un progetto - Schema CDK
Ora possiamo iniziare a implementare il nostro codice. Innanzitutto, dobbiamo creare il nostro schema. Puoi semplicemente creare un .graphql
file nella tua app:
mkdir schema touch schema.graphql
Nel nostro esempio, abbiamo incluso una directory di primo livello chiamata schema
contenente il nostroschema.graphql
:
All'interno del nostro schema, includiamo un semplice esempio:
input CreatePostInput { title: String content: String } type Post { id: ID! title: String content: String } type Mutation { createPost(input: CreatePostInput!): Post } type Query { getPost: [Post] }
Tornando al nostro file stack, dobbiamo assicurarci che siano definite le seguenti direttive di importazione:
import * as cdk from 'aws-cdk-lib'; import * as appsync from 'aws-cdk-lib/aws-appsync'; import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; import { Construct } from 'constructs';
All'interno della classe, aggiungeremo il codice per creare il nostro GraphQL API e collegarlo al nostro schema.graphql
file:
export class ExampleCdkAppStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // makes a GraphQL API const api = new appsync.GraphqlApi(this, 'post-apis', { name: 'api-to-process-posts', schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'), }); } }
Aggiungeremo anche del codice per stampare GraphQLURL, la API chiave e la regione:
export class ExampleCdkAppStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Makes a GraphQL API construct const api = new appsync.GraphqlApi(this, 'post-apis', { name: 'api-to-process-posts', schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'), }); // Prints out URL new cdk.CfnOutput(this, "GraphQLAPIURL", { value: api.graphqlUrl }); // Prints out the AppSync GraphQL API key to the terminal new cdk.CfnOutput(this, "GraphQLAPIKey", { value: api.apiKey || '' }); // Prints out the stack region to the terminal new cdk.CfnOutput(this, "Stack Region", { value: this.region }); } }
A questo punto, utilizzeremo nuovamente la distribuzione della nostra app:
cdk deploy
Questo è il risultato:
Sembra che il nostro esempio abbia avuto successo, ma controlliamo la AWS AppSync console solo per confermare:
Sembra che il nostro API sia stato creato. Ora controlleremo lo schema allegato aAPI:
Questo sembra corrispondere al nostro codice dello schema, quindi ha avuto successo. Un altro modo per confermarlo dal punto di vista dei metadati è guardare lo AWS CloudFormation stack:
Quando distribuiamo la nostra CDK app, questa attiva risorse AWS CloudFormation come il bootstrap. Ogni stack all'interno della nostra app viene mappato 1:1 con uno stack. AWS CloudFormation Se torni al codice dello stack, il nome dello stack è stato preso dal nome della classe. ExampleCdkAppStack
Puoi vedere le risorse che ha creato, che corrispondono anche alle nostre convenzioni di denominazione, nel nostro costrutto GraphQL: API
Implementazione di un CDK progetto - Fonte dei dati
Successivamente, dobbiamo aggiungere la nostra fonte di dati. Il nostro esempio utilizzerà una tabella DynamoDB. All'interno della classe stack, aggiungeremo del codice per creare una nuova tabella:
export class ExampleCdkAppStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Makes a GraphQL API construct const api = new appsync.GraphqlApi(this, 'post-apis', { name: 'api-to-process-posts', schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'), }); //creates a DDB table const add_ddb_table = new dynamodb.Table(this, 'posts-table', { partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING, }, }); // Prints out URL new cdk.CfnOutput(this, "GraphQLAPIURL", { value: api.graphqlUrl }); // Prints out the AppSync GraphQL API key to the terminal new cdk.CfnOutput(this, "GraphQLAPIKey", { value: api.apiKey || '' }); // Prints out the stack region to the terminal new cdk.CfnOutput(this, "Stack Region", { value: this.region }); } }
A questo punto, eseguiamo nuovamente l'implementazione:
cdk deploy
Dovremmo controllare la console DynamoDB per la nostra nuova tabella:
Il nome del nostro stack è corretto e il nome della tabella corrisponde al nostro codice. Se controlliamo nuovamente il nostro AWS CloudFormation stack, ora vedremo la nuova tabella:
Implementazione di un CDK progetto - Resolver
Questo esempio utilizzerà due resolver: uno per interrogare la tabella e uno per aggiungervi. Poiché utilizziamo resolver di pipeline, dovremo dichiarare due resolver di pipeline con una funzione ciascuno. Nella query, aggiungeremo il seguente codice:
export class ExampleCdkAppStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Makes a GraphQL API construct const api = new appsync.GraphqlApi(this, 'post-apis', { name: 'api-to-process-posts', schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'), }); //creates a DDB table const add_ddb_table = new dynamodb.Table(this, 'posts-table', { partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING, }, }); // Creates a function for query const add_func = new appsync.AppsyncFunction(this, 'func-get-post', { name: 'get_posts_func_1', api, dataSource: api.addDynamoDbDataSource('table-for-posts', add_ddb_table), code: appsync.Code.fromInline(` export function request(ctx) { return { operation: 'Scan' }; } export function response(ctx) { return ctx.result.items; } `), runtime: appsync.FunctionRuntime.JS_1_0_0, }); // Creates a function for mutation const add_func_2 = new appsync.AppsyncFunction(this, 'func-add-post', { name: 'add_posts_func_1', api, dataSource: api.addDynamoDbDataSource('table-for-posts-2', add_ddb_table), code: appsync.Code.fromInline(` export function request(ctx) { return { operation: 'PutItem', key: util.dynamodb.toMapValues({id: util.autoId()}), attributeValues: util.dynamodb.toMapValues(ctx.args.input), }; } export function response(ctx) { return ctx.result; } `), runtime: appsync.FunctionRuntime.JS_1_0_0, }); // Adds a pipeline resolver with the get function new appsync.Resolver(this, 'pipeline-resolver-get-posts', { api, typeName: 'Query', fieldName: 'getPost', code: appsync.Code.fromInline(` export function request(ctx) { return {}; } export function response(ctx) { return ctx.prev.result; } `), runtime: appsync.FunctionRuntime.JS_1_0_0, pipelineConfig: [add_func], }); // Adds a pipeline resolver with the create function new appsync.Resolver(this, 'pipeline-resolver-create-posts', { api, typeName: 'Mutation', fieldName: 'createPost', code: appsync.Code.fromInline(` export function request(ctx) { return {}; } export function response(ctx) { return ctx.prev.result; } `), runtime: appsync.FunctionRuntime.JS_1_0_0, pipelineConfig: [add_func_2], }); // Prints out URL new cdk.CfnOutput(this, "GraphQLAPIURL", { value: api.graphqlUrl }); // Prints out the AppSync GraphQL API key to the terminal new cdk.CfnOutput(this, "GraphQLAPIKey", { value: api.apiKey || '' }); // Prints out the stack region to the terminal new cdk.CfnOutput(this, "Stack Region", { value: this.region }); } }
In questo frammento, abbiamo aggiunto un risolutore di pipeline chiamato pipeline-resolver-create-posts
con una funzione chiamata attached. func-add-post
Questo è il codice che verrà aggiunto alla tabella. Posts
L'altro risolutore di pipeline è stato chiamato pipeline-resolver-get-posts
con una funzione chiamata func-get-post
che recupera i dati Posts
aggiunti alla tabella.
Lo implementeremo per aggiungerlo al servizio: AWS AppSync
cdk deploy
Controlliamo la AWS AppSync console per vedere se erano collegate al nostro GraphQLAPI:
Sembra essere corretto. Nel codice, entrambi questi resolver erano collegati al GraphQL che API abbiamo creato (indicato dal valore api
props presente sia nei resolver che nelle funzioni). In GraphQLAPI, i campi a cui abbiamo collegato i nostri resolver sono stati specificati anche negli oggetti di scena (definiti da typename
e fieldname
props in ogni resolver).
Vediamo se il contenuto dei resolver è corretto a partire da: pipeline-resolver-get-posts
I gestori prima e dopo corrispondono al nostro valore props. code
Possiamo anche vedere una funzione chiamataadd_posts_func_1
, che corrisponde al nome della funzione che abbiamo inserito nel resolver.
Diamo un'occhiata al contenuto del codice di quella funzione:
Questo corrisponde agli code
oggetti di scena della add_posts_func_1
funzione. La nostra query è stata caricata correttamente, quindi controlliamo la query:
Anche questi corrispondono al codice. Se osserviamoget_posts_func_1
:
Sembra che tutto sia a posto. Per confermarlo dal punto di vista dei metadati, possiamo ricontrollare il nostro stack: AWS CloudFormation
Ora, dobbiamo testare questo codice eseguendo alcune richieste.
Implementazione di un CDK progetto - Richieste
Per testare la nostra app nella AWS AppSync console, abbiamo effettuato una query e una mutazione:
MyMutation
contiene un'createPost
operazione con gli argomenti 1970-01-01T12:30:00.000Z
efirst post
. Restituisce l'date
and title
che abbiamo passato e il id
valore generato automaticamente. L'esecuzione della mutazione produce il risultato:
{ "data": { "createPost": { "date": "1970-01-01T12:30:00.000Z", "id": "4dc1c2dd-0aa3-4055-9eca-7c140062ada2", "title": "first post" } } }
Se controlliamo rapidamente la tabella DynamoDB, possiamo vedere la nostra voce nella tabella quando la scansioniamo:
Tornando alla AWS AppSync console, se eseguiamo la query per recuperarloPost
, otteniamo il seguente risultato:
{ "data": { "getPost": [ { "id": "9f62c4dd-49d5-48d5-b835-143284c72fe0", "date": "1970-01-01T12:30:00.000Z", "title": "first post" } ] } }