

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à.

# Progettazione di GraphQL APIs con AWS AppSync
<a name="designing-a-graphql-api"></a>

AWS AppSync consente di creare GraphQL APIs utilizzando l'esperienza della console. L'hai visto di sfuggita nella sezione [Avvio](https://docs.aws.amazon.com/appsync/latest/devguide/quickstart.html) di uno schema di esempio. Tuttavia, quella guida non mostrava l'intero catalogo di opzioni e configurazioni che potevi sfruttare. AWS AppSync

Quando scegli di creare un'API GraphQL nella console, ci sono diverse opzioni da esplorare. Se hai seguito la nostra guida all'[avvio di uno schema di esempio](https://docs.aws.amazon.com/appsync/latest/devguide/quickstart.html), ti abbiamo mostrato come creare un'API da un modello predefinito. Nelle sezioni seguenti, ti guideremo attraverso il resto delle opzioni e configurazioni per la creazione di APIs AWS AppSync GraphQL in.

In questa sezione, esaminerai i seguenti concetti:

1. [Blank APIs or imports](blank-import-api.md#aws-appsync-blank-import-api): Questa guida illustrerà l'intero processo di creazione di un'API GraphQL. Imparerai come creare un GraphQL da un modello vuoto senza modello, configurare le fonti di dati per il tuo schema e aggiungere il tuo primo resolver a un campo.

1. [Real-time data](aws-appsync-real-time-data.md#aws-appsync-real-time-data-anchor): Questa guida ti mostrerà le potenziali opzioni per creare un'API utilizzando AWS AppSync il motore di G's. WebSocket 

1. [Merged APIs](merged-api.md#aws-appsync-merged-api): Questa guida ti mostrerà come creare un nuovo GraphQL associando e unendo dati APIs da più GraphQL esistenti. APIs

1. [Creazione di GraphQL APIs con l'introspezione RDS](rds-introspection.md): Questa guida ti mostrerà come integrare le tue tabelle Amazon RDS utilizzando un'API di dati.

# Strutturazione di un'API GraphQL (vuota o importata) APIs
<a name="blank-import-api"></a>

Prima di creare l'API GraphQL da un modello vuoto, sarebbe utile esaminare i concetti relativi a GraphQL. Esistono tre componenti fondamentali di un'API GraphQL:

1. Lo **schema** è il file contenente la forma e la definizione dei dati. Quando un client effettua una richiesta al servizio GraphQL, i dati restituiti seguiranno le specifiche dello schema. Per ulteriori informazioni, consulta [Schemi GraphQL](schema-components.md#aws-appsync-schema-components).

1. L'**origine dati** è allegata allo schema. Quando viene effettuata una richiesta, è qui che i dati vengono recuperati e modificati. Per ulteriori informazioni, consulta [Fonti di dati](data-source-components.md#aws-appsync-data-source-components).

1. Il **resolver** si trova tra lo schema e l'origine dati. Quando viene effettuata una richiesta, il resolver esegue l'operazione sui dati dall'origine, quindi restituisce il risultato come risposta. Per ulteriori informazioni, consulta [Risolutori](resolver-components.md#aws-appsync-resolver-components).

![\[GraphQL API architecture showing schema, resolvers, and data sources connected via AppSync.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/appsync-architecture-graphql-api.png)


AWS AppSync gestisce il tuo APIs consentendoti di creare, modificare e archiviare il codice per i tuoi schemi e resolver. Le tue fonti di dati proverranno da repository esterni come database, tabelle DynamoDB e funzioni Lambda. Se utilizzi un AWS servizio per archiviare i tuoi dati o hai intenzione di farlo, AWS AppSync offre un'esperienza quasi perfetta quando associ i dati dei tuoi account AWS al tuo GraphQL. APIs

Nella sezione successiva, imparerai come creare ciascuno di questi componenti utilizzando il servizio. AWS AppSync 

**Topics**
+ [Progettazione dello schema GraphQL](designing-your-schema.md)
+ [Allegare una fonte di dati](attaching-a-data-source.md)
+ [Configurazione AWS AppSync dei resolver](resolver-config-overview.md)
+ [Utilizzo APIs con il CDK](using-your-api.md)

# Progettazione dello schema GraphQL
<a name="designing-your-schema"></a>

Lo schema GraphQL è alla base di qualsiasi implementazione del server GraphQL. Ogni API GraphQL è definita da un **unico** schema che contiene tipi e campi che descrivono come verranno popolati i dati delle richieste. I dati che fluiscono attraverso l'API e le operazioni eseguite devono essere convalidati rispetto allo schema.

In generale, il [sistema di tipo GraphQL](https://graphql.org/learn/schema/#type-system) descrive le funzionalità di un server GraphQL e viene utilizzato per determinare se una query è valida. Il sistema di tipi di server viene spesso definito schema del server e può essere costituito da diversi tipi di oggetti, tipi scalari, tipi di input e altro ancora. GraphQL è sia dichiarativo che fortemente tipizzato, il che significa che i tipi saranno ben definiti in fase di esecuzione e restituiranno solo ciò che è stato specificato.

AWS AppSync consente di definire e configurare schemi GraphQL. La sezione seguente descrive come creare schemi GraphQL da zero utilizzando AWS AppSync i servizi di GraphQL.

## Strutturazione di uno schema GraphQL
<a name="schema-structure"></a>

**Suggerimento**  
Consigliamo di rivedere la sezione [Schemas](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html) prima di continuare.

GraphQL è un potente strumento per l'implementazione di servizi API. Secondo il [sito Web di GraphQL, GraphQL è](https://graphql.org/) il seguente:

«*GraphQL è un linguaggio di query APIs e un runtime per soddisfare tali richieste con i dati esistenti. GraphQL fornisce una descrizione completa e comprensibile dei dati dell'API, offre ai clienti la possibilità di chiedere esattamente ciò di cui hanno bisogno e nient'altro, facilita l'evoluzione APIs nel tempo e abilita potenti strumenti di sviluppo.* »

Questa sezione tratta la primissima parte dell'implementazione GraphQL, lo schema. Utilizzando la citazione precedente, uno schema svolge il ruolo di «fornire una descrizione completa e comprensibile dei dati nell'API». In altre parole, uno schema GraphQL è una rappresentazione testuale dei dati, delle operazioni e delle relazioni tra di essi del servizio. Lo schema è considerato il punto di ingresso principale per l'implementazione del servizio GraphQL. Non sorprende che sia spesso una delle prime cose che fai nel tuo progetto. Ti consigliamo di rivedere la sezione [Schemi prima di continuare](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html).

Per citare la sezione [Schemas](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html), gli schemi GraphQL sono scritti nello *Schema Definition* Language (SDL). SDL è composto da tipi e campi con una struttura consolidata:
+ **Tipi**: I tipi sono il modo in cui GraphQL definisce la forma e il comportamento dei dati. GraphQL supporta una moltitudine di tipi che verranno spiegati più avanti in questa sezione. Ogni tipo definito nello schema conterrà il proprio ambito. All'interno dell'ambito ci saranno uno o più campi che possono contenere un valore o una logica che verrà utilizzata nel servizio GraphQL. I tipi ricoprono molti ruoli diversi, i più comuni sono gli oggetti o gli scalari (tipi di valori primitivi).
+ **Campi**: i campi esistono nell'ambito di un tipo e contengono il valore richiesto dal servizio GraphQL. Sono molto simili alle variabili di altri linguaggi di programmazione. La forma dei dati definiti nei campi determinerà il modo in cui i dati sono strutturati in un' request/response operazione. Ciò consente agli sviluppatori di prevedere cosa verrà restituito senza sapere come viene implementato il backend del servizio.

Gli schemi più semplici conterranno tre diverse categorie di dati:

1. **Radici dello schema**: le radici definiscono i punti di ingresso dello schema. Indica i campi che eseguiranno alcune operazioni sui dati come aggiungere, eliminare o modificare qualcosa.

1. **Tipi**: si tratta di tipi di base utilizzati per rappresentare la forma dei dati. Puoi quasi pensarli come oggetti o rappresentazioni astratte di qualcosa con caratteristiche definite. Ad esempio, è possibile creare un `Person` oggetto che rappresenti una persona in un database. Le caratteristiche di ogni persona verranno definite all'interno dei campi `Person` as. Possono essere qualsiasi cosa, ad esempio il nome, l'età, il lavoro, l'indirizzo della persona, ecc.

1. **Tipi di oggetti speciali**: questi sono i tipi che definiscono il comportamento delle operazioni nello schema. Ogni tipo di oggetto speciale viene definito una volta per schema. Vengono prima inseriti nella radice dello schema, quindi definiti nel corpo dello schema. Ogni campo di un tipo di oggetto speciale definisce una singola operazione che deve essere implementata dal resolver.

Per metterlo in prospettiva, immagina di creare un servizio che memorizza gli autori e i libri che hanno scritto. Ogni autore ha un nome e una serie di libri di cui è autore. Ogni libro ha un nome e un elenco di autori associati. Vogliamo anche avere la possibilità di aggiungere o recuperare libri e autori. Una semplice rappresentazione UML di questa relazione può avere il seguente aspetto:

![\[UML diagram showing Author and Book classes with attributes and methods, linked by association.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/GraphQL-UML-1.png)


In GraphQL, le entità `Author` e `Book` rappresentano due diversi tipi di oggetti nello schema:

```
type Author {
}

type Book {
}
```

`Author`contiene `authorName` e`Books`, mentre `Book` contiene `bookName` e`Authors`. Questi possono essere rappresentati come campi che rientrano nell'ambito dei tuoi tipi:

```
type Author {
  authorName: String
  Books: [Book]
}

type Book {
  bookName: String
  Authors: [Author]
}
```

Come potete vedere, le rappresentazioni dei tipi sono molto simili al diagramma. Tuttavia, i metodi sono quelli in cui la cosa diventa un po' più complicata. Questi verranno inseriti in uno dei pochi tipi di oggetti speciali come campo. La loro classificazione speciale degli oggetti dipende dal loro comportamento. GraphQL contiene tre tipi di oggetti speciali fondamentali: query, mutazioni e sottoscrizioni. [Per ulteriori informazioni, vedete Oggetti speciali.](https://docs.aws.amazon.com//appsync/latest/devguide/graphql-types.html#special-object-components)

Poiché `getAuthor` `getBook` entrambi richiedono dati, verranno inseriti in un tipo di oggetto `Query` speciale:

```
type Author {
  authorName: String
  Books: [Book]
}

type Book {
  bookName: String
  Authors: [Author]
}

type Query {
  getAuthor(authorName: String): Author
  getBook(bookName: String): Book
}
```

Le operazioni sono collegate alla query, che a sua volta è collegata allo schema. L'aggiunta di una radice dello schema definirà il tipo di oggetto speciale (`Query`in questo caso) come uno dei punti di ingresso. Questo può essere fatto usando la `schema` parola chiave:

```
schema {
  query: Query
}

type Author {
  authorName: String
  Books: [Book]
}

type Book {
  bookName: String
  Authors: [Author]
}

type Query {
  getAuthor(authorName: String): Author
  getBook(bookName: String): Book
}
```

Considerando gli ultimi due metodi, `addAuthor` `addBook` stiamo aggiungendo dati al database, quindi verranno definiti in un tipo di oggetto `Mutation` speciale. Tuttavia, dalla pagina [Tipi](https://docs.aws.amazon.com/appsync/latest/devguide/graphql-types.html#input-components), sappiamo anche che gli input che fanno riferimento direttamente agli oggetti non sono consentiti perché sono strettamente tipi di output. In questo caso, non possiamo usare `Author` or`Book`, quindi dobbiamo creare un tipo di input con gli stessi campi. In questo esempio, abbiamo aggiunto `AuthorInput` e`BookInput`, entrambi, accettano gli stessi campi dei rispettivi tipi. Quindi, creiamo la nostra mutazione usando gli input come parametri:

```
schema {
  query: Query
  mutation: Mutation
}

type Author {
  authorName: String
  Books: [Book]
}

input AuthorInput {
  authorName: String
  Books: [BookInput]
}

type Book {
  bookName: String
  Authors: [Author]
}

input BookInput {
  bookName: String
  Authors: [AuthorInput]
}

type Query {
  getAuthor(authorName: String): Author
  getBook(bookName: String): Book
}

type Mutation {
  addAuthor(input: [BookInput]): Author
  addBook(input: [AuthorInput]): Book
}
```

Rivediamo cosa abbiamo appena fatto:

1. Abbiamo creato uno schema con i `Author` tipi `Book` e per rappresentare le nostre entità.

1. Abbiamo aggiunto i campi contenenti le caratteristiche delle nostre entità.

1. Abbiamo aggiunto una query per recuperare queste informazioni dal database.

1. Abbiamo aggiunto una mutazione per manipolare i dati nel database.

1. Abbiamo aggiunto tipi di input per sostituire i parametri dei nostri oggetti nella mutazione per rispettare le regole di GraphQL.

1. Abbiamo aggiunto la query e la mutazione al nostro schema principale in modo che l'implementazione GraphQL comprenda la posizione del tipo di radice.

Come puoi vedere, il processo di creazione di uno schema richiede molti concetti tratti dalla modellazione dei dati (in particolare dalla modellazione di database) in generale. Si può pensare che lo schema si adatti alla forma dei dati di origine. Serve anche come modello che il resolver implementerà. Nelle sezioni seguenti, imparerai come creare uno schema utilizzando vari strumenti e AWS servizi supportati.

**Nota**  
Gli esempi nelle sezioni seguenti non sono pensati per essere eseguiti in un'applicazione reale. Servono solo a mostrare i comandi in modo da poter creare applicazioni personalizzate.

## Creazione di schemi
<a name="creating-schema"></a>

Lo schema sarà contenuto in un file chiamato`schema.graphql`. AWS AppSync consente agli utenti di creare nuovi schemi per il proprio APIs GraphQL utilizzando vari metodi. In questo esempio, creeremo un'API vuota insieme a uno schema vuoto.

------
#### [ Console ]

1. Accedi a Console di gestione AWS e apri la [AppSyncconsole](https://console.aws.amazon.com/appsync/).

   1. Nel **pannello di controllo**, scegliere **Create API (Crea API)**.

   1. **In **Opzioni API**, scegli **GraphQL APIs**, **Progetta da zero**, quindi Avanti.**

      1. Per **il nome dell'API**, modifica il nome precompilato in base alle esigenze dell'applicazione.

      1. Per **i dettagli di contatto**, puoi inserire un punto di contatto per identificare un gestore dell'API. Questo campo è opzionale.

      1. In **Configurazione API privata**, puoi abilitare le funzionalità dell'API privata. È possibile accedere a un'API privata solo da un endpoint VPC configurato (VPCE). [Per ulteriori informazioni, consulta Privato. APIs](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html)

         Non è consigliabile abilitare questa funzionalità per questo esempio. Scegli **Avanti** dopo aver esaminato i dati inseriti.

   1. In **Crea un tipo GraphQL**, puoi scegliere di creare una tabella DynamoDB da utilizzare come origine dati o saltare questa operazione e farlo in un secondo momento.

      Per questo esempio, scegli **Create GraphQL resources** in un secondo momento. Creeremo una risorsa in una sezione separata.

   1. Controlla i tuoi input, quindi scegli **Crea API**.

1. Sarai nella dashboard della tua API specifica. Puoi capirlo perché il nome dell'API sarà nella parte superiore della dashboard. In caso contrario, puoi selezionarlo **APIs**nella **barra laterale**, quindi scegliere l'API nella **APIs dashboard**.

   1. **Nella **barra laterale** sotto il nome dell'API, scegli Schema.**

1. Nell'**editor dello schema**, puoi configurare il tuo file. `schema.graphql` Può essere vuoto o pieno di tipi generati da un modello. Sulla destra, c'è la sezione **Resolver per allegare i resolver** ai campi dello schema. Non esamineremo i resolver in questa sezione.

------
#### [ CLI ]

**Nota**  
Quando utilizzi la CLI, assicurati di disporre delle autorizzazioni corrette per accedere e creare risorse nel servizio. Potresti voler impostare politiche con [privilegi minimi](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege) per gli utenti non amministratori che devono accedere al servizio. Per ulteriori informazioni sulle AWS AppSync politiche, consulta Gestione delle [identità](https://docs.aws.amazon.com//appsync/latest/devguide/security-iam.html) e degli accessi per. AWS AppSync  
Inoltre, ti consigliamo di leggere prima la versione per console se non l'hai già fatto.

1. [Se non l'hai già fatto, [installa](https://docs.aws.amazon.com//cli/latest/userguide/cli-chap-getting-started.html) la AWS CLI, quindi aggiungi la tua configurazione.](https://docs.aws.amazon.com//cli/latest/userguide/cli-configure-quickstart.html)

1. Crea un oggetto API GraphQL eseguendo il [https://docs.aws.amazon.com/cli/latest/reference/appsync/create-graphql-api.html](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-graphql-api.html)comando.

   Dovrai digitare due parametri per questo particolare comando:

   1. La `name` della tua API.

   1. Il o `authentication-type` il tipo di credenziali utilizzate per accedere all'API (IAM, OIDC, ecc.).
**Nota**  
Altri parametri, ad esempio, `Region` devono essere configurati, ma di solito vengono utilizzati per impostazione predefinita i valori di configurazione CLI.

   Un comando di esempio può avere il seguente aspetto:

   ```
   aws appsync create-graphql-api --name testAPI123 --authentication-type API_KEY
   ```

   Un output verrà restituito nella CLI. Ecco un esempio:

   ```
   {
       "graphqlApi": {
           "xrayEnabled": false,
           "name": "testAPI123",
           "authenticationType": "API_KEY",
           "tags": {},
           "apiId": "abcdefghijklmnopqrstuvwxyz",
           "uris": {
               "GRAPHQL": "https://zyxwvutsrqponmlkjihgfedcba.appsync-api.us-west-2.amazonaws.com/graphql",
               "REALTIME": "wss://zyxwvutsrqponmlkjihgfedcba.appsync-realtime-api.us-west-2.amazonaws.com/graphql"
           },
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz"
       }
   }
   ```

1. 
**Nota**  
Si tratta di un comando opzionale che accetta uno schema esistente e lo carica sul AWS AppSync servizio utilizzando un blob base-64. Non utilizzeremo questo comando per questo esempio.

   Esegui il comando [https://docs.aws.amazon.com/cli/latest/reference/appsync/start-schema-creation.html](https://docs.aws.amazon.com/cli/latest/reference/appsync/start-schema-creation.html).

   Dovrai digitare due parametri per questo particolare comando:

   1. Provieni `api-id` dal passaggio precedente.

   1. Lo schema `definition` è un blob binario codificato in base 64.

   Un comando di esempio può avere il seguente aspetto:

   ```
    aws appsync start-schema-creation --api-id abcdefghijklmnopqrstuvwxyz --definition "aa1111aa-123b-2bb2-c321-12hgg76cc33v"
   ```

   Verrà restituito un output:

   ```
   {
       "status": "PROCESSING"
   }
   ```

   Questo comando non restituirà l'output finale dopo l'elaborazione. È necessario utilizzare un comando separato per visualizzare il risultato. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/get-schema-creation-status.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/get-schema-creation-status.html) Nota che questi due comandi sono asincroni, quindi puoi controllare lo stato dell'output anche mentre lo schema è ancora in fase di creazione.

------
#### [ CDK ]

**Suggerimento**  
[Prima di utilizzare il CDK, consigliamo di consultare la [documentazione ufficiale](https://docs.aws.amazon.com/cdk/v2/guide/home.html) del CDK insieme al riferimento CDK. AWS AppSync](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
I passaggi elencati di seguito mostreranno solo un esempio generale dello snippet utilizzato per aggiungere una particolare risorsa. Questa **non** è pensata per essere una soluzione funzionante nel codice di produzione. Supponiamo inoltre che tu abbia già un'app funzionante.

1. Il punto di partenza per il CDK è leggermente diverso. Idealmente, il `schema.graphql` file dovrebbe essere già stato creato. Devi solo creare un nuovo file con l'estensione del `.graphql` file. Questo può essere un file vuoto.

1. In generale, potrebbe essere necessario aggiungere la direttiva di importazione al servizio che si sta utilizzando. Ad esempio, può seguire i moduli:

   ```
   import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
   import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
   ```

   Per aggiungere un'API GraphQL, il file stack deve importare il servizio: AWS AppSync 

   ```
   import * as appsync from 'aws-cdk-lib/aws-appsync';
   ```
**Nota**  
Ciò significa che stiamo importando l'intero servizio con la parola chiave. `appsync` Per utilizzarlo nella tua app, i tuoi AWS AppSync costrutti utilizzeranno il formato. `appsync.construct_name` Ad esempio, se volessimo creare un'API GraphQL, diremmo. `new appsync.GraphqlApi(args_go_here)` Il passaggio seguente illustra questo.

1. L'API GraphQL più semplice includerà una `name` per l'API e il `schema` percorso.

   ```
   const add_api = new appsync.GraphqlApi(this, 'API_ID', {
     name: 'name_of_API_in_console',
     schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema_name.graphql')),
   });
   ```
**Nota**  
Esaminiamo cosa fa questo frammento. Nell'ambito di`api`, stiamo creando una nuova API GraphQL chiamando. `appsync.GraphqlApi(scope: Construct, id: string, props: GraphqlApiProps)` L'ambito è`this`, che si riferisce all'oggetto corrente. L'id è*API\$1ID*, che sarà il nome della risorsa dell'API GraphQL al CloudFormation momento della creazione. `GraphqlApiProps`Contiene la `name` tua API GraphQL e il. `schema` `schema`Genererà uno schema (`SchemaFile.fromAsset`) cercando il percorso assoluto (`__dirname`) per il `.graphql` file (*schema\$1name.graphql*). In uno scenario reale, il file di schema si troverà probabilmente all'interno dell'app CDK.  
Per utilizzare le modifiche apportate alla tua API GraphQL, dovrai ridistribuire l'app.

------

## Aggiungere tipi agli schemi
<a name="adding-schema-types"></a>

Ora che hai aggiunto lo schema, puoi iniziare ad aggiungere sia i tipi di input che quelli di output. Nota che i tipi qui non devono essere usati nel codice reale; sono solo esempi per aiutarti a comprendere il processo.

Per prima cosa, creeremo un tipo di oggetto. Nel codice reale, non è necessario iniziare con questi tipi. Puoi creare qualsiasi tipo desideri in qualsiasi momento purché segua le regole e la sintassi di GraphQL.

**Nota**  
Nelle prossime sezioni verrà utilizzato l'**editor di schemi**, quindi tienilo aperto.

------
#### [ Console ]
+ È possibile creare un tipo di oggetto utilizzando la `type` parola chiave insieme al nome del tipo:

  ```
  type Type_Name_Goes_Here {}
  ```

  All'interno dell'ambito del tipo, puoi aggiungere campi che rappresentano le caratteristiche dell'oggetto:

  ```
  type Type_Name_Goes_Here {
    # Add fields here
  }
  ```

  Ecco un esempio:

  ```
  type Obj_Type_1 {
    id: ID!
    title: String
    date: AWSDateTime
  }
  ```
**Nota**  
In questo passaggio, abbiamo aggiunto un tipo di oggetto generico con un `id` campo obbligatorio memorizzato come`ID`, un `title` campo archiviato come e un `date` campo archiviato come`AWSDateTime`. `String` Per visualizzare un elenco di tipi e campi e le relative funzioni, consulta [Schemi](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html). Per visualizzare un elenco di scalari e cosa fanno, consulta il riferimento [Type](https://docs.aws.amazon.com/appsync/latest/devguide/type-reference.html).

------
#### [ CLI ]

**Nota**  
Ti consigliamo di leggere prima la versione per console se non l'hai già fatto.
+ È possibile creare un tipo di oggetto eseguendo il [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html)comando.

  Dovrai inserire alcuni parametri per questo particolare comando:

  1. La `api-id` della tua API.

  1. Il`definition`, o il contenuto del tuo tipo. Nell'esempio della console, questo era:

     ```
     type Obj_Type_1 {
       id: ID!
       title: String
       date: AWSDateTime
     }
     ```

  1. Il `format` tuo input. In questo esempio, stiamo usando`SDL`.

  Un comando di esempio può essere simile al seguente:

  ```
  aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "type Obj_Type_1{id: ID! title: String date: AWSDateTime}" --format SDL
  ```

  Un output verrà restituito nella CLI. Ecco un esempio:

  ```
  {
      "type": {
          "definition": "type Obj_Type_1{id: ID! title: String date: AWSDateTime}",
          "name": "Obj_Type_1",
          "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Obj_Type_1",
          "format": "SDL"
      }
  }
  ```
**Nota**  
In questo passaggio, abbiamo aggiunto un tipo di oggetto generico con un `id` campo obbligatorio memorizzato come`ID`, un `title` campo archiviato come e un `date` campo archiviato come. `String` `AWSDateTime` Per visualizzare un elenco di tipi e campi e le relative funzioni, consulta [Schemi](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html). Per visualizzare un elenco di scalari e cosa fanno, vedi [Type](https://docs.aws.amazon.com/appsync/latest/devguide/type-reference.html) reference.  
Inoltre, potresti aver capito che l'immissione diretta della definizione funziona per i tipi più piccoli, ma non è possibile aggiungere tipi più grandi o multipli. Puoi scegliere di aggiungere tutto in un `.graphql` file e poi [passarlo come input](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-file.html).

------
#### [ CDK ]

**Suggerimento**  
Prima di utilizzare il CDK, consigliamo di consultare la [documentazione ufficiale del CDK insieme AWS AppSync al riferimento](https://docs.aws.amazon.com/cdk/v2/guide/home.html) [CDK](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html).  
I passaggi elencati di seguito mostreranno solo un esempio generale dello snippet utilizzato per aggiungere una particolare risorsa. Questa **non** è pensata per essere una soluzione funzionante nel codice di produzione. Supponiamo inoltre che tu abbia già un'app funzionante.

Per aggiungere un tipo, devi aggiungerlo al tuo `.graphql` file. Ad esempio, l'esempio della console era:

```
type Obj_Type_1 {
  id: ID!
  title: String
  date: AWSDateTime
}
```

Puoi aggiungere i tuoi tipi direttamente allo schema come qualsiasi altro file.

**Nota**  
Per utilizzare le modifiche apportate alla tua API GraphQL, dovrai ridistribuire l'app.

------

Il [tipo di oggetto](https://graphql.org/learn/schema/#object-types-and-fields) ha campi di [tipo scalare](https://graphql.org/learn/schema/#scalar-types) come stringhe e numeri interi. AWS AppSync consente inoltre di utilizzare tipi scalari avanzati, ad esempio `AWSDateTime` in aggiunta agli scalari GraphQL di base. Inoltre, è obbligatorio qualsiasi campo che termina con un punto esclamativo. 

Il tipo `ID` scalare, in particolare, è un identificatore univoco che può essere uno dei due. `String` `Int` È possibile controllarli nel codice del resolver per l'assegnazione automatica.

Esistono delle somiglianze tra tipi di oggetti speciali come quelli `Query` «normali», come nell'esempio precedente, in quanto entrambi usano la `type` parola chiave e sono considerati oggetti. Tuttavia, per i tipi di oggetti speciali (`Query`,`Mutation`, and`Subscription`), il loro comportamento è molto diverso perché sono esposti come punti di ingresso per l'API. Si occupano anche più di modellare le operazioni piuttosto che i dati. Per ulteriori informazioni, consulta [I tipi di interrogazione e mutazione.](https://graphql.org/learn/schema/#the-query-and-mutation-types)

Per quanto riguarda i tipi di oggetti speciali, il passaggio successivo potrebbe essere quello di aggiungerne uno o più per eseguire operazioni sui dati sagomati. In uno scenario reale, ogni schema GraphQL deve avere almeno un tipo di query root per la richiesta dei dati. Puoi pensare alla query come a uno dei punti di ingresso (o endpoint) del tuo server GraphQL. Aggiungiamo una query come esempio.

------
#### [ Console ]
+ Per creare una query, è sufficiente aggiungerla al file di schema come qualsiasi altro tipo. Una query richiederebbe un `Query` tipo e una voce nella radice come segue:

  ```
  schema {
    query: Name_of_Query
  }
  
  type Name_of_Query {
    # Add field operation here
  }
  ```

  Nota che *Name\$1of\$1Query* in un ambiente di produzione verrà semplicemente chiamato `Query` nella maggior parte dei casi. Si consiglia di mantenerlo a questo valore. All'interno del tipo di query, puoi aggiungere campi. Ogni campo eseguirà un'operazione nella richiesta. Di conseguenza, la maggior parte, se non tutti, questi campi verranno allegati a un resolver. Tuttavia, questo non ci interessa in questa sezione. Per quanto riguarda il formato dell'operazione sul campo, potrebbe essere simile a questo:

  ```
  Name_of_Query(params): Return_Type # version with params
  Name_of_Query: Return_Type # version without params
  ```

  Ecco un esempio:

  ```
  schema {
    query: Query
  }
  
  type Query {
    getObj: [Obj_Type_1]
  }
  
  type Obj_Type_1 {
    id: ID!
    title: String
    date: AWSDateTime
  }
  ```
**Nota**  
In questo passaggio, abbiamo aggiunto un `Query` tipo e lo abbiamo definito nella `schema` radice. Il nostro `Query` tipo ha definito un `getObj` campo che restituisce un elenco di `Obj_Type_1` oggetti. Nota che `Obj_Type_1` è l'oggetto del passaggio precedente. Nel codice di produzione, le operazioni sul campo normalmente funzioneranno con dati modellati da oggetti come`Obj_Type_1`. Inoltre, campi come quelli `getObj` normalmente dispongono di un resolver per eseguire la logica aziendale. Questo sarà trattato in una sezione diversa.  
Come nota aggiuntiva, aggiunge AWS AppSync automaticamente una radice dello schema durante le esportazioni, quindi tecnicamente non è necessario aggiungerla direttamente allo schema. Il nostro servizio elaborerà automaticamente gli schemi duplicati. Lo stiamo aggiungendo qui come best practice.

------
#### [ CLI ]

**Nota**  
Ti consigliamo di leggere prima la versione per console se non l'hai già fatto.

1. Crea una `schema` radice con una `query` definizione eseguendo il [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html)comando.

   Dovrai inserire alcuni parametri per questo particolare comando:

   1. La `api-id` della tua API.

   1. Il`definition`, o il contenuto del tuo tipo. Nell'esempio della console, questo era:

      ```
      schema {
        query: Query
      }
      ```

   1. Il `format` tuo input. In questo esempio, stiamo usando`SDL`.

   Un comando di esempio può essere simile al seguente:

   ```
   aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "schema {query: Query}" --format SDL
   ```

   Un output verrà restituito nella CLI. Ecco un esempio:

   ```
   {
       "type": {
           "definition": "schema {query: Query}",
           "name": "schema",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/schema",
           "format": "SDL"
       }
   }
   ```
**Nota**  
Nota che se non hai inserito qualcosa correttamente nel `create-type` comando, puoi aggiornare la radice dello schema (o qualsiasi tipo nello schema) eseguendo il [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html)comando. In questo esempio, cambieremo temporaneamente la radice dello schema per contenere una `subscription` definizione.  
Dovrai inserire alcuni parametri per questo particolare comando:  
La `api-id` della tua API.
Il tuo `type-name` tipo. Nell'esempio della console, questo era`schema`.
Il`definition`, o il contenuto del tuo tipo. Nell'esempio della console, questo era:  

      ```
      schema {
        query: Query
      }
      ```
Lo schema dopo l'aggiunta di un `subscription` sarà simile al seguente:  

      ```
      schema {
        query: Query
        subscription: Subscription
      }
      ```
Il `format` tuo contributo. In questo esempio, stiamo usando`SDL`.
Un comando di esempio può essere simile al seguente:  

   ```
   aws appsync update-type --api-id abcdefghijklmnopqrstuvwxyz --type-name schema --definition "schema {query: Query subscription: Subscription}" --format SDL
   ```
Un output verrà restituito nella CLI. Ecco un esempio:  

   ```
   {
       "type": {
           "definition": "schema {query: Query subscription: Subscription}",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/schema",
           "format": "SDL"
       }
   }
   ```
L'aggiunta di file preformattati continuerà a funzionare in questo esempio.

1. Crea un `Query` tipo eseguendo il [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html)comando.

   Dovrai inserire alcuni parametri per questo particolare comando:

   1. La `api-id` della tua API.

   1. Il`definition`, o il contenuto del tuo tipo. Nell'esempio della console, questo era:

      ```
      type Query {
        getObj: [Obj_Type_1]
      }
      ```

   1. Il `format` tuo input. In questo esempio, stiamo usando`SDL`.

   Un comando di esempio può essere simile al seguente:

   ```
   aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "type Query {getObj: [Obj_Type_1]}" --format SDL
   ```

   Un output verrà restituito nella CLI. Ecco un esempio:

   ```
   {
       "type": {
           "definition": "Query {getObj: [Obj_Type_1]}",
           "name": "Query",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Query",
           "format": "SDL"
       }
   }
   ```
**Nota**  
In questo passaggio, abbiamo aggiunto un `Query` tipo e lo abbiamo definito nella `schema` radice. Il nostro `Query` tipo ha definito un `getObj` campo che ha restituito un elenco di `Obj_Type_1` oggetti.  
Nel codice `schema` principale`query: Query`, la `query:` parte indica che una query è stata definita nello schema, mentre la `Query` parte indica il nome effettivo dell'oggetto speciale. 

------
#### [ CDK ]

**Suggerimento**  
Prima di utilizzare il CDK, consigliamo di consultare la [documentazione ufficiale del CDK insieme AWS AppSync al riferimento](https://docs.aws.amazon.com/cdk/v2/guide/home.html) [CDK](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html).  
I passaggi elencati di seguito mostreranno solo un esempio generale dello snippet utilizzato per aggiungere una particolare risorsa. Questa **non** è pensata per essere una soluzione funzionante nel codice di produzione. Supponiamo inoltre che tu abbia già un'app funzionante.

Dovrai aggiungere la tua query e la radice dello schema al `.graphql` file. Il nostro esempio assomigliava all'esempio seguente, ma ti consigliamo di sostituirlo con il codice dello schema effettivo:

```
schema {
  query: Query
}

type Query {
  getObj: [Obj_Type_1]
}

type Obj_Type_1 {
  id: ID!
  title: String
  date: AWSDateTime
}
```

Puoi aggiungere i tuoi tipi direttamente allo schema come qualsiasi altro file.

**Nota**  
L'aggiornamento della radice dello schema è facoltativo. L'abbiamo aggiunta a questo esempio come procedura consigliata.  
Per utilizzare le modifiche apportate alla tua API GraphQL, dovrai ridistribuire l'app.

------

Ora hai visto un esempio di creazione sia di oggetti che di oggetti speciali (query). Hai anche visto come questi possono essere interconnessi per descrivere dati e operazioni. Puoi avere schemi con solo la descrizione dei dati e una o più interrogazioni. Tuttavia, vorremmo aggiungere un'altra operazione per aggiungere dati all'origine dati. Aggiungeremo un altro tipo di oggetto speciale chiamato `Mutation` che modifica i dati.

------
#### [ Console ]
+ Verrà chiamata una mutazione. `Mutation` Ad esempio`Query`, le operazioni sul campo interne `Mutation` descriveranno un'operazione e saranno collegate a un resolver. Inoltre, nota che dobbiamo definirlo nella `schema` radice perché è un tipo di oggetto speciale. Ecco un esempio di mutazione:

  ```
  schema {
    mutation: Name_of_Mutation
  }
  
  type Name_of_Mutation {
    # Add field operation here
  }
  ```

  Una mutazione tipica verrà elencata nella radice come una query. La mutazione viene definita utilizzando la `type` parola chiave insieme al nome. *Name\$1of\$1Mutation*di solito viene chiamato`Mutation`, quindi consigliamo di mantenerlo in questo modo. Ogni campo eseguirà anche un'operazione. Per quanto riguarda il formato dell'operazione sul campo, potrebbe essere simile a questo:

  ```
  Name_of_Mutation(params): Return_Type # version with params
  Name_of_Mutation: Return_Type # version without params
  ```

  Ecco un esempio:

  ```
  schema {
    query: Query
    mutation: Mutation
  }
  
  type Obj_Type_1 {
    id: ID!
    title: String
    date: AWSDateTime
  }
  
  type Query {
    getObj: [Obj_Type_1]
  }
  
  type Mutation {
    addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
  }
  ```
**Nota**  
In questo passaggio, abbiamo aggiunto un `Mutation` tipo con un `addObj` campo. Riassumiamo cosa fa questo campo:  

  ```
  addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
  ```
`addObj`sta usando l'`Obj_Type_1`oggetto per eseguire un'operazione. Ciò è evidente a causa dei campi, ma la sintassi lo dimostra nel tipo `: Obj_Type_1` restituito. All'interno`addObj`, accetta i `id` `date` campi e e dell'`Obj_Type_1`oggetto come parametri. `title` Come puoi vedere, assomiglia molto a una dichiarazione di metodo. Tuttavia, non abbiamo ancora descritto il comportamento del nostro metodo. Come affermato in precedenza, lo schema serve solo a definire quali saranno i dati e le operazioni e non come funzioneranno. L'implementazione dell'effettiva logica aziendale avverrà più avanti, quando creeremo i nostri primi resolver.  
Una volta che hai finito con lo schema, c'è un'opzione per esportarlo come file. `schema.graphql` Nell'**editor dello schema**, puoi scegliere **Esporta schema** per scaricare il file in un formato supportato.  
Come nota aggiuntiva, aggiunge AWS AppSync automaticamente una radice dello schema durante le esportazioni, quindi tecnicamente non è necessario aggiungerla direttamente allo schema. Il nostro servizio elaborerà automaticamente gli schemi duplicati. Lo stiamo aggiungendo qui come best practice.

------
#### [ CLI ]

**Nota**  
Ti consigliamo di leggere prima la versione per console se non l'hai già fatto.

1. Aggiorna lo schema root eseguendo il [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html)comando.

   Dovrai inserire alcuni parametri per questo particolare comando:

   1. La `api-id` della tua API.

   1. Il tuo `type-name` tipo. Nell'esempio della console, questo era`schema`.

   1. Il`definition`, o il contenuto del tuo tipo. Nell'esempio della console, questo era:

      ```
      schema {
        query: Query
        mutation: Mutation
      }
      ```

   1. Il `format` tuo input. In questo esempio, stiamo usando`SDL`.

   Un comando di esempio può essere simile al seguente:

   ```
   aws appsync update-type --api-id abcdefghijklmnopqrstuvwxyz --type-name schema --definition "schema {query: Query mutation: Mutation}" --format SDL
   ```

   Un output verrà restituito nella CLI. Ecco un esempio:

   ```
   {
       "type": {
           "definition": "schema {query: Query mutation: Mutation}",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/schema",
           "format": "SDL"
       }
   }
   ```

1. Crea un `Mutation` tipo eseguendo il [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html)comando.

   Dovrai inserire alcuni parametri per questo particolare comando:

   1. La `api-id` della tua API.

   1. Il`definition`, o il contenuto del tuo tipo. Nell'esempio della console, questo era

      ```
      type Mutation {
        addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
      }
      ```

   1. Il `format` tuo input. In questo esempio, stiamo usando`SDL`.

   Un comando di esempio può essere simile al seguente:

   ```
   aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "type Mutation {addObj(id: ID! title: String date: AWSDateTime): Obj_Type_1}" --format SDL
   ```

   Un output verrà restituito nella CLI. Ecco un esempio:

   ```
   {
       "type": {
           "definition": "type Mutation {addObj(id: ID! title: String date: AWSDateTime): Obj_Type_1}",
           "name": "Mutation",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation",
           "format": "SDL"
       }
   }
   ```

------
#### [ CDK ]

**Suggerimento**  
[Prima di utilizzare il CDK, consigliamo di consultare la [documentazione ufficiale del CDK insieme AWS AppSync al riferimento](https://docs.aws.amazon.com/cdk/v2/guide/home.html) CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
I passaggi elencati di seguito mostreranno solo un esempio generale dello snippet utilizzato per aggiungere una particolare risorsa. Questa **non** è pensata per essere una soluzione funzionante nel codice di produzione. Supponiamo inoltre che tu abbia già un'app funzionante.

Dovrai aggiungere la tua query e la radice dello schema al `.graphql` file. Il nostro esempio assomigliava all'esempio seguente, ma ti consigliamo di sostituirlo con il codice dello schema effettivo:

```
schema {
  query: Query
  mutation: Mutation
}

type Obj_Type_1 {
  id: ID!
  title: String
  date: AWSDateTime
}

type Query {
  getObj: [Obj_Type_1]
}

type Mutation {
  addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
}
```

**Nota**  
L'aggiornamento della radice dello schema è facoltativo. L'abbiamo aggiunta a questo esempio come procedura consigliata.  
Per utilizzare le modifiche apportate alla tua API GraphQL, dovrai ridistribuire l'app.

------

## Considerazioni facoltative: utilizzo delle enumerazioni come stati
<a name="optional-consideration-enums"></a>

A questo punto, sapete come creare uno schema di base. Tuttavia, ci sono molte cose che è possibile aggiungere per aumentare la funzionalità dello schema. Una caratteristica comune nelle applicazioni è l'uso di enumerazioni come stati. È possibile utilizzare un enum per forzare un valore specifico da un insieme di valori da scegliere quando viene chiamato. Questo è utile per cose che sai non cambieranno drasticamente per lunghi periodi di tempo. Ipoteticamente parlando, potremmo aggiungere un enum che restituisca il codice di stato o la stringa nella risposta. 

Ad esempio, supponiamo di creare un'app per social media che memorizza i dati dei post di un utente nel backend. Il nostro schema contiene un `Post` tipo che rappresenta i dati di un singolo post:

```
type Post {
  id: ID!
  title: String
  date: AWSDateTime
  poststatus: PostStatus
}
```

Il nostro `Post` conterrà un unico `id` post `title` `date` di pubblicazione e un enum chiamato `PostStatus` che rappresenta lo stato del post così come viene elaborato dall'app. Per le nostre operazioni, avremo una query che restituisce tutti i dati dei post:

```
type Query {
  getPosts: [Post]
}
```

Avremo anche una mutazione che aggiunge post alla fonte di dati:

```
type Mutation {
  addPost(id: ID!, title: String, date: AWSDateTime, poststatus: PostStatus): Post
}
```

Guardando il nostro schema, l'`PostStatus`enum potrebbe avere diversi stati. Potremmo volere che i tre stati di base si chiamino `success` (post elaborato con successo), `pending` (post in fase di elaborazione) e `error` (post non in grado di essere elaborato). Per aggiungere l'enum, potremmo fare questo:

```
enum PostStatus {
  success
  pending
  error
}
```

Lo schema completo potrebbe essere simile a questo:

```
schema {
  query: Query
  mutation: Mutation
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
  poststatus: PostStatus
}

type Mutation {
  addPost(id: ID!, title: String, date: AWSDateTime, poststatus: PostStatus): Post
}

type Query {
  getPosts: [Post]
}

enum PostStatus {  
  success
  pending
  error
}
```

Se un utente aggiunge un `Post` nell'applicazione, l'`addPost`operazione verrà chiamata per elaborare quei dati. Man mano che il resolver collegato `addPost` elabora i dati, li aggiornerà continuamente `poststatus` con lo stato dell'operazione. Quando richiesto, `Post` conterrà lo stato finale dei dati. Tieni presente che stiamo solo descrivendo come vogliamo che i dati funzionino nello schema. Stiamo dando molte supposizioni sull'implementazione dei nostri resolver, che implementeranno l'effettiva logica aziendale per la gestione dei dati per soddisfare la richiesta.

## Considerazioni opzionali - Abbonamenti
<a name="optional-consideration-subscriptions"></a>

Le sottoscrizioni in AWS AppSync vengono richiamate come risposta a una mutazione. È possibile configurare ciò con un tipo `Subscription` e una direttiva `@aws_subscribe()` nello schema, per indicare quali mutazioni richiamano una o più sottoscrizioni. [Per ulteriori informazioni sulla configurazione degli abbonamenti, consulta Dati in tempo reale.](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html)

## Considerazioni facoltative: relazioni e impaginazione
<a name="optional-consideration-relations-and-pagination"></a>

Supponiamo di avere un milione `Posts` archiviato in una tabella DynamoDB e di voler restituire alcuni di quei dati. Tuttavia, la query di esempio riportata sopra restituisce solo tutti i post. Non vorrai recuperarli tutti ogni volta che fai una richiesta. Invece, dovresti [sfogliarli per pagina](https://graphql.org/learn/pagination/). Apporta le modifiche seguenti allo schema:
+ Nel `getPosts` campo, aggiungi due argomenti di input: `nextToken` (iteratore) e `limit` (limite di iterazione).
+ Aggiungi un nuovo `PostIterator` tipo contenente `Posts` (recupera l'elenco degli `Post` oggetti) e `nextToken` (iteratore) i campi.
+ Modifica `getPosts` in modo che restituisca `PostIterator` e non un elenco di `Post` oggetti.

```
schema {
  query: Query
  mutation: Mutation
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
  poststatus: PostStatus
}

type Mutation {
  addPost(id: ID!, title: String, date: AWSDateTime, poststatus: PostStatus): Post
}

type Query {
  getPosts(limit: Int, nextToken: String): PostIterator
}

enum PostStatus {
  success
  pending
  error
}

type PostIterator {
  posts: [Post]
  nextToken: String
}
```

Il `PostIterator` tipo consente di restituire una parte dell'elenco di `Post` oggetti e `nextToken` di ottenere la parte successiva. All'interno`PostIterator`, c'è un elenco di `Post` elementi (`[Post]`) che viene restituito con un token di paginazione (`nextToken`). Nel AWS AppSync, questo verrebbe collegato ad Amazon DynamoDB tramite un resolver e generato automaticamente come token crittografato. Il modello converte il valore dell'argomento `limit` nel parametro `maxResults` e dell'argomento `nextToken` nel parametro `exclusiveStartKey`. Per alcuni esempi e gli esempi di modelli incorporati nella AWS AppSync console, consulta [Resolver](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html) reference (). JavaScript

# Collegamento di un'origine dati in AWS AppSync
<a name="attaching-a-data-source"></a>

Le fonti di dati sono risorse del tuo AWS account con cui GraphQL APIs può interagire. AWS AppSync supporta una moltitudine di fonti di dati come Amazon DynamoDB AWS Lambda, database relazionali (Amazon Aurora Serverless) OpenSearch , Amazon Service ed endpoint HTTP. Un' AWS AppSync API può essere configurata per interagire con più fonti di dati, consentendoti di aggregare i dati in un'unica posizione. AWS AppSync puoi utilizzare AWS le risorse esistenti del tuo account o effettuare il provisioning di tabelle DynamoDB per tuo conto a partire da una definizione di schema.

La sezione seguente ti mostrerà come collegare un'origine dati all'API GraphQL.

## Tipi di fonti di dati
<a name="data-source-types"></a>

Ora che hai creato uno schema nella AWS AppSync console, puoi allegare un'origine dati ad esso. Quando crei inizialmente un'API, è possibile effettuare il provisioning di una tabella Amazon DynamoDB durante la creazione dello schema predefinito. Tuttavia, non tratteremo questa opzione in questa sezione. Puoi vederne un esempio nella sezione [Avvio di uno schema](https://docs.aws.amazon.com//appsync/latest/devguide/schema-launch-start.html).

Invece, esamineremo tutte le fonti di dati AWS AppSync supportate. Ci sono molti fattori che contribuiscono alla scelta della soluzione giusta per la propria applicazione. Le sezioni seguenti forniranno un contesto aggiuntivo per ciascuna fonte di dati. Per informazioni generali sulle fonti di dati, consulta [Fonti di dati](https://docs.aws.amazon.com/appsync/latest/devguide/data-source-components.html).

### Amazon DynamoDB
<a name="data-source-type-ddb"></a>

Amazon DynamoDB è una delle principali soluzioni AWS di storage per applicazioni scalabili. Il componente principale di DynamoDB è **la** tabella, che è semplicemente una raccolta di dati. In genere creerai tabelle basate su entità come `Book` o. `Author` Le informazioni sulle voci della tabella vengono memorizzate come **elementi**, ovvero gruppi di campi univoci per ogni voce. Un elemento completo rappresenta un elemento row/record nel database. Ad esempio, un elemento di una `Book` voce potrebbe includere `title` e `author` insieme ai relativi valori. I singoli campi come `title` e `author` sono chiamati **attributi**, che sono simili ai valori delle colonne nei database relazionali. 

Come puoi immaginare, le tabelle verranno utilizzate per archiviare i dati dell'applicazione. AWS AppSync consente di collegare le tabelle DynamoDB all'API GraphQL per manipolare i dati. Prendete questo [caso d'uso dal blog](https://aws.amazon.com/blogs/mobile/new-real-time-multi-group-app-with-aws-amplify-graphql-build-a-twitter-community-clone/) *Front-end* per web e dispositivi mobili. Questa applicazione consente agli utenti di iscriversi a un'app di social media. Gli utenti possono unirsi a gruppi e caricare post che vengono trasmessi ad altri utenti iscritti al gruppo. La loro applicazione archivia le informazioni su utenti, post e gruppi di utenti in DynamoDB. L'API GraphQL (gestita da AWS AppSync) si interfaccia con la tabella DynamoDB. Quando un utente apporta una modifica al sistema che si rifletterà sul front-end, l'API GraphQL recupera queste modifiche e le trasmette ad altri utenti in tempo reale.

### AWS Lambda
<a name="data-source-type-lam"></a>

Lambda è un servizio basato sugli eventi che crea automaticamente le risorse necessarie per eseguire il codice in risposta a un evento. Lambda utilizza **le funzioni**, che sono istruzioni di gruppo contenenti il codice, le dipendenze e le configurazioni per l'esecuzione di una risorsa. Le funzioni vengono eseguite automaticamente quando rilevano un **trigger**, un gruppo di attività che richiamano la funzione. Un trigger può essere qualcosa come un'applicazione che effettua una chiamata API, un AWS servizio del tuo account che attiva una risorsa, ecc. Quando attivate, le funzioni elaboreranno **gli eventi**, che sono documenti JSON contenenti i dati da modificare.

Lambda è utile per eseguire codice senza dover fornire le risorse per eseguirlo. Prendi questo [caso d'uso](https://aws.amazon.com/blogs/mobile/building-a-graphql-api-with-java-and-aws-lambda/) dal blog *Web e mobile di Front-end*. Questo caso d'uso è un po' simile a quello illustrato nella sezione DynamoDB. In questa applicazione, l'API GraphQL è responsabile della definizione delle operazioni per cose come l'aggiunta di post (mutazioni) e il recupero di tali dati (query). Per implementare la funzionalità delle loro operazioni (ad esempio,`getPostsByAuthor ( author: String ! ) : [ Post ]`)`getPost ( id: String ! ) : Post`, utilizzano le funzioni Lambda per elaborare le richieste in entrata. Nell'*opzione 2: AWS AppSync con il resolver Lambda*, utilizzano il AWS AppSync servizio per mantenere lo schema e collegare un'origine dati Lambda a una delle operazioni. Quando viene chiamata l'operazione, Lambda si interfaccia con il proxy Amazon RDS per eseguire la logica di business sul database.

### Amazon RDS
<a name="data-source-type-RDS"></a>

Amazon RDS consente di creare e configurare rapidamente database relazionali. In Amazon RDS, creerai un'**istanza di database** generica che fungerà da ambiente di database isolato nel cloud. In questo caso, utilizzerai un **motore DB**, che è il software RDBMS effettivo (PostgreSQL, MySQL, ecc.). Il servizio alleggerisce gran parte del lavoro di backend fornendo scalabilità tramite AWS l'infrastruttura, servizi di sicurezza come patch e crittografia e costi amministrativi ridotti per le implementazioni.

Prendiamo lo stesso [caso d'uso](https://aws.amazon.com/blogs/mobile/building-a-graphql-api-with-java-and-aws-lambda/) dalla sezione Lambda. Nell'*opzione 3: AWS AppSync con Amazon RDS resolver*, un'altra opzione presentata è il collegamento diretto dell'API AWS AppSync GraphQL ad Amazon RDS. Utilizzando un'[API di dati](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html), associano il database all'API GraphQL. Un resolver è collegato a un campo (di solito una query, una mutazione o una sottoscrizione) e implementa le istruzioni SQL necessarie per accedere al database. Quando il client effettua una richiesta che richiama il campo, il resolver esegue le istruzioni e restituisce la risposta.

### Amazon EventBridge
<a name="data-source-type-eventbridge"></a>

In EventBridge, creerai **bus di eventi**, ossia pipeline che ricevono eventi dai servizi o dalle applicazioni che colleghi (la **fonte dell'evento**) e li elaborano in base a una serie di regole. Un **evento** è un cambiamento di stato in un ambiente di esecuzione, mentre una **regola** è un insieme di filtri per gli eventi. Una regola segue uno **schema di evento** o i metadati della modifica dello stato di un evento (id, regione, numero di account, ARN, ecc.). Quando un evento corrisponde al modello dell'evento, EventBridge invierà l'evento attraverso la pipeline al servizio di destinazione (**target**) e attiverà l'azione specificata nella regola.

EventBridge è utile per indirizzare le operazioni di modifica dello stato verso altri servizi. Prendi questo [caso d'uso](https://aws.amazon.com/blogs/mobile/appsync-eventbridge/) dal blog *Web e mobile di Front-end*. L'esempio illustra una soluzione di e-commerce che dispone di diversi team che gestiscono servizi diversi. Uno di questi servizi fornisce aggiornamenti sugli ordini al cliente in ogni fase della consegna (ordine effettuato, in corso, spedito, consegnato, ecc.) sul front-end. Tuttavia, il team di front-end che gestisce questo servizio non ha accesso diretto ai dati del sistema di ordinazione, poiché sono gestiti da un team di backend separato. Il sistema di ordinazione del team di backend è anche descritto come una scatola nera, quindi è difficile raccogliere informazioni sul modo in cui strutturano i dati. Tuttavia, il team di backend ha creato un sistema che pubblicava i dati degli ordini tramite un bus di eventi gestito da. EventBridge Per accedere ai dati provenienti dal bus degli eventi e indirizzarli al front-end, il team del front-end ha creato un nuovo target che puntava alla loro API GraphQL installata. AWS AppSync Inoltre, hanno creato una regola per inviare solo i dati relativi all'aggiornamento dell'ordine. Quando viene effettuato un aggiornamento, i dati del bus degli eventi vengono inviati all'API GraphQL. Lo schema nell'API elabora i dati, quindi li passa al front-end.

### Nessuna fonte di dati
<a name="data-source-type-none"></a>

Se non hai intenzione di utilizzare un'origine dati, puoi impostarla su`none`. Una fonte di `none` dati, sebbene sia ancora esplicitamente classificata come fonte di dati, non è un supporto di archiviazione. In genere, un resolver richiamerà una o più fonti di dati a un certo punto per elaborare la richiesta. Tuttavia, ci sono situazioni in cui potrebbe non essere necessario manipolare una fonte di dati. L'impostazione dell'origine dati su `none` eseguirà la richiesta, salterà la fase di invocazione dei dati, quindi eseguirà la risposta.

Prendiamo lo stesso [caso d'uso](https://aws.amazon.com/blogs/mobile/appsync-eventbridge/) della sezione. EventBridge Nello schema, la mutazione elabora l'aggiornamento dello stato, quindi lo invia agli abbonati. Ricordando come funzionano i resolver, di solito c'è almeno una chiamata alla fonte di dati. Tuttavia, i dati in questo scenario sono già stati inviati automaticamente dal bus degli eventi. Ciò significa che non è necessario che la mutazione esegua una chiamata alla fonte di dati; lo stato dell'ordine può essere semplicemente gestito localmente. La mutazione è impostata su`none`, che funge da valore pass-through senza richiamare l'origine dei dati. Lo schema viene quindi popolato con i dati, che vengono inviati agli abbonati.

### OpenSearch
<a name="data-source-type-opensearch"></a>

Amazon OpenSearch Service è una suite di strumenti per implementare la ricerca di testo completo, la visualizzazione dei dati e la registrazione. Puoi utilizzare questo servizio per interrogare i dati strutturati che hai caricato.

In questo servizio, creerai istanze di OpenSearch. Questi sono chiamati **nodi**. In un nodo, aggiungerai almeno un **indice**. Gli indici sono concettualmente un po' come le tabelle nei database relazionali. (Tuttavia, OpenSearch non è conforme ad ACID, quindi non dovrebbe essere usato in questo modo). Compilerai il tuo indice con i dati che caricherai sul servizio. OpenSearch Una volta caricati, i dati verranno indicizzati in uno o più shard presenti nell'indice. Uno **shard** è come una partizione dell'indice che contiene alcuni dati e può essere interrogato separatamente dagli altri shard. **Una volta caricati, i dati saranno strutturati come file JSON chiamati documenti.** È quindi possibile interrogare il nodo per i dati nel documento.

### Endpoint HTTP
<a name="data-source-type-http"></a>

È possibile utilizzare gli endpoint HTTP come fonti di dati. AWS AppSync può inviare richieste agli endpoint con le informazioni pertinenti come parametri e payload. La risposta HTTP verrà esposta al resolver, che restituirà la risposta finale al termine delle sue operazioni.

## Aggiungere una fonte di dati
<a name="adding-a-data-source"></a>

Se hai creato un'origine dati, puoi collegarla al AWS AppSync servizio e, più specificamente, all'API.

------
#### [ Console ]

1. Accedi a Console di gestione AWS e apri la [AppSyncconsole](https://console.aws.amazon.com/appsync/).

   1. Scegli la tua API nella **dashboard**.

   1. Nella **barra laterale**, scegli **Fonti dati**.

1. Seleziona **Create data source (Crea origine dati)**.

   1. Assegna un nome alla tua fonte di dati. Puoi anche dargli una descrizione, ma è facoltativa.

   1. Scegli il **tipo di origine dati**.

   1. Per DynamoDB, dovrai scegliere la tua regione, quindi la tabella nella regione. Puoi dettare le regole di interazione con la tabella scegliendo di creare un nuovo ruolo generico nella tabella o importando un ruolo esistente per la tabella. È possibile abilitare il [controllo delle versioni](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html), che consente di creare automaticamente versioni dei dati per ogni richiesta quando più client tentano di aggiornare i dati contemporaneamente. Il controllo delle versioni viene utilizzato per conservare e gestire più varianti di dati per scopi di rilevamento e risoluzione dei conflitti. Puoi anche abilitare la generazione automatica dello schema, che prende la tua fonte di dati e genera parte del CRUD`List`, e `Query` le operazioni necessarie per accedervi nello schema. 

      Infatti OpenSearch, dovrai scegliere la tua regione, quindi il dominio (cluster) nella regione. Puoi dettare le regole di interazione con il tuo dominio scegliendo di creare un nuovo ruolo di tabella generico o importando un ruolo esistente per la tabella. 

      Per Lambda, dovrai scegliere la tua regione, quindi l'ARN della funzione Lambda nella regione. Puoi dettare le regole di interazione con la tua funzione Lambda scegliendo di creare un nuovo ruolo generico nella tabella o importando un ruolo esistente per la tabella. 

      Per HTTP, dovrai inserire il tuo endpoint HTTP.

      Perché EventBridge, dovrai scegliere la tua regione, quindi l'autobus dell'evento nella regione. Puoi dettare le regole di interazione con il tuo event bus scegliendo di creare un nuovo ruolo generico nella tabella o importando un ruolo esistente per la tabella. 

      Per RDS, dovrai scegliere la tua regione, quindi l'archivio segreto (nome utente e password), il nome del database e lo schema.

      Per nessuno, aggiungerai un'origine dati senza un'origine dati effettiva. Questo serve per gestire i resolver localmente anziché tramite una fonte di dati effettiva.
**Nota**  
Se stai importando ruoli esistenti, hanno bisogno di una politica di fiducia. Per ulteriori informazioni, consulta la [policy di fiducia di IAM](#iam-trust-policy.title).

1. Scegli **Create** (Crea).
**Nota**  
In alternativa, se stai creando un'origine dati DynamoDB, puoi andare **alla** pagina Schema nella console, **scegliere Crea** risorse nella parte superiore della pagina, quindi compilare un modello predefinito da convertire in tabella. In questa opzione, compilerai o importerai il tipo di base, configurerai i dati di base della tabella, inclusa la chiave di partizione, ed esaminerai le modifiche allo schema.

------
#### [ CLI ]
+ Crea la tua fonte di dati eseguendo il [https://docs.aws.amazon.com/cli/latest/reference/appsync/create-data-source.html](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-data-source.html)comando.

  Dovrai inserire alcuni parametri per questo particolare comando:

  1. La `api-id` della tua API.

  1. Il `name` tuo tavolo.

  1. La fonte `type` dei dati. A seconda del tipo di origine dati scelto, potrebbe essere necessario inserire un tag `service-role-arn` e un `-config` tag.

  Un comando di esempio può avere il seguente aspetto:

  ```
   aws appsync create-data-source --api-id abcdefghijklmnopqrstuvwxyz --name data_source_name --type data_source_type --service-role-arn arn:aws:iam::107289374856:role/role_name --[data_source_type]-config {params}
  ```

------
#### [ CDK ]

**Suggerimento**  
Prima di utilizzare il CDK, consigliamo di consultare la [documentazione ufficiale del CDK insieme AWS AppSync al riferimento](https://docs.aws.amazon.com/cdk/v2/guide/home.html) [CDK](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html).  
I passaggi elencati di seguito mostreranno solo un esempio generale dello snippet utilizzato per aggiungere una particolare risorsa. Questa **non** è pensata per essere una soluzione funzionante nel codice di produzione. Supponiamo inoltre che tu abbia già un'app funzionante.

Per aggiungere una particolare fonte di dati, dovrai aggiungere il costrutto al tuo file stack. Un elenco di tipi di fonti di dati è disponibile qui:
+  [ DynamoDbDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.DynamoDbDataSource.html) 
+  [ EventBridgeDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.EventBridgeDataSource.html) 
+  [ HttpDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.HttpDataSource.html) 
+  [ LambdaDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.LambdaDataSource.html) 
+  [ NoneDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.NoneDataSource.html) 
+  [ OpenSearchDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.OpenSearchDataSource.html) 
+  [ RdsDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.RdsDataSource.html) 

1. In generale, potresti dover aggiungere la direttiva di importazione al servizio che stai utilizzando. Ad esempio, può seguire i moduli:

   ```
   import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
   import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
   ```

   Ad esempio, ecco come importare i servizi AWS AppSync e DynamoDB:

   ```
   import * as appsync from 'aws-cdk-lib/aws-appsync';
   import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
   ```

1. Alcuni servizi come RDS richiedono una configurazione aggiuntiva nel file stack prima di creare l'origine dati (ad esempio, creazione di VPC, ruoli e credenziali di accesso). Consulta gli esempi nelle pagine CDK pertinenti per ulteriori informazioni.

1. Per la maggior parte delle fonti di dati, in particolare AWS i servizi, creerai una nuova istanza dell'origine dati nel tuo file stack. In genere, avrà il seguente aspetto:

   ```
   const add_data_source_func = new service_scope.resource_name(scope: Construct, id: string, props: data_source_props);
   ```

   Ad esempio, ecco un esempio di tabella Amazon DynamoDB:

   ```
   const add_ddb_table = new dynamodb.Table(this, 'Table_ID', {
     partitionKey: {
       name: 'id',
       type: dynamodb.AttributeType.STRING,
     },
     sortKey: {
       name: 'id',
       type: dynamodb.AttributeType.STRING,
     },
     tableClass: dynamodb.TableClass.STANDARD,
   });
   ```
**Nota**  
La maggior parte delle fonti di dati avrà almeno una proprietà obbligatoria (sarà indicata **senza** un simbolo). `?` Consultate la documentazione del CDK per vedere quali oggetti di scena sono necessari.

1. Successivamente, è necessario collegare l'origine dati all'API GraphQL. Il metodo consigliato è aggiungerlo quando crei una funzione per il tuo risolutore di pipeline. Ad esempio, lo snippet seguente è una funzione che analizza tutti gli elementi in una tabella DynamoDB:

   ```
   const add_func = new appsync.AppsyncFunction(this, 'func_ID', {
     name: 'func_name_in_console',
     add_api,
     dataSource: add_api.addDynamoDbDataSource('data_source_name_in_console', 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,
   });
   ```

   Nelle `dataSource` proprietà, puoi chiamare l'API GraphQL `add_api` () e utilizzare uno dei suoi metodi integrati `addDynamoDbDataSource` () per creare l'associazione tra la tabella e l'API GraphQL. Gli argomenti sono il nome di questo collegamento che esisterà nella AWS AppSync console (`data_source_name_in_console`in questo esempio) e il metodo della tabella (). `add_ddb_table` Ulteriori informazioni su questo argomento verranno rivelate nella prossima sezione quando inizierai a creare resolver.

   Esistono metodi alternativi per collegare una fonte di dati. Tecnicamente è possibile aggiungerlo `api` all'elenco degli oggetti di scena nella funzione di tabella. Ad esempio, ecco lo snippet del passaggio 3 ma con un oggetto di `api` scena contenente un'API GraphQL:

   ```
   const add_api = new appsync.GraphqlApi(this, 'API_ID', {
     ...
   });
   
   const add_ddb_table = new dynamodb.Table(this, 'Table_ID', {
   
    ...
   
     api: add_api
   });
   ```

   In alternativa, puoi chiamare il costrutto separatamente: `GraphqlApi`

   ```
   const add_api = new appsync.GraphqlApi(this, 'API_ID', {
     ...
   });
   
   const add_ddb_table = new dynamodb.Table(this, 'Table_ID', {
     ...
   });
   
   const link_data_source = add_api.addDynamoDbDataSource('data_source_name_in_console', add_ddb_table);
   ```

   Consigliamo di creare l'associazione solo negli oggetti di scena della funzione. Altrimenti, dovrai collegare manualmente la funzione del resolver alla fonte di dati nella AWS AppSync console (se vuoi continuare a utilizzare il valore della console`data_source_name_in_console`) o creare un'associazione separata nella funzione con un altro nome come. `data_source_name_in_console_2` Ciò è dovuto alle limitazioni nel modo in cui gli oggetti di scena elaborano le informazioni.
**Nota**  
Dovrai ridistribuire l'app per vedere le modifiche.

------

### Politica di fiducia IAM
<a name="iam-trust-policy"></a>

Se utilizzi un ruolo IAM esistente per la tua origine dati, devi concedere a quel ruolo le autorizzazioni appropriate per eseguire operazioni sulla tua AWS risorsa, ad esempio `PutItem` su una tabella Amazon DynamoDB. È inoltre necessario modificare la policy di fiducia su quel ruolo per consentirne AWS AppSync l'utilizzo per l'accesso alle risorse, come illustrato nella seguente policy di esempio:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
        "Effect": "Allow",
        "Principal": {
            "Service": "appsync.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
        }
    ]
}
```

------

Puoi anche aggiungere condizioni alla tua politica di fiducia per limitare l'accesso all'origine dati, se lo desideri. Attualmente, `SourceArn` le `SourceAccount` chiavi possono essere utilizzate in queste condizioni. Ad esempio, la seguente politica limita l'accesso all'origine dati all'account`123456789012`:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "appsync.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "123456789012"
        }
      }
    }
  ]
}
```

------

In alternativa, puoi limitare l'accesso a un'origine dati a un'API specifica`abcdefghijklmnopq`, ad esempio utilizzando la seguente politica:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "appsync.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:appsync:us-west-2:123456789012:apis/abcdefghijklmnopq"
        }
      }
    }
  ]
}
```

------

Puoi limitare l'accesso a tutti AWS AppSync APIs da una regione specifica`us-east-1`, ad esempio utilizzando la seguente politica:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "appsync.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:appsync:us-east-1:123456789012:apis/*"
        }
      }
    }
  ]
}
```

------

Nella prossima sezione ([Configurazione dei resolver](https://docs.aws.amazon.com//appsync/latest/devguide/resolver-config-overview.html)), aggiungeremo la nostra logica aziendale del resolver e la collegheremo ai campi del nostro schema per elaborare i dati nella nostra fonte di dati.

*Per ulteriori informazioni sulla configurazione delle politiche relative ai ruoli, consulta [Modificare un](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_manage_modify.html) ruolo nella Guida per l'utente IAM.*

[Per ulteriori informazioni sull'accesso tra account ai resolver per AWS AppSync, consulta AWS Lambda Creazione di resolver tra account per. AWS LambdaAWS AppSync](https://aws.amazon.com/blogs/mobile/appsync-lambda-cross-account/)

# Configurazione dei resolver in AWS AppSync
<a name="resolver-config-overview"></a>

Nelle sezioni precedenti, hai imparato a creare lo schema e l'origine dati GraphQL, quindi a collegarli insieme nel AWS AppSync servizio. Nel vostro schema, potreste aver stabilito uno o più campi (operazioni) nella query e nella mutazione. Sebbene lo schema descrivesse i tipi di dati che le operazioni avrebbero richiesto alla fonte dei dati, non ha mai implementato il modo in cui tali operazioni si sarebbero comportate rispetto ai dati. 

Il comportamento di un'operazione è sempre implementato nel resolver, che sarà collegato al campo che esegue l'operazione. [Per ulteriori informazioni sul funzionamento dei resolver in generale, consulta la pagina Resolver.](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html)

In AWS AppSync, il resolver è legato a un runtime, che è l'ambiente in cui viene eseguito. I runtime determinano la lingua in cui verrà scritto il resolver. Attualmente sono supportati due runtime: APPSYNC\$1JS (JavaScript) e Apache Velocity Template Language (VTL). 

Quando si implementano i resolver, esiste una struttura generale che seguono:
+ **Prima della fase**: quando viene effettuata una richiesta dal client, ai resolver per i campi dello schema utilizzati (in genere le query, le mutazioni, le sottoscrizioni) vengono trasmessi i dati della richiesta. Il resolver inizierà a elaborare i dati della richiesta con un gestore del passaggio precedente, che consente di eseguire alcune operazioni di preelaborazione prima che i dati vengano trasferiti nel resolver.
+ **Funzione/i**: dopo l'esecuzione del passaggio precedente, la richiesta viene passata all'elenco delle funzioni. La prima funzione dell'elenco verrà eseguita sulla fonte di dati. Una funzione è un sottoinsieme del codice del resolver contenente il proprio gestore di richieste e risposte. Un gestore di richieste prenderà i dati della richiesta ed eseguirà operazioni sulla fonte dei dati. Il gestore della risposta elaborerà la risposta dell'origine dati prima di restituirla all'elenco. Se è presente più di una funzione, i dati della richiesta verranno inviati alla funzione successiva nell'elenco da eseguire. Le funzioni nell'elenco verranno eseguite in serie nell'ordine definito dallo sviluppatore. Una volta eseguite tutte le funzioni, il risultato finale viene passato alla fase successiva.
+ **Dopo la fase**: la fase successiva è una funzione di gestione che consente di eseguire alcune operazioni finali sulla risposta finale della funzione prima di passarla alla risposta GraphQL.

Questo flusso è un esempio di risolutore di pipeline. I resolver di pipeline sono supportati in entrambi i runtime. Tuttavia, questa è una spiegazione semplificata di cosa possono fare i resolver di pipeline. Inoltre, stiamo descrivendo solo una possibile configurazione del resolver. [Per ulteriori informazioni sulle configurazioni dei resolver supportate, consulta la panoramica dei resolver per [JavaScript APPSYNC\$1JS o la panoramica dei modelli di mappatura Resolver](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html) per VTL.](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-overview.html)

Come puoi vedere, i resolver sono modulari. Affinché i componenti del resolver funzionino correttamente, devono essere in grado di esaminare lo stato di esecuzione da altri componenti. Dalla sezione [Resolver](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html), sapete che a ogni componente del resolver possono essere trasmesse informazioni vitali sullo stato dell'esecuzione sotto forma di un insieme di argomenti (,, ecc.). `args` `context` Nel AWS AppSync, questo è gestito rigorosamente da. `context` È un contenitore per le informazioni sul campo da risolvere. Ciò può includere qualsiasi cosa, dagli argomenti passati, ai risultati, ai dati di autorizzazione, ai dati di intestazione, ecc. Per ulteriori informazioni sul contesto, vedere il riferimento al contesto [Resolver Context Object per APPSYNC\$1JS o il riferimento](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) contestuale del modello di mappatura [Resolver](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html) per VTL.

Il contesto non è l'unico strumento che puoi usare per implementare il tuo resolver. AWS AppSync supporta un'ampia gamma di utilità per la generazione di valore, la gestione degli errori, l'analisi, la conversione, ecc. [Puoi vedere un elenco di utilità [qui per APPSYNC\$1JS o qui](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) per VTL.](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html)

Nelle sezioni seguenti, imparerai come configurare i resolver nella tua API GraphQL.

**Topics**
+ [Creazione di interrogazioni di base () JavaScript](configuring-resolvers-js.md)
+ [Creazione di interrogazioni di base (VTL)](configuring-resolvers.md)

# Creazione di interrogazioni di base () JavaScript
<a name="configuring-resolvers-js"></a>

I resolver GraphQL connettono i campi nello schema di un tipo a un'origine dati. I resolver sono il meccanismo mediante il quale vengono soddisfatte le richieste.

Resolver AWS AppSync utilizzati JavaScript per convertire un'espressione GraphQL in un formato utilizzabile dall'origine dati. In alternativa, i modelli di mappatura possono essere scritti in [Apache Velocity Template Language (VTL) per](https://velocity.apache.org/engine/2.0/vtl-reference.html) convertire un'espressione GraphQL in un formato utilizzabile dall'origine dati.

Questa sezione descrive come configurare i resolver utilizzando. JavaScript La sezione [Resolver tutorials (JavaScript) fornisce tutorial](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html) approfonditi su come implementare i resolver utilizzando. JavaScript La sezione [Resolver reference (JavaScript) fornisce una spiegazione delle operazioni di utilità che possono essere utilizzate con i resolver](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html). JavaScript 

Consigliamo di seguire questa guida prima di tentare di utilizzare uno qualsiasi dei tutorial sopra citati.

In questa sezione, spiegheremo come creare e configurare resolver per query e mutazioni.

**Nota**  
Questa guida presuppone che tu abbia creato il tuo schema e che tu abbia almeno una query o una mutazione. [Se stai cercando abbonamenti (dati in tempo reale), consulta questa guida.](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html)

In questa sezione, forniremo alcuni passaggi generali per la configurazione dei resolver insieme a un esempio che utilizza lo schema seguente:

```
// schema.graphql file

input CreatePostInput {
  title: String
  date: AWSDateTime
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
}

type Mutation {
  createPost(input: CreatePostInput!): Post
}

type Query {
  getPost: [Post]
}
```

## Creazione di risolutori di query di base
<a name="create-basic-query-resolver-js"></a>

Questa sezione ti mostrerà come creare un risolutore di query di base.

------
#### [ Console ]

1. [Accedi a Console di gestione AWS e apri la AppSync console.](https://console.aws.amazon.com/appsync/)

   1. Nella **APIs dashboard**, scegli la tua API GraphQL.

   1. **Nella **barra laterale**, scegli Schema.**

1. Inserisci i dettagli dello schema e della fonte di dati. Per ulteriori informazioni, consulta [le sezioni Progettazione dello schema](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html) e [Collegamento di un'origine dati](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html).

1. Accanto all'editor dello **schema**, c'è una finestra chiamata **Resolvers**. **Questa casella contiene un elenco dei tipi e dei campi definiti nella finestra Schema.** È possibile allegare resolver ai campi. Molto probabilmente allegherai dei resolver alle tue operazioni sul campo. In questa sezione, esamineremo semplici configurazioni di query. Nella sezione Tipo di **query**, scegli **Allega** accanto al campo della query.

1. Nella pagina **Attach resolver**, in **Tipo di resolver**, puoi scegliere tra resolver pipeline o unit. [Per ulteriori informazioni su questi tipi, consulta Resolvers.](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html) Questa guida utilizzerà. `pipeline resolvers`
**Suggerimento**  
Durante la creazione di risolutori di pipeline, le sorgenti dati verranno allegate alle funzioni della pipeline. Le funzioni vengono create dopo aver creato il risolutore della pipeline stesso, motivo per cui non è possibile impostarlo in questa pagina. Se utilizzi un risolutore di unità, la fonte di dati è collegata direttamente al resolver, quindi devi impostarla in questa pagina.

   Per **Resolver runtime, scegli di abilitare il runtime**. `APPSYNC_JS` JavaScript 

1. Puoi abilitare la [memorizzazione nella cache per questa API](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html). Ti consigliamo di disattivare questa funzionalità per ora. Scegli **Create** (Crea).

1. Nella pagina **Modifica resolver**, c'è un editor di codice chiamato **Resolver code** che consente di implementare la logica per il gestore e la risposta del resolver (prima e dopo i passaggi). [Per ulteriori informazioni, consulta la panoramica dei resolver. JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html) 
**Nota**  
[Nel nostro esempio, lasceremo la richiesta vuota e la risposta impostata per restituire l'ultima fonte di dati risultante dal contesto:](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)  

   ```
   import {util} from '@aws-appsync/utils';
   
   export function request(ctx) {
       return {};
   }
   
   export function response(ctx) {
       return ctx.prev.result;
   }
   ```

   Sotto questa sezione, c'è una tabella chiamata **Funzioni**. Le funzioni consentono di implementare codice che può essere riutilizzato su più resolver. Invece di riscrivere o copiare costantemente il codice, puoi memorizzare il codice sorgente come funzione da aggiungere a un resolver ogni volta che ne hai bisogno. 

   Le funzioni costituiscono la maggior parte dell'elenco delle operazioni di una pipeline. Quando si utilizzano più funzioni in un resolver, si imposta l'ordine delle funzioni e queste verranno eseguite in quell'ordine in sequenza. Vengono eseguiti dopo l'esecuzione della funzione di richiesta e prima dell'inizio della funzione di risposta.

   Per aggiungere una nuova funzione, in **Funzioni**, scegli **Aggiungi funzione**, quindi **Crea nuova funzione**. In alternativa, potresti invece visualizzare il pulsante **Crea funzione** tra cui scegliere.

   1. Scegli una fonte di dati. Questa sarà la fonte di dati su cui agisce il resolver.
**Nota**  
Nel nostro esempio, stiamo collegando un resolver per`getPost`, che recupera un oggetto tramite. `Post` `id` Supponiamo di aver già impostato una tabella DynamoDB per questo schema. La sua chiave di partizione è impostata su `id` ed è vuota.

   1. Inserisci un`Function name`.

   1. In **Codice funzione**, dovrai implementare il comportamento della funzione. Ciò potrebbe creare confusione, ma ogni funzione avrà il proprio gestore locale di richieste e risposte. La richiesta viene eseguita, quindi viene effettuata la chiamata all'origine dati per gestire la richiesta, quindi la risposta dell'origine dati viene elaborata dal gestore della risposta. [Il risultato viene archiviato nell'oggetto contestuale.](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) Successivamente, verrà eseguita la funzione successiva nell'elenco o verrà passata al gestore di risposte post-passaggio se è l'ultima. 
**Nota**  
Nel nostro esempio, stiamo collegando un resolver a`getPost`, che ottiene un elenco di `Post` oggetti dalla fonte di dati. La nostra funzione di richiesta richiederà i dati dalla nostra tabella, la tabella passerà la sua risposta al contesto (ctx), quindi la risposta restituirà il risultato nel contesto. AWS AppSync la forza di questa soluzione risiede nella sua interconnessione con altri servizi. AWS Poiché utilizziamo DynamoDB, disponiamo di [una suite di](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html) operazioni per semplificare cose come queste. Abbiamo anche alcuni esempi standard per altri tipi di fonti di dati.  
Il nostro codice sarà simile a questo:  

      ```
      import { util } from '@aws-appsync/utils';
      
      /**
       * Performs a scan on the dynamodb data source
       */
      export function request(ctx) {
        return { operation: 'Scan' };
      }
      
      /**
       * return a list of scanned post items
       */
      export function response(ctx) {
        return ctx.result.items;
      }
      ```
In questo passaggio, abbiamo aggiunto due funzioni:  
`request`: Il gestore della richiesta esegue l'operazione di recupero sulla fonte di dati. L'argomento contiene l'oggetto context (`ctx`) o alcuni dati disponibili per tutti i resolver che eseguono una particolare operazione. Ad esempio, potrebbe contenere dati di autorizzazione, i nomi dei campi da risolvere, ecc. L'istruzione return esegue un'[https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan](https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan)operazione (vedi [qui](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html) per alcuni esempi). Poiché lavoriamo con DynamoDB, siamo autorizzati a utilizzare alcune delle operazioni di quel servizio. La scansione esegue un recupero di base di tutti gli elementi della nostra tabella. Il risultato di questa operazione viene archiviato nell'oggetto di contesto come `result` contenitore prima di essere passato al gestore delle risposte. `request`Viene eseguito prima della risposta nella pipeline.
`response`: Il gestore di risposte che restituisce l'output di. `request` L'argomento è l'oggetto di contesto aggiornato e l'istruzione return è`ctx.prev.result`. A questo punto della guida, potresti non avere familiarità con questo valore. `ctx`si riferisce all'oggetto contestuale. `prev`si riferisce all'operazione precedente nella pipeline, che era la nostra`request`. `result`Contiene i risultati del resolver mentre si muove attraverso la pipeline. Se metti tutto insieme, `ctx.prev.result` restituisce il risultato dell'ultima operazione eseguita, che era il gestore della richiesta.

   1. Scegli **Crea** dopo aver finito.

1. Tornando alla schermata del resolver, in **Funzioni**, scegli il menu a discesa **Aggiungi funzione** e aggiungi la tua funzione all'elenco delle funzioni.

1. Scegli **Salva** per aggiornare il resolver.

------
#### [ CLI ]

**Per aggiungere la tua funzione**
+ Crea una funzione per il tuo risolutore di pipeline usando il comando. `[create-function](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-function.html)`

  Dovrai inserire alcuni parametri per questo particolare comando:

  1. La `api-id` della tua API.

  1. `name`La funzione nella AWS AppSync console.

  1. Il`data-source-name`, o il nome dell'origine dati che verrà utilizzata dalla funzione. Deve essere già stato creato e collegato all'API GraphQL nel AWS AppSync servizio.

  1. L'`runtime`ambiente o e il linguaggio della funzione. Perché JavaScript, il nome deve essere`APPSYNC_JS`, e il runtime,`1.0.0`.

  1. I `code` gestori di richieste e risposte della funzione. Sebbene sia possibile digitarlo manualmente, è molto più semplice aggiungerlo a un file.txt (o un formato simile) e quindi passarlo come argomento. 
**Nota**  
Il nostro codice di query sarà contenuto in un file passato come argomento:  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Performs a scan on the dynamodb data source
      */
     export function request(ctx) {
       return { operation: 'Scan' };
     }
     
     /**
      * return a list of scanned post items
      */
     export function response(ctx) {
       return ctx.result.items;
     }
     ```

  Un comando di esempio può essere simile al seguente:

  ```
  aws appsync create-function \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --name get_posts_func_1 \
  --data-source-name table-for-posts \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file://~/path/to/file/{filename}.{fileType}
  ```

  Verrà restituito un output nella CLI. Ecco un esempio:

  ```
  {
      "functionConfiguration": {
          "functionId": "ejglgvmcabdn7lx75ref4qeig4",
          "functionArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/functions/ejglgvmcabdn7lx75ref4qeig4",
          "name": "get_posts_func_1",
          "dataSourceName": "table-for-posts",
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```
**Nota**  
Assicurati di registrarlo `functionId` da qualche parte poiché verrà utilizzato per collegare la funzione al resolver.

**Per creare il tuo resolver**
+ Crea una funzione di pipeline `Query` eseguendo il comando. `[create-resolver](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)`

  Dovrai inserire alcuni parametri per questo particolare comando:

  1. La `api-id` della tua API.

  1. Il`type-name`, o il tipo di oggetto speciale nel tuo schema (Query, Mutation, Subscription).

  1. Il`field-name`, o l'operazione di campo all'interno del tipo di oggetto speciale a cui si desidera collegare il resolver.

  1. Il`kind`, che specifica un'unità o un resolver di pipeline. Impostalo per abilitare le funzioni della `PIPELINE` pipeline.

  1. La`pipeline-config`, o la o le funzioni da collegare al resolver. Assicurati di conoscere `functionId` i valori delle tue funzioni. L'ordine delle inserzioni è importante.

  1. Il`runtime`, che era `APPSYNC_JS` (JavaScript). `runtimeVersion`Attualmente è`1.0.0`.

  1. Il`code`, che contiene i gestori della fase prima e dopo.
**Nota**  
Il nostro codice di query sarà in un file passato come argomento:  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       const { id, ...values } = ctx.args;
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({ id }),
         attributeValues: util.dynamodb.toMapValues(values),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  Un comando di esempio può essere simile al seguente:

  ```
  aws appsync create-resolver \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --type-name Query \
  --field-name getPost \
  --kind PIPELINE \
  --pipeline-config functions=ejglgvmcabdn7lx75ref4qeig4 \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  Verrà restituito un output nella CLI. Ecco un esempio:

  ```
  {
      "resolver": {
          "typeName": "Mutation",
          "fieldName": "getPost",
          "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation/resolvers/getPost",
          "kind": "PIPELINE",
          "pipelineConfig": {
              "functions": [
                  "ejglgvmcabdn7lx75ref4qeig4"
              ]
          },
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```

------
#### [ CDK ]

**Suggerimento**  
[Prima di utilizzare il CDK, consigliamo di consultare la [documentazione ufficiale del CDK insieme AWS AppSync al riferimento](https://docs.aws.amazon.com/cdk/v2/guide/home.html) CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
I passaggi elencati di seguito mostreranno solo un esempio generale dello snippet utilizzato per aggiungere una particolare risorsa. Questa **non** è pensata per essere una soluzione funzionante nel codice di produzione. Supponiamo inoltre che tu abbia già un'app funzionante.

Un'app di base avrà bisogno delle seguenti cose:

1. Direttive di importazione dei servizi

1. Codice dello schema

1. Generatore di fonti di dati

1. Codice di funzione

1. Codice del resolver

Dalle sezioni [Progettazione dello schema](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html) e [Allegare una fonte di dati](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html), sappiamo che il file stack includerà le direttive di importazione del modulo:

```
import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
```

**Nota**  
Nelle sezioni precedenti, abbiamo solo indicato come importare i costrutti. AWS AppSync In codice reale, dovrai importare più servizi solo per eseguire l'app. Nel nostro esempio, se dovessimo creare un'app CDK molto semplice, importeremmo almeno il AWS AppSync servizio insieme alla nostra fonte di dati, che era una tabella DynamoDB. Dovremmo anche importare alcuni costrutti aggiuntivi per distribuire l'app:  

```
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';
```
Per riassumere ognuno di questi:  
`import * as cdk from 'aws-cdk-lib';`: Ciò consente di definire l'app CDK e i costrutti come lo stack. Contiene anche alcune utili funzioni di utilità per la nostra applicazione, come la manipolazione dei metadati. [Se conosci questa direttiva di importazione, ma ti stai chiedendo perché la libreria di base cdk non viene utilizzata qui, consulta la pagina Migrazione.](https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html)
`import * as appsync from 'aws-cdk-lib/aws-appsync';`: Questo importa il [AWS AppSync servizio](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html).
`import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';`: Importa il servizio [DynamoDB](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_dynamodb-readme.html).
`import { Construct } from 'constructs';`[: Ne abbiamo bisogno per definire il costrutto root.](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html)

Il tipo di importazione dipende dai servizi che stai chiamando. Ti consigliamo di consultare la documentazione CDK per alcuni esempi. Lo schema nella parte superiore della pagina sarà un file separato nell'app CDK come `.graphql` file. Nel file stack, possiamo associarlo a un nuovo GraphQL utilizzando il modulo:

```
const add_api = new appsync.GraphqlApi(this, 'graphQL-example', {
  name: 'my-first-api',
  schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema.graphql')),
});
```

**Nota**  
Nell'ambito`add_api`, stiamo aggiungendo una nuova API GraphQL utilizzando la `new` parola chiave seguita da. `appsync.GraphqlApi(scope: Construct, id: string , props: GraphqlApiProps)` Il nostro ambito è`this`, l'id CFN è `graphQL-example` e i nostri oggetti di scena sono `my-first-api` (nome dell'API nella console) e `schema.graphql` (il percorso assoluto del file di schema).

Per aggiungere una fonte di dati, devi prima aggiungere la tua fonte di dati allo stack. Quindi, è necessario associarlo all'API GraphQL utilizzando il metodo specifico del codice sorgente. L'associazione avverrà quando farai funzionare il resolver. Nel frattempo, facciamo un esempio creando la tabella DynamoDB usando: `dynamodb.Table`

```
const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
  partitionKey: {
    name: 'id',
    type: dynamodb.AttributeType.STRING,
  },
});
```

**Nota**  
Se dovessimo utilizzarlo nel nostro esempio, aggiungeremmo una nuova tabella DynamoDB con l'id CFN `posts-table` di e una chiave di partizione di. `id (S)`

Successivamente, dobbiamo implementare il nostro resolver nel file stack. Ecco un esempio di una semplice query che analizza tutti gli elementi in una tabella DynamoDB:

```
const add_func = new appsync.AppsyncFunction(this, 'func-get-posts', {
  name: 'get_posts_func_1',
  add_api,
  dataSource: add_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,
});

new appsync.Resolver(this, 'pipeline-resolver-get-posts', {
  add_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],
});
```

**Nota**  
Innanzitutto, abbiamo creato una funzione chiamata. `add_func` Questo ordine di creazione può sembrare un po' controintuitivo, ma è necessario creare le funzioni nel resolver della pipeline prima di creare il resolver stesso. Una funzione segue la forma:  

```
AppsyncFunction(scope: Construct, id: string, props: AppsyncFunctionProps)
```
Il nostro ambito era`this`, il nostro ID CFN lo era `func-get-posts` e i nostri oggetti di scena contenevano i dettagli effettivi della funzione. All'interno degli oggetti di scena, abbiamo incluso:  
La `name` funzione che sarà presente nella AWS AppSync console (`get_posts_func_1`).
L'API GraphQL che abbiamo creato in precedenza ()`add_api`.
L'origine dei dati; questo è il punto in cui colleghiamo l'origine dati al valore dell'API GraphQL, quindi la colleghiamo alla funzione. Prendiamo la tabella che abbiamo creato (`add_ddb_table`) e la colleghiamo all'API GraphQL (`add_api`) utilizzando uno dei `GraphqlApi` metodi ([https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.GraphqlApi.html#addwbrdynamowbrdbwbrdatawbrsourceid-table-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.GraphqlApi.html#addwbrdynamowbrdbwbrdatawbrsourceid-table-options)). Il valore id (`table-for-posts`) è il nome dell'origine dati nella AWS AppSync console. Per un elenco di metodi specifici dell'origine, consulta le pagine seguenti:  
[ DynamoDbDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.DynamoDbDataSource.html) 
 [ EventBridgeDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.EventBridgeDataSource.html) 
 [ HttpDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.HttpDataSource.html) 
 [ LambdaDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.LambdaDataSource.html) 
 [ NoneDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.NoneDataSource.html) 
 [ OpenSearchDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.OpenSearchDataSource.html) 
 [ RdsDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.RdsDataSource.html) 
Il codice contiene i gestori di richiesta e risposta della nostra funzione, che consistono in una semplice scansione e restituzione.
Il runtime specifica che vogliamo usare la versione di runtime APPSYNC\$1JS 1.0.0. Nota che questa è attualmente l'unica versione disponibile per APPSYNC\$1JS.
Successivamente, dobbiamo collegare la funzione al risolutore della pipeline. Abbiamo creato il nostro resolver utilizzando il modulo:  

```
Resolver(scope: Construct, id: string, props: ResolverProps)
```
Il nostro ambito era`this`, il nostro ID CFN lo era `pipeline-resolver-get-posts` e i nostri oggetti di scena contenevano i dettagli effettivi della funzione. All'interno degli oggetti di scena, abbiamo incluso:  
L'API GraphQL che abbiamo creato in precedenza ()`add_api`.
Il nome speciale del tipo di oggetto; si tratta di un'operazione di interrogazione, quindi abbiamo semplicemente aggiunto il valore`Query`.
Il nome del campo (`getPost`) è il nome del campo nello schema sotto il `Query` tipo.
Il codice contiene i gestori prima e dopo. Il nostro esempio restituisce semplicemente i risultati presenti nel contesto dopo che la funzione ha eseguito la sua operazione.
Il runtime specifica che vogliamo usare la versione di runtime APPSYNC\$1JS 1.0.0. Nota che questa è attualmente l'unica versione disponibile per APPSYNC\$1JS.
La configurazione della pipeline contiene il riferimento alla funzione che abbiamo creato (). `add_func`

------

Per riassumere ciò che è successo in questo esempio, hai visto una AWS AppSync funzione che implementava un gestore di richieste e risposte. La funzione era responsabile dell'interazione con la fonte dei dati. Il gestore della richiesta ha inviato un'`Scan`operazione a AWS AppSync, indicandogli quale operazione eseguire sull'origine dati DynamoDB. Il gestore della risposta ha restituito l'elenco degli elementi (). `ctx.result.items` L'elenco degli elementi è stato quindi mappato automaticamente al tipo `Post` GraphQL. 

## Creazione di risolutori di mutazioni di base
<a name="creating-basic-mutation-resolvers-js"></a>

Questa sezione ti mostrerà come creare un risolutore di mutazioni di base.

------
#### [ Console ]

1. [Accedi a Console di gestione AWS e apri la console. AppSync](https://console.aws.amazon.com/appsync/)

   1. Nella **APIs dashboard**, scegli la tua API GraphQL.

   1. **Nella **barra laterale**, scegli Schema.**

1. Nella sezione **Resolver** e nel tipo di **mutazione**, scegli **Allega** accanto al tuo campo.
**Nota**  
Nel nostro esempio, stiamo collegando un resolver per`createPost`, che aggiunge un oggetto alla nostra tabella. `Post` Supponiamo di utilizzare la stessa tabella DynamoDB dell'ultima sezione. La sua chiave di partizione è impostata su `id` ed è vuota.

1. Nella pagina **Allega resolver**, in Tipo di **risolutore, scegli**. `pipeline resolvers` [Come promemoria, puoi trovare ulteriori informazioni sui resolver qui.](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html) Per **Resolver runtime, scegli di abilitare il runtime**. `APPSYNC_JS` JavaScript 

1. Puoi abilitare la [memorizzazione nella cache per questa API](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html). Ti consigliamo di disattivare questa funzionalità per ora. Scegli **Create** (Crea).

1. Scegli **Aggiungi funzione**, quindi scegli **Crea nuova funzione**. In alternativa, potresti invece visualizzare un pulsante **Crea funzione** tra cui scegliere.

   1. Scegli l'origine dati. Questa dovrebbe essere la fonte di cui manipolerai i dati con la mutazione.

   1. Inserisci un. `Function name`

   1. In **Codice funzione**, dovrai implementare il comportamento della funzione. Questa è una mutazione, quindi la richiesta eseguirà idealmente alcune operazioni di modifica dello stato sulla fonte di dati richiamata. Il risultato verrà elaborato dalla funzione di risposta.
**Nota**  
`createPost`sta aggiungendo, o «inserendo», un nuovo `Post` nella tabella con i nostri parametri come dati. Potremmo aggiungere qualcosa del genere:   

      ```
      import { util } from '@aws-appsync/utils';
      
      /**
       * Sends a request to `put` an item in the DynamoDB data source
       */
      export function request(ctx) {
        return {
          operation: 'PutItem',
          key: util.dynamodb.toMapValues({id: util.autoId()}),
          attributeValues: util.dynamodb.toMapValues(ctx.args.input),
        };
      }
      
      /**
       * returns the result of the `put` operation
       */
      export function response(ctx) {
        return ctx.result;
      }
      ```
In questo passaggio, abbiamo anche aggiunto `request` `response` funzioni:  
`request`: Il gestore della richiesta accetta il contesto come argomento. L'istruzione return del gestore di richieste esegue un [https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem](https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem)comando, che è un'operazione DynamoDB integrata ([vedi](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-2.html) qui [o](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.WritingData) qui per alcuni esempi). Il `PutItem` comando aggiunge un `Post` oggetto alla nostra tabella DynamoDB prendendo il valore della `key` partizione (generato automaticamente `util.autoid()` da) `attributes` e dall'input dell'argomento di contesto (questi sono i valori che passeremo nella nostra richiesta). Gli argomenti `key` è `id` e `attributes` sono gli `date` e `title` i campi. Sono entrambi preformattati tramite l'[https://docs.aws.amazon.com//appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html#utility-helpers-in-toMap-js](https://docs.aws.amazon.com//appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html#utility-helpers-in-toMap-js)helper per funzionare con la tabella DynamoDB.
`response`: La risposta accetta il contesto aggiornato e restituisce il risultato del gestore della richiesta.

   1. Scegli **Crea** dopo aver finito.

1. Tornando alla schermata del resolver, in **Funzioni**, scegli il menu a discesa **Aggiungi funzione** e aggiungi la tua funzione all'elenco delle funzioni.

1. Scegli **Salva** per aggiornare il resolver.

------
#### [ CLI ]

**Per aggiungere la tua funzione**
+ Crea una funzione per il tuo risolutore di pipeline usando il comando. `[create-function](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-function.html)`

  Dovrai inserire alcuni parametri per questo particolare comando:

  1. La `api-id` della tua API.

  1. `name`La funzione nella AWS AppSync console.

  1. Il`data-source-name`, o il nome dell'origine dati che verrà utilizzata dalla funzione. Deve essere già stato creato e collegato all'API GraphQL nel AWS AppSync servizio.

  1. L'`runtime`ambiente o e il linguaggio della funzione. Perché JavaScript, il nome deve essere`APPSYNC_JS`, e il runtime,`1.0.0`.

  1. I `code` gestori di richieste e risposte della funzione. Sebbene sia possibile digitarlo manualmente, è molto più semplice aggiungerlo a un file.txt (o un formato simile) e passarlo come argomento. 
**Nota**  
Il nostro codice di query sarà contenuto in un file passato come argomento:  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({id: util.autoId()}),
         attributeValues: util.dynamodb.toMapValues(ctx.args.input),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  Un comando di esempio può essere simile al seguente:

  ```
  aws appsync create-function \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --name add_posts_func_1 \
  --data-source-name table-for-posts \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  Verrà restituito un output nella CLI. Ecco un esempio:

  ```
  {
      "functionConfiguration": {
          "functionId": "vulcmbfcxffiram63psb4dduoa",
          "functionArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/functions/vulcmbfcxffiram63psb4dduoa",
          "name": "add_posts_func_1",
          "dataSourceName": "table-for-posts",
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output foes here"
      }
  }
  ```
**Nota**  
Assicurati di registrarlo `functionId` da qualche parte poiché verrà utilizzato per collegare la funzione al resolver.

**Per creare il tuo resolver**
+ Crea una funzione di pipeline `Mutation` eseguendo il comando. `[create-resolver](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)`

  Dovrai inserire alcuni parametri per questo particolare comando:

  1. La `api-id` della tua API.

  1. Il`type-name`, o il tipo di oggetto speciale nel tuo schema (Query, Mutation, Subscription).

  1. Il`field-name`, o l'operazione di campo all'interno del tipo di oggetto speciale a cui si desidera collegare il resolver.

  1. Il`kind`, che specifica un'unità o un resolver di pipeline. Impostalo per abilitare le funzioni della `PIPELINE` pipeline.

  1. La`pipeline-config`, o la o le funzioni da collegare al resolver. Assicurati di conoscere `functionId` i valori delle tue funzioni. L'ordine delle inserzioni è importante.

  1. Il`runtime`, che era `APPSYNC_JS` (JavaScript). `runtimeVersion`Attualmente è`1.0.0`.

  1. Il`code`, che contiene il passaggio prima e dopo.
**Nota**  
Il nostro codice di query sarà in un file passato come argomento:  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       const { id, ...values } = ctx.args;
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({ id }),
         attributeValues: util.dynamodb.toMapValues(values),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  Un comando di esempio può essere simile al seguente:

  ```
  aws appsync create-resolver \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --type-name Mutation \
  --field-name createPost \
  --kind PIPELINE \
  --pipeline-config functions=vulcmbfcxffiram63psb4dduoa \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  Verrà restituito un output nella CLI. Ecco un esempio:

  ```
  {
      "resolver": {
          "typeName": "Mutation",
          "fieldName": "createPost",
          "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation/resolvers/createPost",
          "kind": "PIPELINE",
          "pipelineConfig": {
              "functions": [
                  "vulcmbfcxffiram63psb4dduoa"
              ]
          },
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```

------
#### [ CDK ]

**Suggerimento**  
[Prima di utilizzare il CDK, consigliamo di consultare la [documentazione ufficiale del CDK insieme AWS AppSync al riferimento](https://docs.aws.amazon.com/cdk/v2/guide/home.html) CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
I passaggi elencati di seguito mostreranno solo un esempio generale dello snippet utilizzato per aggiungere una particolare risorsa. Questa **non** è pensata per essere una soluzione funzionante nel codice di produzione. Supponiamo inoltre che tu abbia già un'app funzionante.
+ Per effettuare una mutazione, supponendo che siate nello stesso progetto, potete aggiungerla allo stack file come nella query. Ecco una funzione e un resolver modificati per una mutazione che ne aggiunge una nuova alla tabella: `Post`

  ```
  const add_func_2 = new appsync.AppsyncFunction(this, 'func-add-post', {
    name: 'add_posts_func_1',
    add_api,
    dataSource: add_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,
  });
  
  new appsync.Resolver(this, 'pipeline-resolver-create-posts', {
    add_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],
  });
  ```
**Nota**  
Poiché questa mutazione e la query sono strutturate in modo simile, ci limiteremo a spiegare le modifiche che abbiamo apportato per apportare la mutazione.   
Nella funzione, abbiamo cambiato l'id CFN in `func-add-post` e il nome in `add_posts_func_1` per riflettere il fatto che stiamo aggiungendo `Posts` alla tabella. Nell'origine dati, abbiamo creato una nuova associazione alla nostra table (`add_ddb_table`) nella AWS AppSync console `table-for-posts-2` perché il `addDynamoDbDataSource` metodo lo richiede. Tieni presente che questa nuova associazione utilizza ancora la stessa tabella che abbiamo creato in precedenza, ma ora abbiamo due connessioni ad essa nella AWS AppSync console: una per la query as `table-for-posts` e una per la mutazione as`table-for-posts-2`. Il codice è stato modificato per aggiungere un valore `Post` generando automaticamente il suo `id` valore e accettando l'input di un client per il resto dei campi.  
Nel resolver, abbiamo modificato il valore id in modo `pipeline-resolver-create-posts` che rifletta il fatto che stiamo aggiungendo `Posts` alla tabella. Per riflettere la mutazione nello schema, il nome del tipo è stato cambiato in`Mutation`, e il nome,. `createPost` La configurazione della pipeline è stata impostata sulla nostra nuova funzione di mutazione. `add_func_2`

------

Per riassumere ciò che sta accadendo in questo esempio, converte AWS AppSync automaticamente gli argomenti definiti nel `createPost` campo dallo schema GraphQL in operazioni DynamoDB. L'esempio archivia i record in DynamoDB utilizzando una chiave `id` di, che viene creata automaticamente utilizzando il nostro helper. `util.autoId()` Tutti gli altri campi passati agli argomenti di contesto (`ctx.args.input`) dalle richieste effettuate nella AWS AppSync console o in altro modo verranno memorizzati come attributi della tabella. Sia la chiave che gli attributi vengono mappati automaticamente su un formato DynamoDB compatibile utilizzando l'helper. `util.dynamodb.toMapValues(values)`

AWS AppSync supporta anche flussi di lavoro di test e debug per la modifica dei resolver. È possibile utilizzare un `context` oggetto fittizio per vedere il valore trasformato del modello prima di richiamarlo. Facoltativamente, puoi visualizzare la richiesta completa a un'origine dati in modo interattivo quando esegui una query. [Per ulteriori informazioni, vedete [Test and debug resolvers () JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/test-debug-resolvers-js.html) e Monitoring and logging.](https://docs.aws.amazon.com/appsync/latest/devguide/monitoring.html#aws-appsync-monitoring)

## Resolver avanzati
<a name="advanced-resolvers-js"></a>

Se stai seguendo la sezione opzionale sull'impaginazione in [Progettazione dello schema](designing-your-schema.md#aws-appsync-designing-your-schema), devi comunque aggiungere il resolver alla richiesta per utilizzare l'impaginazione. Il nostro esempio ha utilizzato una paginazione di query chiamata `getPosts` per restituire solo una parte degli elementi richiesti alla volta. Il codice del nostro resolver su quel campo potrebbe essere simile al seguente:

```
/**
 * Performs a scan on the dynamodb data source
 */
export function request(ctx) {
  const { limit = 20, nextToken } = ctx.args;
  return { operation: 'Scan', limit, nextToken };
}

/**
 * @returns the result of the `put` operation
 */
export function response(ctx) {
  const { items: posts = [], nextToken } = ctx.result;
  return { posts, nextToken };
}
```

Nella richiesta, passiamo nel contesto della richiesta. Il nostro `limit` è*20*, il che significa che restituiamo fino a 20 `Posts` nella prima query. Il nostro `nextToken` cursore è fissato alla prima `Post` voce nella fonte di dati. Questi vengono passati agli args. La richiesta esegue quindi una scansione dalla prima `Post` fino al numero limite di scansione. L'origine dati memorizza il risultato nel contesto, che viene passato alla risposta. La risposta `Posts` restituisce la risposta recuperata, quindi imposta l'impostazione `nextToken` è impostata sulla `Post` voce subito dopo il limite. La richiesta successiva viene inviata per fare esattamente la stessa cosa, ma a partire dall'offset subito dopo la prima query. Tieni presente che questo tipo di richieste vengono eseguite in sequenza e non in parallelo.

# Test e debug dei resolver in () AWS AppSync JavaScript
<a name="test-debug-resolvers-js"></a>

AWS AppSync esegue resolver su un campo GraphQL su un'origine dati. Quando si lavora con i resolver per pipeline, le funzioni interagiscono con le fonti di dati. Come descritto nella [panoramica dei JavaScript resolver, le funzioni comunicano con le fonti di dati utilizzando gestori](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html) di richieste e risposte scritti ed eseguiti nel runtime. JavaScript `APPSYNC_JS` Ciò consente di fornire logica e condizioni personalizzate prima e dopo la comunicazione con l'origine dati.

Per aiutare gli sviluppatori a scrivere, testare ed eseguire il debug di questi resolver, la AWS AppSync console fornisce anche strumenti per creare una richiesta e una risposta GraphQL con dati fittizi fino al singolo resolver di campo. Inoltre, puoi eseguire query, mutazioni e sottoscrizioni nella AWS AppSync console e visualizzare un flusso di log dettagliato dell'intera richiesta proveniente da Amazon. CloudWatch Ciò include i risultati della fonte di dati.

## Test con dati fittizi
<a name="testing-with-mock-data-js"></a>

Quando viene richiamato un resolver GraphQL, contiene un `context` oggetto che contiene informazioni pertinenti sulla richiesta. Tali informazioni includono gli argomenti provenienti da un client, le informazioni sull'identità e i dati del campo GraphQL padre. Memorizza anche i risultati della fonte di dati, che può essere utilizzata nel gestore delle risposte. Per ulteriori informazioni su questa struttura e sulle utilità di supporto disponibili da utilizzare durante la programmazione, vedete il riferimento all'oggetto contestuale [Resolver](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html).

Quando si scrive o si modifica una funzione resolver, è possibile passare un oggetto contestuale *fittizio* o di *test* all'editor della console. Ciò consente di vedere come valutano sia il gestore di richiesta che quello di risposta senza che vengano effettivamente eseguiti su una fonte di dati. Puoi ad esempio passare un argomento `firstname: Shaggy` di test e vedere i relativi risultati quando usi `ctx.args.firstname` nel codice del modello. Puoi anche testare la valutazione di utilità helper, ad esempio `util.autoId()` o `util.time.nowISO8601()`.

### Test dei resolver
<a name="test-a-resolver-js"></a>

Questo esempio utilizzerà la AWS AppSync console per testare i resolver.

1. [Accedi a Console di gestione AWS e apri la console. AppSync](https://console.aws.amazon.com/appsync/)

   1. Nella **APIs dashboard**, scegli la tua API GraphQL.

   1. **Nella **barra laterale**, scegli Funzioni.**

1. Scegli una funzione esistente.

1. Nella parte superiore della pagina **Aggiorna funzione**, scegli **Seleziona contesto di test**, quindi scegli **Crea nuovo contesto**.

1. Seleziona un oggetto di contesto di esempio o compila il codice JSON manualmente nella finestra **Configura contesto di test** di seguito.

1. Immettete un nome per **il contesto di testo**.

1. Seleziona il pulsante **Save** (Salva).

1. Per valutare il resolver utilizzando l'oggetto context fittizio, scegliere **Run Test (Esegui test)**.

Per un esempio più pratico, supponiamo di avere un'app che memorizza un tipo GraphQL che utilizza la generazione automatica `Dog` di ID per gli oggetti e li archivia in Amazon DynamoDB. Vuoi anche scrivere alcuni valori dagli argomenti di una mutazione GraphQL e consentire solo a utenti specifici di vedere una risposta. Il seguente frammento mostra come potrebbe apparire lo schema:

```
type Dog {
  breed: String
  color: String
}

type Mutation {
  addDog(firstname: String, age: Int): Dog
}
```

Puoi scrivere una AWS AppSync funzione e aggiungerla al tuo `addDog` resolver per gestire la mutazione. Per testare la tua AWS AppSync funzione, puoi compilare un oggetto di contesto come nell'esempio seguente. Il seguente include gli argomenti `name` e `age` del client, oltre che un elemento `username` popolato nell'oggetto `identity`:

```
{
    "arguments" : {
        "firstname": "Shaggy",
        "age": 4
    },
    "source" : {},
    "result" : {
        "breed" : "Miniature Schnauzer",
        "color" : "black_grey"
    },
    "identity": {
        "sub" : "uuid",
        "issuer" : " https://cognito-idp.{region}.amazonaws.com/{userPoolId}",
        "username" : "Nadia",
        "claims" : { },
        "sourceIp" :[  "x.x.x.x" ],
        "defaultAuthStrategy" : "ALLOW"
    }
}
```

È possibile testare la AWS AppSync funzione utilizzando il codice seguente:

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ id: util.autoId() }),
    attributeValues: util.dynamodb.toMapValues(ctx.args),
  };
}

export function response(ctx) {
  if (ctx.identity.username === 'Nadia') {
    console.log("This request is allowed")
    return ctx.result;
  }
  util.unauthorized();
}
```

Il gestore di richieste e risposte valutato contiene i dati dell'oggetto del contesto di test e il valore generato da. `util.autoId()` Inoltre, se decidi di modificare `username` in un valore diverso da `Nadia`, i risultati non verranno restituiti perché il controllo di autorizzazione avrebbe esito negativo. [Per ulteriori informazioni sul controllo granulare degli accessi, consulta Casi d'uso delle autorizzazioni.](security-authorization-use-cases.md#aws-appsync-security-authorization-use-cases)

### Testare i gestori di richieste e risposte con's AWS AppSync APIs
<a name="testing-with-appsync-api-js"></a>

Puoi utilizzare il comando `EvaluateCode` API per testare in remoto il tuo codice con dati simulati. Per iniziare con il comando, assicurati di aver aggiunto l'`appsync:evaluateMappingCode`autorizzazione alla tua politica. Esempio:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "appsync:evaluateCode",
            "Resource": "arn:aws:appsync:us-east-1:111122223333:*"
        }
    ]
}
```

------

È possibile sfruttare il comando utilizzando [AWS CLI](https://aws.amazon.com/cli/)o [AWS SDKs](https://aws.amazon.com/tools/). Ad esempio, prendiamo lo `Dog` schema e i relativi gestori di richiesta e risposta delle AWS AppSync funzioni della sezione precedente. Utilizzando la CLI sulla stazione locale, salvate il codice in un file denominato`code.js`, quindi salvate l'`context`oggetto in un file denominato. `context.json` Dalla tua shell, esegui il seguente comando:

```
$ aws appsync evaluate-code \
  --code file://code.js \
  --function response \
  --context file://context.json \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0
```

La risposta contiene un file `evaluationResult` contenente il payload restituito dal gestore. Contiene anche un `logs` oggetto che contiene l'elenco dei log generati dal gestore durante la valutazione. Ciò semplifica il debug dell'esecuzione del codice e la visualizzazione delle informazioni sulla valutazione per facilitare la risoluzione dei problemi. Esempio:

```
{
    "evaluationResult": "{\"breed\":\"Miniature Schnauzer\",\"color\":\"black_grey\"}",
    "logs": [
        "INFO - code.js:13:5: \"This request is allowed\""
    ]
}
```

`evaluationResult`Può essere analizzato come JSON, il che fornisce: 

```
{
  "breed": "Miniature Schnauzer",
  "color": "black_grey"
}
```

Utilizzando l'SDK, puoi incorporare facilmente i test della tua suite di test preferita per convalidare il comportamento dei tuoi gestori. Ti consigliamo di creare test utilizzando [Jest Testing Framework, ma qualsiasi suite di test](https://jestjs.io/) funziona. Il seguente frammento mostra un'ipotetica esecuzione di convalida. Nota che ci aspettiamo che la risposta di valutazione sia un codice JSON valido, quindi lo utilizziamo `JSON.parse` per recuperare JSON dalla stringa di risposta:

```
const AWS = require('aws-sdk')
const fs = require('fs')
const client = new AWS.AppSync({ region: 'us-east-2' })
const runtime = {name:'APPSYNC_JS',runtimeVersion:'1.0.0')

test('request correctly calls DynamoDB', async () => {
  const code = fs.readFileSync('./code.js', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateCode({ code, context, runtime, function: 'request' }).promise()
  const result = JSON.parse(response.evaluationResult)
  
  expect(result.key.id.S).toBeDefined()
  expect(result.attributeValues.firstname.S).toEqual(contextJSON.arguments.firstname)
})
```

 Ciò produce il seguente risultato:

```
Ran all test suites.
> jest

PASS ./index.test.js
✓ request correctly calls DynamoDB (543 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 totalTime: 1.511 s, estimated 2 s
```

## Eseguire il debug di una query live
<a name="debugging-a-live-query-js"></a>

Non c'è nulla che possa sostituire un end-to-end test e una registrazione per eseguire il debug di un'applicazione di produzione. AWS AppSync consente di registrare gli errori e i dettagli completi delle richieste utilizzando Amazon CloudWatch. Inoltre, puoi utilizzare la AWS AppSync console per testare le query, le mutazioni e gli abbonamenti GraphQL e trasmettere in live streaming i dati di registro per ogni richiesta nell'editor di query per il debug in tempo reale. Per le sottoscrizioni, i log visualizzano le informazioni relative al tempo della connessione.

A tale scopo, è necessario che Amazon CloudWatch logs sia abilitato in anticipo, come descritto in [Monitoraggio e registrazione](monitoring.md#aws-appsync-monitoring). Successivamente, nella AWS AppSync console, scegli la scheda **Queries** e inserisci una query GraphQL valida. Nella sezione in basso a destra, fai clic e trascina la finestra **Logs per aprire** la visualizzazione dei log. Sulla parte superiore della pagina, scegliere l'icona con la freccia per la riproduzione per eseguire la query GraphQL. In pochi istanti, i registri completi delle richieste e delle risposte relativi all'operazione vengono trasmessi in streaming a questa sezione e possono essere visualizzati nella console.

# Configurazione e utilizzo dei resolver di pipeline in () AWS AppSync JavaScript
<a name="pipeline-resolvers-js"></a>

AWS AppSync esegue i resolver su un campo GraphQL. In alcuni casi, le applicazioni prevedono il compimento di più operazioni per la risoluzione di un singolo campo GraphQL. Con i resolver a pipeline, gli sviluppatori possono ora comporre operazioni chiamate Funzioni ed eseguirle in sequenza. Questo tipo di resolver torna utile, ad esempio, con applicazioni che prevedono un controllo delle autorizzazioni antecedente al recupero dei dati per un campo.

[Per ulteriori informazioni sull'architettura di un resolver di JavaScript pipeline, consulta la panoramica dei resolver. JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html#anatomy-of-a-pipeline-resolver-js)

## Fase 1: Creazione di un risolutore di pipeline
<a name="create-a-pipeline-resolver-js"></a>

**Nella AWS AppSync console, vai alla pagina Schema.**

Salva lo schema seguente:

```
schema {
    query: Query
    mutation: Mutation
}

type Mutation {
    signUp(input: Signup): User
}

type Query {
    getUser(id: ID!): User
}

input Signup {
    username: String!
    email: String!
}

type User {
    id: ID!
    username: String
    email: AWSEmail
}
```

Bisogna implementare un resolver di pipeline per il campo **signUp (registrazione)** del tipo di **Mutation (Mutazione)**. Nel tipo di **mutazione** sul lato destro, scegli **Allega** accanto al campo di `signUp` mutazione. Imposta il resolver su `pipeline resolver` e il `APPSYNC_JS` runtime, quindi crea il resolver.

Il nostra resolver di pipeline registra un utente convalidandone l'indirizzo e-mail e, successivamente, salvandolo nel sistema. **Incapsuleremo la convalida dell'e-mail all'interno di una funzione ValidateEmail e il salvataggio dell'**utente all'interno** di una funzione SaveUser.** Per prima, viene eseguita la funzione **validateEmail**, al termine della quale e solo se appurata la validità dell'e-mail, si può procedere con la **saveUser**.

Il flusso di esecuzione sarà il seguente:

1. Gestore di richieste del resolver Mutation.signup

1. Funzione validateEmail

1. Funzione saveUser

1. Gestore di risposte del resolver Mutation.signup

Poiché probabilmente riutilizzeremo la funzione **ValidateEmail** in altri resolver sulla nostra API, vogliamo evitare l'accesso `ctx.args` perché questi cambieranno da un campo GraphQL all'altro. In alternativa, è possibile avvalersi di `ctx.stash` per memorizzare l'attributo e-mail dall'argomento del campo di input `signUp(input: Signup)`.

Aggiorna il codice del resolver sostituendo le funzioni di richiesta e risposta:

```
export function request(ctx) {
    ctx.stash.email = ctx.args.input.email
    return {};
}

export function response(ctx) {
    return ctx.prev.result;
}
```

Scegli **Crea** o **Salva** per aggiornare il resolver.

## Fase 2: Creazione di una funzione
<a name="create-a-function-js"></a>

Dalla pagina Pipeline Resolver, nella sezione **Funzioni**, fai clic su **Aggiungi funzione, quindi su **Crea** nuova funzione**. **È anche possibile creare funzioni senza passare dalla pagina del resolver; per farlo, nella AWS AppSync console, vai alla pagina Funzioni.** Selezionare il pulsante **Create function (Crea funzione)**. Creiamo quindi una funzione che verifichi la validità e la provenienza da un determinato dominio di un indirizzo e-mail. In caso di e-mail non valida, la funzione restituisce un errore. Altrimenti, inoltra qualsiasi input immesso.

Assicurati di aver creato una fonte di dati del tipo **NONE**. Scegli questa fonte di **dati nell'elenco Nome origine dati**. Per il **nome della funzione**, immettete`validateEmail`. Nell'area del **codice della funzione**, sovrascrivi tutto con questo frammento:

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { email } = ctx.stash;
  const valid = util.matches(
    '^[a-zA-Z0-9_.+-]+@(?:(?:[a-zA-Z0-9-]+\.)?[a-zA-Z]+\.)?(myvaliddomain)\.com',
    email
  );
  if (!valid) {
    util.error(`"${email}" is not a valid email.`);
  }

  return { payload: { email } };
}

export function response(ctx) {
  return ctx.result;
}
```

**Controlla i dati inseriti, quindi scegli Crea.** A questo punto, la funzione **validateEmail** è stata creata. **Ripeti questi passaggi per creare la funzione SaveUser con il codice seguente (per semplicità, utilizziamo **una** fonte di dati NONE e facciamo finta che l'utente sia stato salvato nel sistema dopo l'esecuzione della funzione.** ):

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  return ctx.prev.result;
}

export function response(ctx) {
  ctx.result.id = util.autoId();
  return ctx.result;
}
```

Abbiamo appena creato la nostra funzione **SaveUser**.

## Fase 3: Aggiungere una funzione a un risolutore di pipeline
<a name="adding-a-function-to-a-pipeline-resolver-js"></a>

Le nostre funzioni avrebbero dovuto essere aggiunte automaticamente al risolutore di pipeline che abbiamo appena creato. Se così non fosse, o se hai creato le funzioni tramite la pagina **Funzioni**, puoi fare clic su **Aggiungi funzione** nuovamente nella pagina del `signUp` resolver per allegarle. Aggiungi entrambe le funzioni **ValidateEmail** **e** SaveUser al resolver. la funzione **validateEmail** deve precedere quella **saveUser**. Man mano che aggiungi altre funzioni, puoi utilizzare le opzioni di **spostamento su** e **sposta giù** per riorganizzare l'ordine di esecuzione delle funzioni. Controlla le modifiche, quindi scegli **Salva**.

## Passaggio 4: Esecuzione di una query
<a name="running-a-query-js"></a>

Nella AWS AppSync console, vai alla pagina **Query**. Nell'explorer, assicurati di usare la tua mutazione. Se non lo sei, scegli `Mutation` nell'elenco a discesa, quindi scegli. `+` Inserire la query seguente:

```
mutation {
  signUp(input: {email: "nadia@myvaliddomain.com", username: "nadia"}) {
    id
    username
  }
}
```

Questo dovrebbe restituire qualcosa del tipo:

```
{
  "data": {
    "signUp": {
      "id": "256b6cc2-4694-46f4-a55e-8cb14cc5d7fc",
      "username": "nadia"
    }
  }
}
```

Abbiamo quindi registrato il nostro utente convalidandone, al contempo, l'e-mail di input tramite un resolver di pipeline.

# Creazione di interrogazioni di base (VTL)
<a name="configuring-resolvers"></a>

**Nota**  
Ora supportiamo principalmente il runtime APPSYNC\$1JS e la relativa documentazione. [Prendi in considerazione l'utilizzo del runtime APPSYNC\$1JS e delle relative guide qui.](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html)

I resolver GraphQL connettono i campi nello schema di un tipo a un'origine dati. I resolver sono il meccanismo mediante il quale le richieste vengono soddisfatte. AWS AppSync possono creare e connettere automaticamente i resolver da uno schema oppure creare uno schema e connettere i resolver da una tabella esistente senza dover scrivere alcun codice.

Resolver AWS AppSync utilizzati JavaScript per convertire un'espressione GraphQL in un formato utilizzabile dall'origine dati. In alternativa, i modelli di mappatura possono essere scritti in [Apache Velocity Template Language (VTL) per](https://velocity.apache.org/engine/2.0/vtl-reference.html) convertire un'espressione GraphQL in un formato utilizzabile dall'origine dati.

Questa sezione ti mostrerà come configurare i resolver usando VTL. [Una guida introduttiva alla programmazione in stile tutorial per la scrittura di resolver è disponibile nella guida alla programmazione dei modelli di mappatura [Resolver, mentre le utilità di supporto disponibili per la programmazione sono disponibili nella guida al contesto del modello di mappatura Resolver](resolver-mapping-template-reference-programming-guide.md#aws-appsync-resolver-mapping-template-reference-programming-guide).](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference) AWS AppSync dispone anche di flussi di test e debug integrati che puoi usare quando modifichi o crei da zero. Per ulteriori informazioni, consulta [Test and debug](test-debug-resolvers.md#aws-appsync-test-debug-resolvers) resolvers.

Ti consigliamo di seguire questa guida prima di provare a utilizzare uno dei tutorial sopra menzionati.

In questa sezione, spiegheremo come creare un resolver, aggiungere un resolver per le mutazioni e utilizzare configurazioni avanzate.

## Crea il tuo primo resolver
<a name="create-your-first-resolver"></a>

Seguendo gli esempi delle sezioni precedenti, il primo passo è creare un resolver adatto al tuo tipo. `Query`

------
#### [ Console ]

1. [Accedi a Console di gestione AWS e apri la AppSync console.](https://console.aws.amazon.com/appsync/)

   1. Nella **APIs dashboard**, scegli la tua API GraphQL.

   1. **Nella **barra laterale**, scegli Schema.**

1. **Sul lato destro della pagina, c'è una finestra chiamata Resolvers.** Questa casella contiene un elenco dei tipi e dei campi definiti nella finestra **Schema** sul lato sinistro della pagina. È possibile allegare resolver ai campi. Ad esempio, nella sezione Tipo di **query**, scegli **Allega** accanto al campo. `getTodos`

1. Nella pagina **Create Resolver**, scegli l'origine dati che hai creato nella guida [Allegare una fonte di dati](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html). Nella finestra **Configura modelli di mappatura**, puoi scegliere sia il modello generico di mappatura di richiesta che quello di risposta utilizzando l'elenco a discesa a destra o scriverne uno personalizzato.
**Nota**  
L'associazione di un modello di mappatura delle richieste a un modello di mappatura delle risposte viene chiamata risolutore di unità. I resolver di unità sono in genere pensati per eseguire operazioni di routine; si consiglia di utilizzarli solo per operazioni singolari con un numero limitato di fonti di dati. Per operazioni più complesse, consigliamo di utilizzare resolver a pipeline, che possono eseguire più operazioni con più fonti di dati in sequenza.  
[Per ulteriori informazioni sulla differenza tra i modelli di mappatura delle richieste e delle risposte, consulta Unit resolvers.](https://docs.aws.amazon.com//appsync/latest/devguide/resolver-mapping-template-reference-overview.html#unit-resolvers)  
[Per ulteriori informazioni sull'utilizzo dei resolver pipeline, vedete Pipeline resolvers.](pipeline-resolvers.md#aws-appsync-pipeline-resolvers)

1. Per i casi d'uso più comuni, la AWS AppSync console dispone di modelli integrati che è possibile utilizzare per recuperare elementi dalle fonti di dati (ad esempio, le query su tutti gli elementi, le ricerche individuali, ecc.). Ad esempio, nella versione semplice dello schema di [Designing your schema](designing-your-schema.md#aws-appsync-designing-your-schema) in cui `getTodos` non c'era l'impaginazione, il modello di mappatura delle richieste per elencare gli articoli è il seguente:

   ```
   {
       "version" : "2017-02-28",
       "operation" : "Scan"
   }
   ```

1. È sempre necessario un modello di mappatura delle risposte da allegare alla richiesta. La console ne fornisce uno predefinito con il valore di passthrough seguente per elenchi:

   ```
   $util.toJson($ctx.result.items)
   ```

   In questo esempio, l'oggetto `context` (con alias `$ctx`) per gli elenchi di elementi presenta la forma `$context.result.items`. Se l'operazione GraphQL restituisce un singolo elemento, sarebbe `$context.result`. AWS AppSync fornisce funzioni di helper per operazioni comuni, ad esempio la funzione `$util.toJson` elencata in precedenza, per formattare le risposte correttamente. Per un elenco completo delle funzioni, consulta il riferimento all'utilità del modello di [mappatura Resolver](resolver-util-reference.md#aws-appsync-resolver-mapping-template-util-reference).

1. **Scegli Save Resolver.**

------
#### [ API ]

1. Crea un oggetto resolver chiamando l'API. [https://docs.aws.amazon.com/appsync/latest/APIReference/API_CreateResolver.html](https://docs.aws.amazon.com/appsync/latest/APIReference/API_CreateResolver.html)

1. Puoi modificare i campi del tuo resolver chiamando l'API. [https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateResolver.html](https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateResolver.html)

------
#### [ CLI ]

1. Crea un resolver eseguendo il comando. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)

   Dovrai digitare 6 parametri per questo particolare comando:

   1. La `api-id` della tua API.

   1. Il `type-name` tipo che desideri modificare nel tuo schema. Nell'esempio della console, questo era`Query`.

   1. Il `field-name` campo che vuoi modificare nel tuo tipo. Nell'esempio della console, questo era`getTodos`.

   1. La fonte `data-source-name` di dati che hai creato nella guida [Allegare una fonte di dati](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html).

   1. Il`request-mapping-template`, che è il corpo della richiesta. Nell'esempio della console, questo era:

      ```
      {
          "version" : "2017-02-28",
          "operation" : "Scan"
      }
      ```

   1. Il`response-mapping-template`, che è il corpo della risposta. Nell'esempio della console, questo era:

      ```
      $util.toJson($ctx.result.items)
      ```

   Un comando di esempio può essere simile al seguente:

   ```
   aws appsync create-resolver --api-id abcdefghijklmnopqrstuvwxyz --type-name Query --field-name getTodos --data-source-name TodoTable --request-mapping-template "{ "version" : "2017-02-28", "operation" : "Scan", }" --response-mapping-template ""$"util.toJson("$"ctx.result.items)"
   ```

   Un output verrà restituito nella CLI. Ecco un esempio:

   ```
   {
       "resolver": {
           "kind": "UNIT",
           "dataSourceName": "TodoTable",
           "requestMappingTemplate": "{ version : 2017-02-28, operation : Scan, }",
           "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Query/resolvers/getTodos",
           "typeName": "Query",
           "fieldName": "getTodos",
           "responseMappingTemplate": "$util.toJson($ctx.result.items)"
       }
   }
   ```

1. Per modificare i modelli di and/or mappatura dei campi di un resolver, esegui il comando. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-resolver.html)

   Ad eccezione del `api-id` parametro, i parametri utilizzati nel `create-resolver` comando verranno sovrascritti dai nuovi valori del comando. `update-resolver`

------

## Aggiungere un resolver per le mutazioni
<a name="adding-a-resolver-for-mutations"></a>

Il passaggio successivo consiste nel creare un resolver adatto al tuo tipo. `Mutation`

------
#### [ Console ]

1. [Accedi a Console di gestione AWS e apri la AppSync console.](https://console.aws.amazon.com/appsync/)

   1. Nella **APIs dashboard**, scegli la tua API GraphQL.

   1. **Nella **barra laterale**, scegli Schema.**

1. Nella sezione Tipo di **mutazione**, scegli **Allega** accanto al `addTodo` campo.

1. Nella pagina **Create Resolver**, scegli l'origine dati che hai creato nella guida [Allegare una](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html) fonte di dati.

1. Nella finestra **Configura modelli di mappatura**, è necessario modificare il modello di richiesta perché si tratta di una mutazione in cui si aggiunge un nuovo elemento a DynamoDB. Usa modello di mappatura della richiesta seguente:

   ```
   {
       "version" : "2017-02-28",
       "operation" : "PutItem",
       "key" : {
           "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
       },
       "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
   }
   ```

1. AWS AppSync converte automaticamente gli argomenti definiti nel `addTodo` campo dallo schema GraphQL in operazioni DynamoDB. L'esempio precedente archivia i record in DynamoDB utilizzando una chiave `id` of, che viene passata dall'argomento di mutazione as. `$ctx.args.id` Tutti gli altri campi che passi attraverso vengono mappati automaticamente agli attributi DynamoDB con. `$util.dynamodb.toMapValuesJson($ctx.args)`

   Per questo resolver, usare il seguente modello di mappatura della risposta:

   ```
   $util.toJson($ctx.result)
   ```

   AWS AppSync supporta anche flussi di lavoro di test e debug per la modifica dei resolver. È possibile utilizzare un oggetto `context` fittizio per visualizzare il valore trasformato del modello prima di effettuare la chiamata. Eventualmente, è possibile visualizzare l'esecuzione di richiesta completa a un'origine dati in modo interattivo quando si esegue una query. [Per ulteriori informazioni, consulta [Test e debug resolvers e Monitoraggio e](test-debug-resolvers.md#aws-appsync-test-debug-resolvers) registrazione.](monitoring.md#aws-appsync-monitoring)

1. **Scegli** Save Resolver.

------
#### [ API ]

Puoi farlo anche APIs utilizzando i comandi nella sezione [Crea il tuo primo resolver](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) e i dettagli dei parametri in questa sezione.

------
#### [ CLI ]

Puoi farlo anche nella CLI utilizzando i comandi nella sezione [Crea il tuo primo resolver](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) e i dettagli dei parametri in questa sezione.

------

[A questo punto, se non utilizzi i resolver avanzati, puoi iniziare a utilizzare l'API GraphQL come descritto in Utilizzo dell'API.](using-your-api.md#aws-appsync-using-your-api)

## Resolver avanzati
<a name="advanced-resolvers"></a>

Se stai seguendo la sezione Avanzate e stai creando uno schema di esempio in [Progettazione dello schema](designing-your-schema.md#aws-appsync-designing-your-schema) per eseguire una scansione impaginata, usa invece il seguente modello di richiesta per il campo: `getTodos`

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "limit": $util.defaultIfNull(${ctx.args.limit}, 20),
    "nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.nextToken, null))
}
```

Per questo caso d'uso della paginazione, la mappatura della risposta è più di un semplice passthrough perché deve contenere sia il *cursore* (in modo che il client sappia a quale pagina passare) che il set di risultati. Il modello di mappatura è come segue:

```
{
    "todos": $util.toJson($context.result.items),
    "nextToken": $util.toJson($context.result.nextToken)
}
```

I campi nel modello di mappatura della risposta precedente devono corrispondere ai campi definiti nel tipo `TodoConnection`.

Nel caso di relazioni in cui si dispone di una `Comments` tabella e si sta risolvendo il campo dei commenti sul `Todo` tipo (che restituisce un tipo di`[Comment]`), è possibile utilizzare un modello di mappatura che esegue una query sulla seconda tabella. A tale scopo, è necessario aver già creato un'origine dati per la `Comments` tabella, come descritto in [Allegare](attaching-a-data-source.md#aws-appsync-getting-started-build-a-schema-from-scratch) un'origine dati.

**Nota**  
Stiamo utilizzando un'operazione di interrogazione su una seconda tabella solo a scopo illustrativo. È possibile utilizzare invece un'altra operazione su DynamoDB. Inoltre, puoi estrarre i dati da un'altra fonte di dati, ad AWS Lambda esempio Amazon OpenSearch Service, perché la relazione è controllata dal tuo schema GraphQL.

------
#### [ Console ]

1. Accedi a Console di gestione AWS e apri la [AppSync console](https://console.aws.amazon.com/appsync/).

   1. Nella **APIs dashboard**, scegli la tua API GraphQL.

   1. **Nella **barra laterale**, scegli Schema.**

1. Nel tipo **Todo**, scegli **Allega** accanto al `comments` campo.

1. Nella pagina **Create Resolver**, scegli l'origine dati della tabella **Commenti**. Il nome predefinito per la tabella **Commenti** delle guide di avvio rapido è`AppSyncCommentTable`, ma può variare a seconda del nome assegnato.

1. Aggiungi il seguente frammento al modello di mappatura della richiesta:

   ```
   {
       "version": "2017-02-28",
       "operation": "Query",
       "index": "todoid-index",
       "query": {
           "expression": "todoid = :todoid",
           "expressionValues": {
               ":todoid": {
                   "S": $util.toJson($context.source.id)
               }
           }
       }
   }
   ```

1. `context.source` fa riferimento all'oggetto padre del campo corrente che viene risolto. In questo esempio, `source.id` si riferisce al singolo oggetto `Todo`, che viene quindi utilizzato per l'espressione di query.

   Puoi usare il modello di mappatura della risposta passthrough come segue:

   ```
   $util.toJson($ctx.result.items)
   ```

1. **Scegli Save Resolver.**

1. Infine, torna alla pagina **Schema** della console, collega un resolver al `addComment` campo e specifica l'origine dati per la tabella. `Comments` Il modello di mappatura della richiesta in questo caso è un semplice oggetto `PutItem` con il `todoid` specifico commentato su un argomento, ma puoi utilizzare l'utilità `$utils.autoId()` per creare una chiave di ordinamento per il commento, come segue:

   ```
   {
       "version": "2017-02-28",
       "operation": "PutItem",
       "key": {
           "todoid": { "S": $util.toJson($context.arguments.todoid) },
           "commentid": { "S": "$util.autoId()" }
       },
       "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
   }
   ```

   Usa un modello di risposta passthrough come segue:

   ```
   $util.toJson($ctx.result)
   ```

------
#### [ API ]

Puoi farlo anche APIs utilizzando i comandi nella sezione [Crea il tuo primo resolver](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) e i dettagli dei parametri in questa sezione.

------
#### [ CLI ]

Puoi farlo anche nella CLI utilizzando i comandi nella sezione [Crea il tuo primo resolver](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) e i dettagli dei parametri in questa sezione.

------

# Disabilitazione dei modelli di mappatura VTL con resolver Lambda diretti (VTL)
<a name="direct-lambda-reference"></a>

**Nota**  
Ora supportiamo principalmente il runtime APPSYNC\$1JS e la relativa documentazione. [Prendi in considerazione l'utilizzo del runtime APPSYNC\$1JS e delle relative guide qui.](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html)

Con i resolver diretti Lambda, puoi aggirare l'uso di modelli di mappatura VTL quando utilizzi fonti di dati. AWS Lambda AWS AppSync può fornire un payload predefinito alla funzione Lambda e una traduzione predefinita dalla risposta di una funzione Lambda a un tipo GraphQL. Puoi scegliere di fornire un modello di richiesta, un modello di risposta o nessuno dei due e lo AWS AppSync gestirai di conseguenza. 

Per ulteriori informazioni sul payload predefinito della richiesta e sulla traduzione delle risposte che AWS AppSync fornisce, consulta il riferimento al [resolver Direct Lambda](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers). Per ulteriori informazioni sulla configurazione di un'origine AWS Lambda dati e sulla configurazione di una IAM Trust Policy, consulta [Allegare](attaching-a-data-source.md) un'origine dati. 

## Configurazione di resolver Lambda diretti
<a name="direct-lambda-reference-resolvers"></a>

Le seguenti sezioni ti mostreranno come collegare sorgenti dati Lambda e aggiungere resolver Lambda ai tuoi campi.

### Aggiungere un'origine dati Lambda
<a name="direct-lambda-datasource"></a>

Prima di poter attivare i resolver Lambda diretti, devi aggiungere un'origine dati Lambda.

------
#### [ Console ]

1. [Accedi e apri la console. Console di gestione AWS AppSync](https://console.aws.amazon.com/appsync/)

   1. Nella **APIs dashboard**, scegli la tua API GraphQL.

   1. Nella **barra laterale**, scegli Origini **dati**.

1. Seleziona **Create data source (Crea origine dati)**.

   1. Per **Nome dell'origine dati**, inserisci un nome per la tua origine dati, ad esempio**myFunction**. 

   1. Per **Tipo di origine dati**, scegli **AWS Lambda funzione**.

   1. Per **Regione**, scegli la regione appropriata.

   1. Per **Funzione ARN**, scegli la funzione Lambda dall'elenco a discesa. È possibile cercare il nome della funzione o inserire manualmente l'ARN della funzione che si desidera utilizzare. 

   1. Crea un nuovo ruolo IAM (consigliato) o scegli un ruolo esistente con l'autorizzazione `lambda:invokeFunction` IAM. I ruoli esistenti richiedono una policy di fiducia, come spiegato nella sezione [Allegare una fonte di dati](attaching-a-data-source.md). 

      Di seguito è riportato un esempio di policy IAM che dispone delle autorizzazioni necessarie per eseguire operazioni sulla risorsa:

------
#### [ JSON ]

****  

      ```
      { 
           "Version":"2012-10-17",		 	 	  
           "Statement": [ 
               { 
                   "Effect": "Allow", 
                   "Action": [ "lambda:invokeFunction" ], 
                   "Resource": [ 
                       "arn:aws:lambda:us-west-2:123456789012:function:myFunction", 
                       "arn:aws:lambda:us-west-2:123456789012:function:myFunction:*" 
                   ] 
               } 
           ] 
       }
      ```

------

1. Scegli il pulsante **Crea**.

------
#### [ CLI ]

1. Crea un oggetto sorgente dati eseguendo il [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-data-source.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-data-source.html)comando.

   Dovrai digitare 4 parametri per questo particolare comando:

   1. La `api-id` della tua API.

   1. La tua fonte `name` di dati. Nell'esempio della console, questo è il **nome dell'origine dati**.

   1. La fonte `type` dei dati. Nell'esempio della console, questa è **AWS Lambda la funzione**.

   1. Il`lambda-config`, che è l'**ARN della funzione nell'esempio** della console.
**Nota**  
Esistono altri parametri come questi `Region` che devono essere configurati, ma di solito vengono utilizzati per impostazione predefinita i valori di configurazione CLI.

   Un comando di esempio può avere il seguente aspetto:

   ```
   aws appsync create-data-source --api-id abcdefghijklmnopqrstuvwxyz --name myFunction --type AWS_LAMBDA --lambda-config lambdaFunctionArn=arn:aws:lambda:us-west-2:102847592837:function:appsync-lambda-example
   ```

   Un output verrà restituito nella CLI. Ecco un esempio:

   ```
   {
       "dataSource": {
           "dataSourceArn": "arn:aws:appsync:us-west-2:102847592837:apis/abcdefghijklmnopqrstuvwxyz/datasources/myFunction",
           "type": "AWS_LAMBDA",
           "name": "myFunction",
           "lambdaConfig": {
               "lambdaFunctionArn": "arn:aws:lambda:us-west-2:102847592837:function:appsync-lambda-example"
           }
       }
   }
   ```

1. Per modificare gli attributi di un'origine dati, esegui il [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-data-source.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-data-source.html)comando.

   Ad eccezione del `api-id` parametro, i parametri utilizzati nel `create-data-source` comando verranno sovrascritti dai nuovi valori del `update-data-source` comando.

------

### Attiva i resolver Lambda diretti
<a name="direct-lambda-enable-templates"></a>

Dopo aver creato un'origine dati Lambda e impostato il ruolo IAM appropriato per consentire di AWS AppSync richiamare la funzione, puoi collegarla a una funzione resolver o pipeline. 

------
#### [ Console ]

1. [Accedi a e apri la console. Console di gestione AWS AppSync](https://console.aws.amazon.com/appsync/)

   1. Nella **APIs dashboard**, scegli la tua API GraphQL.

   1. **Nella **barra laterale**, scegli Schema.**

1. **Nella finestra **Resolver**, scegli un campo o un'operazione, quindi seleziona il pulsante Allega.**

1. Nella pagina **Crea nuovo resolver**, scegli la funzione Lambda dall'elenco a discesa.

1. **Per sfruttare i resolver diretti Lambda, verifica che i modelli di mappatura di richiesta e risposta siano disabilitati nella sezione Configura modelli di mappatura.**

1. **Scegli il pulsante Save** Resolver.

------
#### [ CLI ]
+ Crea un resolver eseguendo il comando. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)

  Dovrai digitare 6 parametri per questo particolare comando:

  1. La `api-id` della tua API.

  1. Il `type-name` tipo nel tuo schema.

  1. Il campo `field-name` del tuo schema.

  1. Il`data-source-name`, o il nome della tua funzione Lambda.

  1. Il`request-mapping-template`, che è il corpo della richiesta. Nell'esempio della console, questo era disabilitato:

     ```
     " "
     ```

  1. Il`response-mapping-template`, che è il corpo della risposta. Nell'esempio della console, anche questo era disabilitato:

     ```
     " "
     ```

  Un comando di esempio può avere il seguente aspetto:

  ```
  aws appsync create-resolver --api-id abcdefghijklmnopqrstuvwxyz --type-name Subscription --field-name onCreateTodo --data-source-name LambdaTest --request-mapping-template " " --response-mapping-template " "
  ```

  Un output verrà restituito nella CLI. Ecco un esempio:

  ```
  {
      "resolver": {
          "resolverArn": "arn:aws:appsync:us-west-2:102847592837:apis/abcdefghijklmnopqrstuvwxyz/types/Subscription/resolvers/onCreateTodo",
          "typeName": "Subscription",
          "kind": "UNIT",
          "fieldName": "onCreateTodo",
          "dataSourceName": "LambdaTest"
      }
  }
  ```

------

Quando disabiliti i modelli di mappatura, si verificheranno diversi comportamenti aggiuntivi in: AWS AppSync
+ Disabilitando un modello di mappatura, stai segnalando AWS AppSync che accetti le traduzioni dei dati predefinite specificate nel riferimento del resolver Direct [Lambda](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers).
+ [Disabilitando il modello di mappatura della richiesta, l'origine dati Lambda riceverà un payload costituito dall'intero oggetto Context.](resolver-context-reference.md)
+ Disabilitando il modello di mappatura delle risposte, il risultato della chiamata Lambda verrà tradotto a seconda della versione del modello di mappatura della richiesta o se anche il modello di mappatura della richiesta è disabilitato. 

# Test e debug dei resolver in (VTL) AWS AppSync
<a name="test-debug-resolvers"></a>

**Nota**  
Ora supportiamo principalmente il runtime APPSYNC\$1JS e la relativa documentazione. [Prendi in considerazione l'utilizzo del runtime APPSYNC\$1JS e delle relative guide qui.](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html)

AWS AppSync esegue resolver su un campo GraphQL su un'origine dati. Come descritto nella [panoramica dei modelli di mappatura Resolver, i resolver comunicano con le fonti di dati utilizzando un linguaggio di template](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview). Ciò consente di personalizzare il comportamento e applicare logica e condizioni prima e dopo la comunicazione con l'origine dati. [Per una guida introduttiva alla programmazione in stile tutorial per la scrittura di resolver, consulta la guida alla programmazione dei modelli di mappatura Resolver.](resolver-mapping-template-reference-programming-guide.md#aws-appsync-resolver-mapping-template-reference-programming-guide)

Per aiutare gli sviluppatori a scrivere, testare ed eseguire il debug di questi resolver, la AWS AppSync console fornisce anche strumenti per creare una richiesta e una risposta GraphQL con dati fittizi fino al singolo resolver di campo. Inoltre, puoi eseguire query, mutazioni e sottoscrizioni nella AWS AppSync console e visualizzare un flusso di log dettagliato da Amazon CloudWatch dell'intera richiesta. Ciò include i risultati di un'origine dati.

## Test con dati fittizi
<a name="testing-with-mock-data"></a>

Quando viene richiamato un resolver GraphQL, contiene un `context` oggetto che contiene informazioni sulla richiesta. Tali informazioni includono gli argomenti provenienti da un client, le informazioni sull'identità e i dati del campo GraphQL padre. Contiene anche i risultati della fonte di dati, che possono essere utilizzati nel modello di risposta. Per ulteriori informazioni su questa struttura e sulle utilità helper disponibili per la programmazione, consulta le [informazioni di riferimento contestuali sui modelli di mappatura dei resolver](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference).

Quando si scrive o si modifica un resolver, è possibile passare un oggetto di *contesto *fittizio* o di test* all'editor della console. In questo modo è possibile vedere in che modo i modelli di richiesta e di risposta eseguono la valutazione senza effettivamente eseguire un'origine dati. Puoi ad esempio passare un argomento `firstname: Shaggy` di test e vedere i relativi risultati quando usi `$ctx.args.firstname` nel codice del modello. Puoi anche testare la valutazione di utilità helper, ad esempio `$util.autoId()` o `util.time.nowISO8601()`.

### Test dei resolver
<a name="test-a-resolver"></a>

Questo esempio utilizzerà la AWS AppSync console per testare i resolver.

1. [Accedi a Console di gestione AWS e apri la console. AppSync](https://console.aws.amazon.com/appsync/)

   1. Nella **APIs dashboard**, scegli la tua API GraphQL.

   1. **Nella **barra laterale**, scegli Schema.**

1. Se non l'hai già fatto, sotto il tipo e accanto al campo, scegli **Allega** per aggiungere il tuo resolver.

   [Per ulteriori informazioni su come creare un resolver completo, consulta Configurazione dei resolver.](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html)

   Altrimenti, seleziona il resolver già presente nel campo.

1. **Nella parte superiore della pagina **Modifica resolver**, scegli **Seleziona contesto di test, scegli Crea nuovo contesto**.**

1. Seleziona un oggetto contestuale di esempio o compila il JSON manualmente nella finestra del contesto di **esecuzione** sottostante.

1. Immettete un nome di **contesto di testo**.

1. Seleziona il pulsante **Save** (Salva).

1. Nella parte superiore della pagina **Edit Resolver**, scegli **Esegui** test.

Per un esempio più pratico, supponiamo di avere un'app che memorizza un tipo GraphQL che utilizza la generazione automatica `Dog` di ID per gli oggetti e li archivia in Amazon DynamoDB. Devi inoltre scrivere alcuni valori dagli argomenti di una mutazione GraphQL e permettere la visualizzazione di una risposta solo a determinati utenti. Di seguito viene mostrato come potrebbe apparire lo schema:

```
type Dog {
  breed: String
  color: String
}

type Mutation {
  addDog(firstname: String, age: Int): Dog
}
```

Quando aggiungi un resolver per la `addDog` mutazione, puoi popolare un oggetto di contesto come nell'esempio seguente. Il seguente include gli argomenti `name` e `age` del client, oltre che un elemento `username` popolato nell'oggetto `identity`:

```
{
    "arguments" : {
        "firstname": "Shaggy",
        "age": 4
    },
    "source" : {},
    "result" : {
        "breed" : "Miniature Schnauzer",
        "color" : "black_grey"
    },
    "identity": {
        "sub" : "uuid",
        "issuer" : " https://cognito-idp.{region}.amazonaws.com/{userPoolId}",
        "username" : "Nadia",
        "claims" : { },
        "sourceIp" :[  "x.x.x.x" ],
        "defaultAuthStrategy" : "ALLOW"
    }
}
```

Puoi eseguire un test usando i modelli di mappatura della richiesta e della risposta seguenti:

 **Modello di richiesta** 

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "id" : { "S" : "$util.autoId()" }
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

 **Modello di risposta** 

```
#if ($context.identity.username == "Nadia")
  $util.toJson($ctx.result)
#else
  $util.unauthorized()
#end
```

Il modello valutato contiene i dati dell'oggetto context di test e il valore generato da `$util.autoId()`. Inoltre, se decidi di modificare `username` in un valore diverso da `Nadia`, i risultati non verranno restituiti perché il controllo di autorizzazione avrebbe esito negativo. [Per ulteriori informazioni sul controllo granulare degli accessi, consulta Casi d'uso delle autorizzazioni.](security-authorization-use-cases.md#aws-appsync-security-authorization-use-cases)

### Test dei modelli di mappatura con's AWS AppSync APIs
<a name="testing-with-appsync-api"></a>

Puoi utilizzare il comando `EvaluateMappingTemplate` API per testare in remoto i tuoi modelli di mappatura con dati simulati. Per iniziare con il comando, assicurati di aver aggiunto l'`appsync:evaluateMappingTemplate`autorizzazione alla tua politica. Esempio:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "appsync:evaluateMappingTemplate",
            "Resource": "arn:aws:appsync:us-east-1:111122223333:*"
        }
    ]
}
```

------

È possibile sfruttare il comando utilizzando [AWS CLI](https://aws.amazon.com/cli/)o [AWS SDKs](https://aws.amazon.com/tools/). Ad esempio, prendiamo lo `Dog` schema e i relativi modelli di request/response mappatura della sezione precedente. Utilizzando la CLI sulla stazione locale, salvate il modello di richiesta in un file denominato`request.vtl`, quindi salvate l'`context`oggetto in un file denominato. `context.json` Dalla tua shell, esegui il seguente comando:

```
aws appsync evaluate-mapping-template --template file://request.vtl --context file://context.json
```

Il comando restituisce la seguente risposta:

```
{
  "evaluationResult": "{\n    \"version\" : \"2017-02-28\",\n    \"operation\" : \"PutItem\",\n    \"key\" : {\n        \"id\" : { \"S\" : \"afcb4c85-49f8-40de-8f2b-248949176456\" }\n    },\n    \"attributeValues\" : {\"firstname\":{\"S\":\"Shaggy\"},\"age\":{\"N\":4}}\n}\n"
}
```

`evaluationResult`Contiene i risultati del test del modello fornito con quello fornito`context`. Puoi anche testare i tuoi modelli utilizzando il AWS SDKs. Ecco un esempio di utilizzo dell' AWS SDK per la versione 2 JavaScript : 

```
const AWS = require('aws-sdk')
const client = new AWS.AppSync({ region: 'us-east-2' })

const template = fs.readFileSync('./request.vtl', 'utf8')
const context = fs.readFileSync('./context.json', 'utf8')

client
  .evaluateMappingTemplate({ template, context })
  .promise()
  .then((data) => console.log(data))
```

Utilizzando l'SDK, puoi incorporare facilmente i test della tua suite di test preferita per convalidare il comportamento del tuo modello. Ti consigliamo di creare test utilizzando [Jest Testing Framework](https://jestjs.io/), ma qualsiasi suite di test funziona. Il seguente frammento mostra un'ipotetica esecuzione di convalida. Nota che ci aspettiamo che la risposta di valutazione sia un codice JSON valido, quindi lo utilizziamo `JSON.parse` per recuperare JSON dalla stringa di risposta:

```
const AWS = require('aws-sdk')
const fs = require('fs')
const client = new AWS.AppSync({ region: 'us-east-2' })

test('request correctly calls DynamoDB', async () => {
  const template = fs.readFileSync('./request.vtl', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateMappingTemplate({ template, context }).promise()
  const result = JSON.parse(response.evaluationResult)
  
  expect(result.key.id.S).toBeDefined()
  expect(result.attributeValues.firstname.S).toEqual(contextJSON.arguments.firstname)
})
```

 Ciò produce il seguente risultato:

```
Ran all test suites.
> jest

PASS ./index.test.js
✓ request correctly calls DynamoDB (543 ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.511 s, estimated 2 s
```

## Eseguire il debug di una query live
<a name="debugging-a-live-query"></a>

Non c'è nulla che possa sostituire un end-to-end test e una registrazione per eseguire il debug di un'applicazione di produzione. AWS AppSync consente di registrare gli errori e i dettagli completi delle richieste utilizzando Amazon CloudWatch. Inoltre, puoi utilizzare la AWS AppSync console per testare le query, le mutazioni e gli abbonamenti GraphQL e trasmettere in live streaming i dati di registro per ogni richiesta nell'editor di query per il debug in tempo reale. Per le sottoscrizioni, i log visualizzano le informazioni relative al tempo della connessione.

A tale scopo, è necessario che Amazon CloudWatch logs sia abilitato in anticipo, come descritto in [Monitoraggio e registrazione](monitoring.md#aws-appsync-monitoring). Successivamente, nella AWS AppSync console, scegli la scheda **Queries** e inserisci una query GraphQL valida. Nella sezione in basso a destra, fai clic e trascina la finestra **Logs per aprire** la visualizzazione dei log. Sulla parte superiore della pagina, scegliere l'icona con la freccia per la riproduzione per eseguire la query GraphQL. Dopo alcuni istati, i log completi per la richiesta e la risposta per l'operazione verranno trasmessi in questa sezione della console, dove potrai visualizzarli.

# Configurazione e utilizzo dei resolver di pipeline in (VTL) AWS AppSync
<a name="pipeline-resolvers"></a>

**Nota**  
Ora supportiamo principalmente il runtime APPSYNC\$1JS e la relativa documentazione. [Prendi in considerazione l'utilizzo del runtime APPSYNC\$1JS e delle relative guide qui.](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html)

AWS AppSync esegue i resolver su un campo GraphQL. In alcuni casi, le applicazioni prevedono il compimento di più operazioni per la risoluzione di un singolo campo GraphQL. Con i resolver a pipeline, gli sviluppatori possono ora comporre operazioni chiamate Funzioni ed eseguirle in sequenza. Questo tipo di resolver torna utile, ad esempio, con applicazioni che prevedono un controllo delle autorizzazioni antecedente al recupero dei dati per un campo.

Un resolver di pipeline è composto da due modelli di mappatura, della fase **antecedente** e **successiva**, e un elenco di funzioni. Ogni funzione dispone di un modello di mappatura delle **richieste** e delle **risposte** che esegue su un'origine dati. Dal momento che delega l'esecuzione a un elenco di funzioni, il resolver di pipeline non prevede il collegamento a un'origine dati. I resolver e le funzioni di unità sono primitive che eseguono operazioni su fonti di dati. Per ulteriori informazioni, consulta la panoramica del [modello di mappatura Resolver](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview).

## Fase 1: Creazione di un risolutore di pipeline
<a name="create-a-pipeline-resolver"></a>

**Nella AWS AppSync console, vai alla pagina Schema.**

Salva lo schema seguente:

```
schema {
    query: Query
    mutation: Mutation
}

type Mutation {
    signUp(input: Signup): User
}

type Query {
    getUser(id: ID!): User
}

input Signup {
    username: String!
    email: String!
}

type User {
    id: ID!
    username: String
    email: AWSEmail
}
```

Bisogna implementare un resolver di pipeline per il campo **signUp (registrazione)** del tipo di **Mutation (Mutazione)**. Nel tipo di **mutazione** sul lato destro, scegli **Allega** accanto al campo di `signUp` mutazione. **Nella pagina di creazione del resolver, fai clic su **Azioni, quindi su Aggiorna runtime**.** **Scegli`Pipeline Resolver`, quindi scegli`VTL`, quindi scegli Aggiorna.** La pagina dovrebbe ora mostrare tre sezioni: un'area di testo **Prima della mappatura del modello**, una sezione **Funzioni** e un'area di testo **Dopo la mappatura del modello**.

Il nostra resolver di pipeline registra un utente convalidandone l'indirizzo e-mail e, successivamente, salvandolo nel sistema. Dobbiamo quindi incapsulare la convalida dell'e-mail in una funzione **validateEmail** e il salvataggio dell'utente in una funzione **saveUser**. Per prima, viene eseguita la funzione **validateEmail**, al termine della quale e solo se appurata la validità dell'e-mail, si può procedere con la **saveUser**.

Il flusso di esecuzione corrisponderà al seguente:

1. Modello di mappatura della richiesta del resolver Mutation.signUp

1. Funzione validateEmail

1. Funzione saveUser

1. Modello di mappatura della risposta del resolver Mutation.signUp

Poiché probabilmente riutilizzeremo la funzione **ValidateEmail** in altri resolver sulla nostra API, vogliamo evitare l'accesso `$ctx.args` perché questi cambieranno da un campo GraphQL all'altro. In alternativa, è possibile avvalersi di `$ctx.stash` per memorizzare l'attributo e-mail dall'argomento del campo di input `signUp(input: Signup)`.

**PRIMA di mappare il modello:**

```
## store email input field into a generic email key
$util.qr($ctx.stash.put("email", $ctx.args.input.email))
{}
```

La console fornisce un modello di mappatura **AFTER** passthrough predefinito che utilizzeremo:

```
$util.toJson($ctx.result)
```

Scegli **Crea** o **Salva** per aggiornare il resolver.

## Fase 2: Creazione di una funzione
<a name="create-a-function"></a>

Dalla pagina Pipeline Resolver, nella sezione **Funzioni**, fai clic su **Aggiungi funzione, quindi su **Crea** nuova funzione**. **È anche possibile creare funzioni senza passare dalla pagina del resolver; per farlo, nella AWS AppSync console, vai alla pagina Funzioni.** Selezionare il pulsante **Create function (Crea funzione)**. Creiamo quindi una funzione che verifichi la validità e la provenienza da un determinato dominio di un indirizzo e-mail. In caso di e-mail non valida, la funzione restituisce un errore. Altrimenti, inoltra qualsiasi input immesso.

Nella pagina della nuova funzione, scegli **Azioni**, quindi **Aggiorna** runtime. Scegli`VTL`, quindi **Aggiorna**. Assicurati di aver creato un'origine dati del tipo **NONE**. Scegli questa fonte di **dati nell'elenco Nome origine dati**. Per **il nome della funzione**, inserisci`validateEmail`. Nell'area del **codice della funzione**, sovrascrivi tutto con questo frammento:

```
#set($valid = $util.matches("^[a-zA-Z0-9_.+-]+@(?:(?:[a-zA-Z0-9-]+\.)?[a-zA-Z]+\.)?(myvaliddomain)\.com", $ctx.stash.email))
#if (!$valid)
    $util.error("$ctx.stash.email is not a valid email.")
#end
{
    "payload": { "email": $util.toJson(${ctx.stash.email}) }
}
```

Incollalo nel modello di mappatura delle risposte:

```
$util.toJson($ctx.result)
```

Controlla le modifiche, quindi scegli **Crea**. A questo punto, la funzione **validateEmail** è stata creata. Ripeti questi passaggi per creare la funzione **SaveUser** con i seguenti modelli di mappatura di richieste e risposte (per semplicità, utilizziamo **una** fonte di dati NONE e facciamo finta che l'utente sia stato salvato nel sistema dopo l'esecuzione della funzione. ): 

Modello di mappatura della richiesta:

```
## $ctx.prev.result contains the signup input values. We could have also
## used $ctx.args.input.
{
    "payload": $util.toJson($ctx.prev.result)
}
```

Modello di mappatura della risposta:

```
## an id is required so let's add a unique random identifier to the output
$util.qr($ctx.result.put("id", $util.autoId()))
$util.toJson($ctx.result)
```

Abbiamo appena creato la nostra funzione **SaveUser**.

## Fase 3: Aggiungere una funzione a un risolutore di pipeline
<a name="adding-a-function-to-a-pipeline-resolver"></a>

Le nostre funzioni avrebbero dovuto essere aggiunte automaticamente al risolutore di pipeline che abbiamo appena creato. Se così non fosse, o se hai creato le funzioni tramite la pagina **Funzioni**, puoi fare clic su **Aggiungi funzione** nella pagina del resolver per allegarle. Aggiungi entrambe le funzioni **ValidateEmail** **e** SaveUser al resolver. la funzione **validateEmail** deve precedere quella **saveUser**. Man mano che aggiungi altre funzioni, puoi utilizzare le opzioni di **spostamento su** e **sposta giù** per riorganizzare l'ordine di esecuzione delle funzioni. Controlla le modifiche, quindi scegli **Salva**.

## Fase 4: Esecuzione di una query
<a name="executing-a-query"></a>

Nella AWS AppSync console, vai alla pagina **Query**. Nell'explorer, assicurati di usare la tua mutazione. Se non lo sei, scegli `Mutation` nell'elenco a discesa, quindi scegli. `+` Inserire la query seguente:

```
mutation {
  signUp(input: {
    email: "nadia@myvaliddomain.com"
    username: "nadia"
  }) {
    id
    email
  }
}
```

Questo dovrebbe restituire qualcosa del tipo:

```
{
  "data": {
    "signUp": {
      "id": "256b6cc2-4694-46f4-a55e-8cb14cc5d7fc",
      "email": "nadia@myvaliddomain.com"
    }
  }
}
```

Abbiamo quindi registrato il nostro utente convalidandone, al contempo, l'e-mail di input tramite un resolver di pipeline. Un tutorial più articolato sui resolver di pipeline è disponibile alla pagina [Tutorial: resolver di pipeline](tutorial-pipeline-resolvers.md#aws-appsync-tutorial-pipeline-resolvers). 

# Utilizzo di un' AWS AppSync API con AWS CDK
<a name="using-your-api"></a>

**Suggerimento**  
Prima di utilizzare il CDK, ti consigliamo di consultare la [documentazione ufficiale del CDK insieme AWS AppSync al riferimento](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) [CDK](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html).  
Ti consigliamo inoltre di assicurarti che le installazioni [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) e [NPM](https://docs.npmjs.com/) funzionino sul tuo sistema.

In questa sezione, creeremo una semplice applicazione CDK 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](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html), [Collegamento di una fonte di dati e Configurazione](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html) dei resolvers (). JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html)

## Configurazione di un progetto CDK
<a name="Setting-up-a-cdk-project"></a>

**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 del CDK. AWS Nella CLI, 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'app CDK con i relativi file di inizializzazione:

![\[Terminal output showing Git repository initialization and npm install completion.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-init-app-example.png)


La struttura del progetto potrebbe essere simile a questa:

![\[Project directory structure showing folders and files for an example CDK app.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-init-directories.png)


Noterai che abbiamo diverse directory importanti:
+ `bin`: Il file bin iniziale creerà l'app. Non ne parleremo 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 CloudFormation quando l'app verrà distribuita. È qui che avverrà la maggior parte della nostra codifica.
+ `node_modules`: Questa directory è creata da NPM e contiene tutte le dipendenze dei pacchetti che sono state installate utilizzando il comando. `npm`

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 risorse per il CDK prima della distribuzione dell'app. [Ulteriori informazioni su questo processo sono disponibili qui.](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html) Per creare un bootstrap, il comando è:

```
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
```

**Suggerimento**  
Questo passaggio richiede diverse autorizzazioni IAM 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:

![\[Terminal output showing successful bootstrapping of an AWS environment.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-init-bootstrap-final.png)


Questa operazione viene eseguita una volta per account per regione, quindi non dovrai farlo spesso. Le risorse principali del bootstrap sono lo CloudFormation stack e il bucket Amazon S3.

Il bucket Amazon S3 viene utilizzato per archiviare file e ruoli IAM che concedono le autorizzazioni necessarie per eseguire le distribuzioni. Le risorse richieste sono definite in uno CloudFormation stack, chiamato stack bootstrap, che di solito viene denominato. `CDKToolkit` Come ogni CloudFormation stack, appare nella CloudFormation console una volta distribuito:

![\[CDKToolkit stack with CREATE_COMPLETE status in CloudFormation console.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-init-bootstrap-cfn-console.png)


Lo stesso si può dire per il bucket:

![\[S3 bucket details showing name, region, access settings, and creation date.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-init-bootstrap-bucket-console.png)


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 CDK - Schema
<a name="implementing-a-cdk-project-schema"></a>

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 nostro`schema.graphql`:

![\[File structure showing a schema folder containing schema.graphql file.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-schema-directory.png)


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 la nostra API GraphQL e collegarla 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 l'URL GraphQL, la chiave API 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:

![\[Deployment output showing ExampleCdkAppStack details, including GraphQL API URL and stack region.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-schema.png)


Sembra che il nostro esempio abbia avuto successo, ma controlliamo la AWS AppSync console solo per confermare:

![\[GraphQL interface showing successful API request with response data displayed.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-schema-result-1.png)


Sembra che la nostra API sia stata creata. Ora controlleremo lo schema allegato all'API:

![\[GraphQL schema defining CreatePostInput, Post type, Mutation, and Query operations.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-schema-result-2.png)


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 CloudFormation stack:

![\[CloudFormation stack showing ExampleCdkAppStack update complete and CDKToolkit creation complete.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-schema-result-3.png)


Quando distribuiamo la nostra app CDK, questa attiva risorse come CloudFormation il bootstrap. Ogni stack all'interno della nostra app viene mappato 1:1 con uno stack. 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 API GraphQL:

![\[Expanded view of post-apis resource showing Schema, DefaultApiKey, and CDKMetadata.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-schema-result-4.png)


## Implementazione di un progetto CDK - Fonte dei dati
<a name="implementing-a-cdk-project-data-source"></a>

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:

![\[DynamoDB console showing ExampleCdkAppStack-poststable as Active with Provisioned capacity.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-ddb-result-1.png)


Il nome dello stack è corretto e il nome della tabella corrisponde al nostro codice. Se controlliamo nuovamente il nostro CloudFormation stack, ora vedremo la nuova tabella:

![\[Expanded view of a logical ID in CloudFormation showing post-apis, posts-table, and CDKMetadata.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-ddb-result-2.png)


## Implementazione di un progetto CDK - Resolver
<a name="implementing-a-cdk-project-resolver"></a>

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 alla nostra API GraphQL:

![\[GraphQL API schema showing mutation and query fields with Pipeline resolvers.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-1.png)


Sembra essere corretta. Nel codice, entrambi questi resolver erano collegati all'API GraphQL che abbiamo creato (indicata dal valore `api` props presente sia nei resolver che nelle funzioni). Nell'API GraphQL, i campi a cui abbiamo collegato i nostri resolver sono stati specificati anche nelle proprietà (definite da `typename` e `fieldname` props in ogni resolver).

Vediamo se il contenuto dei resolver è corretto a partire da: `pipeline-resolver-get-posts`

![\[Code snippet showing request and response functions in a resolver, with an arrow pointing to them.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-2.png)


I gestori prima e dopo corrispondono al nostro valore props. `code` Possiamo anche vedere una funzione chiamata`add_posts_func_1`, che corrisponde al nome della funzione che abbiamo collegato nel resolver.

Diamo un'occhiata al contenuto del codice di quella funzione:

![\[Function code showing request and response methods for a PutItem operation.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-3.png)


Questo corrisponde agli `code` oggetti di scena della `add_posts_func_1` funzione. La nostra query è stata caricata correttamente, quindi controlliamo la query:

![\[Resolver code with request and response functions, and a get_posts_func_1 function listed below.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-4.png)


Anche questi corrispondono al codice. Se osserviamo`get_posts_func_1`:

![\[Code snippet showing two exported functions: request returning 'Scan' operation and response returning items.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-5.png)


Sembra che tutto sia a posto. Per confermarlo dal punto di vista dei metadati, possiamo ricontrollare il nostro stack: CloudFormation 

![\[List of logical IDs for AWS resources including API, table, functions, and pipelines.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-6.png)


Ora, dobbiamo testare questo codice eseguendo alcune richieste.

## Implementazione di un progetto CDK - Richieste
<a name="implementing-a-cdk-project-requests"></a>

Per testare la nostra app nella AWS AppSync console, abbiamo effettuato una query e una mutazione:

![\[GraphQL code snippet showing a query to get post details and a mutation to create a post.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-request-1.png)


`MyMutation`contiene un'`createPost`operazione con gli argomenti `1970-01-01T12:30:00.000Z` e`first 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:

![\[DynamoDB table entry showing id, date, and title fields for a single item.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cdk-code-request-2.png)


Tornando alla AWS AppSync console, se eseguiamo la query per recuperarlo`Post`, otteniamo il seguente risultato:

```
{
  "data": {
    "getPost": [
      {
        "id": "9f62c4dd-49d5-48d5-b835-143284c72fe0",
        "date": "1970-01-01T12:30:00.000Z",
        "title": "first post"
      }
    ]
  }
}
```

# Utilizzo di abbonamenti per applicazioni di dati in tempo reale in AWS AppSync
<a name="aws-appsync-real-time-data"></a>

**Importante**  
A partire dal 13 marzo 2025, puoi creare un' PubSub API in tempo reale basata su Events. WebSockets AWS AppSync Per ulteriori informazioni, consulta [Pubblicare eventi tramite WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) nella *AWS AppSync Events Developer Guide*.

AWS AppSyncconsente di utilizzare gli abbonamenti per implementare aggiornamenti in tempo reale delle applicazioni, notifiche push, ecc. Quando i client richiamano le operazioni di sottoscrizione GraphQL, viene stabilita e gestita automaticamente una connessione WebSocket sicura da. AWS AppSync Le applicazioni possono quindi distribuire i dati in tempo reale da una fonte di dati agli abbonati, gestendo al contempo AWS AppSync i requisiti di connessione e scalabilità dell'applicazione. Le seguenti sezioni ti mostreranno come funzionano gli abbonamenti. AWS AppSync

## Direttive di sottoscrizione allo schema GraphQL
<a name="graphql-schema-subscription-directives"></a>

Le sottoscrizioni in AWS AppSync vengono richiamate come risposta a una mutazione. Ciò significa che puoi creare qualsiasi fonte di dati in tempo AWS AppSync reale specificando una direttiva dello schema GraphQL su una mutazione.

Le librerie AWS Amplify client gestiscono automaticamente la gestione delle connessioni in abbonamento. Le librerie utilizzano pure WebSockets come protocollo di rete tra il client e il servizio.

**Nota**  
Per controllare l'autorizzazione al momento della connessione a un abbonamento, puoi utilizzare AWS Identity and Access Management (IAM) AWS Lambda, i pool di identità di Amazon Cognito o i pool di utenti Amazon Cognito per l'autorizzazione a livello di campo. Per controlli di accesso dettagliati sugli abbonamenti, puoi collegare resolver ai campi di abbonamento ed eseguire la logica utilizzando l'identità del chiamante e le fonti di dati. AWS AppSync Per ulteriori informazioni, consulta [Configurazione dell'autorizzazione e dell'autenticazione per proteggere GraphQL APIs](security-authz.md).

Le sottoscrizioni vengono attivate da mutazioni e il set di selezioni delle mutazioni viene inviato ai sottoscrittori.

L'esempio seguente mostra come usare sottoscrizioni GraphQL. Non specifica un'origine dati perché l'origine dati potrebbe essere Lambda, Amazon DynamoDB o Amazon Service. OpenSearch 

Per iniziare con gli abbonamenti, devi aggiungere un punto di ingresso dell'abbonamento allo schema come segue:

```
schema {
    query: Query
    mutation: Mutation
    subscription: Subscription
}
```

Supponiamo di avere un sito di post di blog e di voler sottoscrivere nuovi blog e le modifiche a blog esistenti. A questo scopo, aggiungere la definizione `Subscription` seguente allo schema:

```
type Subscription {
    addedPost: Post
    updatedPost: Post
    deletedPost: Post
}
```

Supponiamo inoltre di avere le mutazioni seguenti:

```
type Mutation {
    addPost(id: ID! author: String! title: String content: String url: String): Post!
    updatePost(id: ID! author: String! title: String content: String url: String ups: Int! downs: Int! expectedVersion: Int!): Post!
    deletePost(id: ID!): Post!
}
```

Puoi impostare questi campi come elementi in tempo reale aggiungendo una direttiva `@aws_subscribe(mutations: ["mutation_field_1", "mutation_field_2"])` per ognuna delle sottoscrizioni per cui vuoi ricevere notifiche, in questo modo:

```
type Subscription {
    addedPost: Post
    @aws_subscribe(mutations: ["addPost"])
    updatedPost: Post
    @aws_subscribe(mutations: ["updatePost"])
    deletedPost: Post
    @aws_subscribe(mutations: ["deletePost"])
}
```

Poiché `@aws_subscribe(mutations: ["",..,""])` richiede una serie di input di mutazione, è possibile specificare più mutazioni, che avviano una sottoscrizione. Se esegui la sottoscrizione da un client, la query GraphQL può essere simile alla seguente:

```
subscription NewPostSub {
    addedPost {
        __typename
        version
        title
        content
        author
        url
    }
}
```

Questa richiesta di sottoscrizione è necessaria per le connessioni e gli strumenti dei client.

Con il WebSockets client puro, il filtraggio del set di selezione viene eseguito per client, poiché ogni client può definire il proprio set di selezione. In questo caso, il set di selezione della sottoscrizione deve essere un sottoinsieme del set di selezione delle mutazioni. Ad esempio, un abbonamento `addedPost{author title}` collegato alla mutazione `addPost(...){id author title url version}` riceve solo l'autore e il titolo del post. Non riceve gli altri campi. Tuttavia, se per la mutazione manca l'autore nel set di selezione, il sottoscrittore ottiene un valore `null` per il campo autore (o un errore nel caso in cui il campo autore sia definito come richiesto/non-null nello schema).

Il set di selezione dell'abbonamento è essenziale quando si utilizza pure WebSockets. Se un campo non è definito in modo esplicito nell'abbonamento, AWS AppSync non restituisce il campo.

Nell'esempio precedente, le sottoscrizioni non dispongono di argomenti. Supponiamo che lo schema sia simile al seguente:

```
type Subscription {
    updatedPost(id:ID! author:String): Post
    @aws_subscribe(mutations: ["updatePost"])
}
```

In questo caso, il client definisce una sottoscrizione come segue:

```
subscription UpdatedPostSub {
    updatedPost(id:"XYZ", author:"ABC") {
        title
        content
    }
}
```

Il tipo restituito di un campo `subscription` nello schema deve corrispondere al tipo restituito del campo della mutazione corrispondente. Questo è stato mostrato nell'esempio precedente, in quanto sia `addPost` sia `addedPost` hanno restituito `Post` come tipo.

Per configurare gli abbonamenti sul client, consulta. [Creazione di un'applicazione client utilizzando il client Amplify](building-a-client-app.md)

## Utilizzo degli argomenti di sottoscrizione
<a name="using-subscription-arguments"></a>

Una parte importante dell'utilizzo degli abbonamenti GraphQL è capire quando e come utilizzare gli argomenti. È possibile apportare lievi modifiche per modificare come e quando notificare ai client le mutazioni che si sono verificate. A tale scopo, consultate lo schema di esempio tratto dal capitolo quickstart, che crea «Todos». Per questo schema di esempio, vengono definite le seguenti mutazioni:

```
type Mutation {
    createTodo(input: CreateTodoInput!): Todo
    updateTodo(input: UpdateTodoInput!): Todo
    deleteTodo(input: DeleteTodoInput!): Todo
}
```

Nell'esempio predefinito, i client possono sottoscrivere gli aggiornamenti di any `Todo` utilizzando il comando `onUpdateTodo` `subscription` senza argomenti:

```
subscription OnUpdateTodo {
  onUpdateTodo {
    description
    id
    name
    when
  }
}
```

Puoi filtrare i tuoi `subscription` utilizzando i relativi argomenti. Ad esempio, per attivare a solo `subscription` quando `ID` viene aggiornato un `todo` con uno specifico, specifica il `ID` valore:

```
subscription OnUpdateTodo {
  onUpdateTodo(id: "a-todo-id") {
    description
    id
    name
    when
  }
}
```

Puoi anche passare più argomenti. Ad esempio, quanto segue `subscription` dimostra come ricevere notifiche di eventuali `Todo` aggiornamenti in un luogo e in un'ora specifici:

```
subscription todosAtHome {
  onUpdateTodo(when: "tomorrow", where: "at home") {
    description
    id
    name
    when
    where
  }
}
```

Nota che tutti gli argomenti sono opzionali. Se non specifichi alcun argomento nel tuo`subscription`, sarai iscritto a tutti `Todo` gli aggiornamenti che avvengono nella tua applicazione. Tuttavia, puoi aggiornare la definizione `subscription` del campo per richiedere l'`ID`argomento. Ciò forzerebbe la risposta di uno specifico `todo` anziché di tutti i `todo` s:

```
onUpdateTodo(
  id: ID!,
  name: String,
  when: String,
  where: String,
  description: String
): Todo
```

### Il valore null dell'argomento ha un significato
<a name="argument-null-value-has-meaning"></a>

Quando si effettua una query di sottoscrizione AWS AppSync, un valore di `null` argomento filtrerà i risultati in modo diverso rispetto all'omissione completa dell'argomento.

Torniamo all'esempio di API todos in cui potremmo creare todos. Vedi lo schema di esempio tratto dal capitolo quickstart.

Modifichiamo il nostro schema per includere un nuovo `owner` campo, sul `Todo` tipo, che descriva chi è il proprietario. Il `owner` campo non è obbligatorio e può essere solo impostato`UpdateTodoInput`. Vedi la seguente versione semplificata dello schema:

```
type Todo {
  id: ID!
  name: String!
  when: String!
  where: String!
  description: String!
  owner: String
}

input CreateTodoInput {
  name: String!
  when: String!
  where: String!
  description: String!
}

input UpdateTodoInput {
  id: ID!
  name: String
  when: String
  where: String
  description: String
  owner: String
}

type Subscription {
    onUpdateTodo(
        id: ID,
        name: String,
        when: String,
        where: String,
        description: String
    ): Todo @aws_subscribe(mutations: ["updateTodo"])
}
```

Il seguente abbonamento restituisce tutti gli `Todo` aggiornamenti:

```
subscription MySubscription {
  onUpdateTodo {
    description
    id
    name
    when
    where
  }
}
```

Se modifichi la sottoscrizione precedente per aggiungere l'argomento del campo`owner: null`, ora stai facendo una domanda diversa. Questo abbonamento ora consente al cliente di ricevere una notifica di tutti gli `Todo` aggiornamenti per i quali non è stato fornito alcun proprietario.

```
subscription MySubscription {
  onUpdateTodo(owner: null) {
    description
    id
    name
    when
    where
  }
}
```

**Nota**  
**A partire dal 1° gennaio 2022, MQTT over non WebSockets è più disponibile come protocollo per gli abbonamenti GraphQL in. AWS AppSync APIs Pure WebSockets è l'unico protocollo supportato in. AWS AppSync**  
I client basati sull' AWS AppSync SDK o sulle librerie Amplify, rilasciati dopo novembre 2019, utilizzano automaticamente pure per impostazione predefinita. WebSockets L'aggiornamento dei client alla versione più recente consente loro di utilizzare il motore puro. AWS AppSync WebSockets   
Pure offre una dimensione del payload più grande (240 KB), una più ampia varietà di opzioni client e metriche WebSockets migliorate. CloudWatch Per ulteriori informazioni sull'utilizzo dei WebSocket client pure, consulta. [ WebSocket Creazione di un client in tempo reale in AWS AppSync](real-time-websocket-client.md)

# Creazione di sistemi generici con pub/sub APIs tecnologia serverless in WebSockets AWS AppSync
<a name="aws-appsync-real-time-create-generic-api-serverless-websocket"></a>

**Importante**  
A partire dal 13 marzo 2025, puoi creare un' PubSub API in tempo reale basata su WebSockets AWS AppSync Events. Per ulteriori informazioni, consulta [Pubblicare eventi tramite WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) nella *AWS AppSync Events Developer Guide*.

Alcune applicazioni richiedono solo che WebSocket APIs i clienti ascoltino un canale o un argomento specifico. I dati JSON generici senza una forma specifica o requisiti fortemente tipizzati possono essere inviati ai clienti che ascoltano uno di questi canali secondo uno schema di pubblicazione (pub/sub) puro e semplice.

Utilizzalo AWS AppSync per implementare soluzioni semplici pub/sub WebSocket APIs con poca o nessuna conoscenza di GraphQL in pochi minuti generando automaticamente codice GraphQL sia sul backend dell'API che sul lato client.

## Crea e configura pub-sub APIs
<a name="aws-appsync-real-time-enhanced-filtering-using-pub-sub-apis"></a>

Per iniziare, procedi come segue: 

1. Accedi a Console di gestione AWS e apri la [AppSync console](https://console.aws.amazon.com/appsync/).

   1. Nel **pannello di controllo**, scegliere **Create API (Crea API)**.

1. Nella schermata successiva, scegli **Crea un'API in tempo reale**, quindi scegli **Avanti**.

1. Inserisci un nome descrittivo per la tua pub/sub API.

1. Puoi abilitare le funzionalità [API private](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html), ma per ora ti consigliamo di tenerla disattivata. Scegli **Next (Successivo)**.

1. Puoi scegliere di generare automaticamente un' pub/sub API funzionante utilizzando WebSockets. Ti consigliamo di tenere disattivata questa funzionalità anche per ora. Scegli **Next (Successivo)**.

1. Scegli **Crea API** e attendi un paio di minuti. Nel tuo account verrà creata una nuova API AWS AppSync pub/sub preconfigurata. AWS 

L'API utilizza i AWS AppSync resolver locali integrati (per ulteriori informazioni sull'utilizzo dei [resolver locali, consulta Tutorial: Local Resolvers nella *AWS AppSync Developer Guide*) per gestire più pub/sub canali e WebSocket connessioni temporanee, che distribuiscono e filtrano automaticamente i dati ai client abbonati solo in base](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-local-resolvers-js.html) al nome del canale. Le chiamate API sono autorizzate con una chiave API.

Dopo l'implementazione dell'API, ti vengono presentati un paio di passaggi aggiuntivi per generare il codice client e integrarlo con l'applicazione client. Per un esempio su come integrare rapidamente un client, questa guida utilizzerà una semplice applicazione web React.

1. Inizia creando un'app React standard usando [NPM](https://www.npmjs.com/get-npm) sul tuo computer locale:

   ```
   $ npx create-react-app mypubsub-app 
   $ cd mypubsub-app
   ```
**Nota**  
Questo esempio utilizza le librerie [Amplify](https://docs.amplify.aws/lib/) per connettere i client all'API di backend. Tuttavia non è necessario creare un progetto Amplify CLI localmente. Sebbene React sia il client preferito in questo esempio, le librerie Amplify supportano anche i client iOS, Android e Flutter, fornendo le stesse funzionalità in questi diversi runtime. [I client Amplify supportati forniscono semplici astrazioni per interagire con i backend dell'API AWS AppSync GraphQL con poche righe di codice, incluse WebSocket funzionalità integrate completamente compatibili con il protocollo in tempo reale:AWS AppSync WebSocket ](https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html)  

   ```
   $ npm install @aws-amplify/api
   ```

1. Nella AWS AppSync console, seleziona **JavaScript**, quindi **Scarica per scaricare** un singolo file con i dettagli di configurazione dell'API e il codice operativo GraphQL generato.

1. Copia il file scaricato `/src` nella cartella del tuo progetto React.

1. Quindi, sostituisci il contenuto del `src/App.js` file boilerplate esistente con il codice client di esempio disponibile nella console.

1. Utilizzate il seguente comando per avviare l'applicazione localmente:

   ```
   $ npm start
   ```

1. Per testare l'invio e la ricezione di dati in tempo reale, apri due finestre del browser e accedi*localhost:3000*. L'applicazione di esempio è configurata per inviare dati JSON generici a un canale codificato denominato. *robots*

1.  **In una delle finestre del browser, inserisci il seguente blob JSON nella casella di testo, quindi fai clic su Invia:** 

   ```
   {
     "robot":"r2d2",
     "planet": "tatooine"
   }
   ```

Entrambe le istanze del browser sono iscritte al *robots* canale e ricevono i dati pubblicati in tempo reale, visualizzati nella parte inferiore dell'applicazione web:

![\[Esempio di app React per API pub/sub\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/pub-sub-react.png)


Tutto il codice API GraphQL necessario, inclusi lo schema, i resolver e le operazioni, viene generato automaticamente per consentire un caso d'uso generico. pub/sub Sul backend, i dati vengono pubblicati sull'endpoint in tempo reale AWS AppSync dell'utente con una mutazione GraphQL come la seguente:

```
mutation PublishData {
    publish(data: "{\"msg\": \"hello world!\"}", name: "channel") {
        data
        name
    }
}
```

Gli abbonati accedono ai dati pubblicati inviati al canale temporaneo specifico con un abbonamento GraphQL correlato:

```
subscription SubscribeToData {
    subscribe(name:"channel") {
        name
        data
    }
}
```

## Implementazione di pub-sub APIs nelle applicazioni esistenti
<a name="aws-appsync-real-time-enhanced-filtering-existing-apps"></a>

Nel caso in cui sia sufficiente implementare una funzionalità in tempo reale in un'applicazione esistente, questa configurazione pub/sub API generica può essere facilmente integrata in qualsiasi applicazione o tecnologia API. Sebbene vi siano vantaggi nell'utilizzare un singolo endpoint API per accedere, manipolare e combinare in modo sicuro i dati provenienti da una o più fonti di dati in una singola chiamata di rete con GraphQL, non è necessario convertire o ricostruire da zero un'applicazione esistente basata su REST per sfruttare le funzionalità in tempo reale di GraphQL. AWS AppSync Ad esempio, potresti avere un carico di lavoro CRUD esistente in un endpoint API separato con i client che inviano e ricevono messaggi o eventi dall'applicazione esistente all' pub/sub API generica solo in tempo reale e per pub/sub scopi. 

# Definizione di filtri di sottoscrizione avanzati in AWS AppSync
<a name="aws-appsync-real-time-enhanced-filtering"></a>

**Importante**  
A partire dal 13 marzo 2025, puoi creare un' PubSub API in tempo reale basata su WebSockets AWS AppSync Events. Per ulteriori informazioni, consulta [Pubblicare eventi tramite WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) nella *AWS AppSync Events Developer Guide*.

Inoltre AWS AppSync, puoi definire e abilitare la logica aziendale per il filtraggio dei dati sul backend direttamente nei resolver di sottoscrizione dell'API GraphQL utilizzando filtri che supportano operatori logici aggiuntivi. È possibile configurare questi filtri, a differenza degli argomenti di sottoscrizione definiti nella query di sottoscrizione nel client. Per ulteriori informazioni sull'utilizzo degli argomenti di sottoscrizione, vedere[Utilizzo degli argomenti di sottoscrizione](aws-appsync-real-time-data.md#using-subscription-arguments). Per un elenco degli operatori, vedere[AWS AppSync riferimento all'utilità del modello di mappatura del resolver](resolver-util-reference.md).

Ai fini di questo documento, suddividiamo il filtraggio dei dati in tempo reale nelle seguenti categorie:
+ **Filtraggio di base**: filtraggio basato su argomenti definiti dal client nella query di sottoscrizione.
+ **Filtraggio avanzato: filtraggio** basato sulla logica definita centralmente nel backend del servizio. AWS AppSync 

Le sezioni seguenti spiegano come configurare i filtri di abbonamento avanzati e ne mostrano l'uso pratico.

## Definizione degli abbonamenti nello schema GraphQL
<a name="aws-appsync-real-time-enhanced-filtering-using-subscription-filters"></a>

Per utilizzare i filtri di sottoscrizione avanzati, è necessario definire l'abbonamento nello schema GraphQL, quindi definire il filtro avanzato utilizzando un'estensione di filtro. Per illustrare come funziona il filtraggio avanzato degli abbonamenti AWS AppSync, usa il seguente schema GraphQL, che definisce un'API del sistema di gestione dei ticket, come esempio:

```
type Ticket {
	id: ID
	createdAt: AWSDateTime
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
	status: String
	
}

type Mutation {
	createTicket(input: TicketInput): Ticket
}

type Query {
	getTicket(id: ID!): Ticket
}

type Subscription {
	onSpecialTicketCreated: Ticket @aws_subscribe(mutations: ["createTicket"])
	onGroupTicketCreated(group: String!): Ticket @aws_subscribe(mutations: ["createTicket"])
}



enum Priority {
	none
	lowest
	low
	medium
	high
	highest
}

input TicketInput {
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
```

Supponete di creare una fonte di `NONE` dati per la vostra API, quindi di collegare un resolver alla mutazione utilizzando questa fonte di dati. `createTicket` I tuoi gestori potrebbero avere questo aspetto:

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
	return {
		payload: {
			id: util.autoId(),
			createdAt: util.time.nowISO8601(),
			status: 'pending',
			...ctx.args.input,
		},
	};
}

export function response(ctx) {
	return ctx.result;
}
```

**Nota**  
I filtri avanzati sono abilitati nel gestore del resolver GraphQL in un determinato abbonamento. [Per ulteriori informazioni, consulta Resolver reference.](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)

Per implementare il comportamento del filtro avanzato, è necessario utilizzare la `extensions.setSubscriptionFilter()` funzione per definire un'espressione di filtro valutata rispetto ai dati pubblicati da una mutazione GraphQL che potrebbe interessare i client sottoscritti. [Per ulteriori informazioni sulle estensioni di filtraggio, consulta Estensioni.](https://docs.aws.amazon.com//appsync/latest/devguide/extensions-js.html)

La sezione seguente spiega come utilizzare le estensioni di filtraggio per implementare filtri avanzati.

## Creazione di filtri di abbonamento avanzati utilizzando estensioni di filtraggio
<a name="aws-appsync-real-time-enhanced-filtering-defining-filters"></a>

I filtri avanzati sono scritti in JSON nel gestore delle risposte dei resolver dell'abbonamento. I filtri possono essere raggruppati in un elenco chiamato a. `filterGroup` I filtri vengono definiti utilizzando almeno una regola, ciascuna con campi, operatori e valori. Definiamo un nuovo resolver `onSpecialTicketCreated` che imposta un filtro avanzato. È possibile configurare più regole in un filtro che vengono valutate utilizzando la logica AND, mentre più filtri in un gruppo di filtri vengono valutati utilizzando la logica OR:

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = {
		or: [
			{ severity: { ge: 7 }, priority: { in: ['high', 'medium'] } },
			{ category: { eq: 'security' }, group: { in: ['admin', 'operators'] } },
		],
	};
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));

  // important: return null in the response
	return null;
}
```

In base ai filtri definiti nell'esempio precedente, i ticket importanti vengono automaticamente inviati ai client API sottoscritti se viene creato un ticket con:
+ `priority`livello o `high` `medium`

  AND 
+ `severity`livello maggiore o uguale a `7` (`ge`)

O 
+ `classification`biglietto impostato su `Security` 

  AND 
+ `group`assegnazione impostata su o `admin` `operators`

![\[Esempio che mostra una query di filtraggio dei ticket\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/aws-priority-example.png)


I filtri definiti nel resolver di sottoscrizione (filtro avanzato) hanno la precedenza sui filtri basati solo sugli argomenti di sottoscrizione (filtro di base). [Per ulteriori informazioni sull'utilizzo degli argomenti di sottoscrizione, vedere Utilizzo degli argomenti di sottoscrizione).](https://docs.aws.amazon.com//appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments)

Se un argomento è definito e richiesto nello schema GraphQL dell'abbonamento, il filtraggio basato sull'argomento specificato avviene solo se l'argomento è definito come regola nel metodo del resolver. `extensions.setSubscriptionFilter()` Tuttavia, se non sono presenti metodi di `extensions` filtraggio nel resolver di sottoscrizione, gli argomenti definiti nel client vengono utilizzati solo per il filtraggio di base. Non è possibile utilizzare contemporaneamente il filtro di base e il filtro avanzato.

Puoi utilizzare la [`context`variabile](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) nella logica di estensione del filtro dell'abbonamento per accedere alle informazioni contestuali sulla richiesta. Ad esempio, quando utilizzi gli autorizzatori personalizzati Amazon Cognito User Pools, OIDC o Lambda per l'autorizzazione, puoi recuperare informazioni sui tuoi utenti nel momento in cui viene stabilito l'abbonamento. `context.identity` Puoi utilizzare queste informazioni per stabilire filtri in base all'identità degli utenti.

Supponiamo ora di voler implementare il comportamento di filtro avanzato per`onGroupTicketCreated`. L'`onGroupTicketCreated`abbonamento richiede un `group` nome obbligatorio come argomento. Una volta creati, ai ticket viene assegnato automaticamente uno `pending` stato. Puoi impostare un filtro di abbonamento per ricevere solo i biglietti appena creati che appartengono al gruppo fornito:

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = { group: { eq: ctx.args.group }, status: { eq: 'pending' } };
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));

	return null;
}
```

Quando i dati vengono pubblicati utilizzando una mutazione come nell'esempio seguente:

```
mutation CreateTicket {
  createTicket(input: {priority: medium, severity: 2, group: "aws"}) {
    id
    priority
    severity
    status
    group
    createdAt
  }
}
```

I clienti abbonati attendono che i dati vengano trasmessi automaticamente non WebSockets appena viene creato un ticket con la mutazione: `createTicket`

```
subscription OnGroup {
  onGroupTicketCreated(group: "aws") {
    category
    status
    severity
    priority
    id
    group
    createdAt
    content
  }
}
```

I client possono essere sottoscritti senza argomenti perché la logica di filtraggio è implementata nel AWS AppSync servizio con un filtraggio avanzato, che semplifica il codice client. I client ricevono i dati solo se vengono soddisfatti i criteri di filtro definiti.

## Definizione di filtri avanzati per i campi dello schema annidati
<a name="aws-appsync-real-time-enhanced-filters-nested-schema-fields.title"></a>

È possibile utilizzare il filtro di sottoscrizione avanzato per filtrare i campi dello schema annidati. Supponiamo di aver modificato lo schema della sezione precedente per includere i tipi di posizione e indirizzo:

```
type Ticket {
	id: ID
	createdAt: AWSDateTime
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
	status: String
	location: ProblemLocation
}

type Mutation {
	createTicket(input: TicketInput): Ticket
}

type Query {
	getTicket(id: ID!): Ticket
}

type Subscription {
	onSpecialTicketCreated: Ticket @aws_subscribe(mutations: ["createTicket"])
	onGroupTicketCreated(group: String!): Ticket @aws_subscribe(mutations: ["createTicket"])
}

type ProblemLocation {
	address: Address
}

type Address {
	country: String
}

enum Priority {
	none
	lowest
	low
	medium
	high
	highest
}

input TicketInput {
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
	location: AWSJSON
```

Con questo schema, è possibile utilizzare un `.` separatore per rappresentare la nidificazione. L'esempio seguente aggiunge una regola di filtro per un campo dello schema annidato in. `location.address.country` L'abbonamento verrà attivato se l'indirizzo del ticket è impostato su: `USA`

```
import { util, extensions } from '@aws-appsync/utils';

export const request = (ctx) => ({ payload: null });

export function response(ctx) {
	const filter = {
		or: [
			{ severity: { ge: 7 }, priority: { in: ['high', 'medium'] } },
			{ category: { eq: 'security' }, group: { in: ['admin', 'operators'] } },
			{ 'location.address.country': { eq: 'USA' } },
		],
	};
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));
	return null;
}
```

Nell'esempio precedente, `location` rappresenta il livello di nidificazione uno, `address` rappresenta il livello di nidificazione due e `country` rappresenta il livello di nidificazione tre, tutti separati dal separatore. `.`

Puoi testare questo abbonamento usando la mutazione: `createTicket`

```
mutation CreateTicketInUSA {
  createTicket(input: {location: "{\"address\":{\"country\":\"USA\"}}"}) {
    category
    content
    createdAt
    group
    id
    location {
      address {
        country
      }
    }
    priority
    severity
    status
  }
}
```

## Definizione di filtri avanzati dal client
<a name="aws-appsync-real-time-enhanced-filtering-defining-from-client"></a>

È possibile utilizzare il filtraggio di base in GraphQL [con](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments) argomenti di sottoscrizione. Il client che effettua la chiamata nella query di sottoscrizione definisce i valori degli argomenti. Quando i filtri avanzati sono abilitati in un resolver di AWS AppSync sottoscrizione con il `extensions` filtro, i filtri di backend definiti nel resolver hanno la precedenza e la priorità.

Configura filtri avanzati dinamici e definiti dal client utilizzando un argomento nella sottoscrizione. `filter` Quando configuri questi filtri, devi aggiornare lo schema GraphQL in modo che rifletta il nuovo argomento:

```
...
type Subscription {
    onSpecialTicketCreated(filter: String): Ticket
        @aws_subscribe(mutations: ["createTicket"])
}
...
```

Il client può quindi inviare una richiesta di sottoscrizione come nell'esempio seguente:

```
subscription onSpecialTicketCreated($filter: String) {
     onSpecialTicketCreated(filter: $filter) {
        id
        group
        description
        priority
        severity
     }
 }
```

È possibile configurare la variabile di query come nell'esempio seguente:

```
{"filter" : "{\"severity\":{\"le\":2}}"}
```

L'utilità `util.transform.toSubscriptionFilter()` resolver può essere implementata nel modello di mappatura delle risposte all'abbonamento per applicare il filtro definito nell'argomento dell'abbonamento per ogni client:

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = ctx.args.filter;
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));
	return null;
}
```

Con questa strategia, i clienti possono definire i propri filtri che utilizzano una logica di filtraggio avanzata e operatori aggiuntivi. I filtri vengono assegnati quando un determinato client richiama la query di sottoscrizione in una connessione sicura. WebSocket [Per ulteriori informazioni sull'utilità di trasformazione per un filtraggio avanzato, incluso il formato del payload della variabile di `filter` query, consulta la panoramica sui resolver. JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)

## Restrizioni di filtraggio avanzate aggiuntive
<a name="aws-appsync-real-time-enhanced-filtering-additional-restrictions"></a>

Di seguito sono riportati diversi casi d'uso in cui vengono applicate restrizioni aggiuntive ai filtri avanzati:
+ I filtri avanzati non supportano il filtraggio per gli elenchi di oggetti di primo livello. In questo caso d'uso, i dati pubblicati relativi alla mutazione verranno ignorati per gli abbonamenti avanzati.
+ AWS AppSync supporta fino a cinque livelli di nidificazione. I filtri sui campi dello schema che hanno superato il quinto livello di nidificazione verranno ignorati. Prendi la risposta GraphQL qui sotto. Il `continent` field in ingresso `venue.address.country.metadata.continent` è consentito perché si tratta di un nido di livello cinque. Tuttavia, `financial` `venue.address.country.metadata.capital.financial` è un nido di livello sei, quindi il filtro non funzionerà:

  ```
  {
      "data": {
          "onCreateFilterEvent": {
              "venue": {
                  "address": {
                      "country": {
                          "metadata": {
                              "capital": {
                                  "financial": "New York"
                              },
                              "continent" : "North America"
                          }
                      },
                      "state": "WA"
                  },
                  "builtYear": 2023
              },
              "private": false,
          }
      }
  }
  ```

# Annullamento dell'iscrizione alle WebSocket connessioni utilizzando i filtri in AWS AppSync
<a name="aws-appsync-real-time-invalidation"></a>

**Importante**  
A partire dal 13 marzo 2025, puoi creare un' PubSub API in tempo reale basata su WebSockets AWS AppSync Events. Per ulteriori informazioni, consulta [Pubblicare eventi tramite WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) nella *AWS AppSync Events Developer Guide*.

In AWS AppSync, puoi annullare forzatamente l'iscrizione e chiudere (invalidare) una WebSocket connessione da un client connesso in base a una logica di filtro specifica. Ciò è utile in scenari relativi all'autorizzazione, ad esempio quando si rimuove un utente da un gruppo.

L'invalidazione dell'abbonamento si verifica in risposta a un payload definito in una mutazione. Ti consigliamo di considerare le mutazioni utilizzate per invalidare le connessioni di sottoscrizione come operazioni amministrative nell'API e di definire di conseguenza le autorizzazioni limitandone l'uso a un utente amministratore, un gruppo o un servizio di backend. Ad esempio, utilizzando direttive di autorizzazione dello schema come o. `@aws_auth(cognito_groups: ["Administrators"])` `@aws_iam` Per ulteriori informazioni, vedere [Utilizzo di modalità di autorizzazione aggiuntive](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#using-additional-authorization-modes).

I filtri di invalidazione utilizzano la stessa sintassi e logica dei filtri di sottoscrizione [avanzati](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html). Definite questi filtri utilizzando le seguenti utilità:
+ `extensions.invalidateSubscriptions()`— Definito nel gestore di risposte del resolver GraphQL per una mutazione.
+ `extensions.setSubscriptionInvalidationFilter()`— Definito nel gestore delle risposte del resolver GraphQL degli abbonamenti collegati alla mutazione.

[Per ulteriori informazioni sulle estensioni di filtro di invalidazione, consulta la panoramica dei resolver. JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)

## Utilizzo dell'invalidazione dell'abbonamento
<a name="aws-appsync-real-time-invalidation-using-invalidations"></a>

Per vedere come funziona l'invalidazione dell'abbonamento AWS AppSync, usa il seguente schema GraphQL:

```
type User {
  userId: ID!
  groupId: ID!
}
    
type Group {
  groupId: ID!
  name: String!
  members: [ID!]!
}

type GroupMessage {
  userId: ID!
  groupId: ID!
  message: String!
}

type Mutation {
    createGroupMessage(userId: ID!, groupId : ID!, message: String!): GroupMessage
    removeUserFromGroup(userId: ID!, groupId : ID!) : User @aws_iam
}

type Subscription {
    onGroupMessageCreated(userId: ID!, groupId : ID!): GroupMessage
        @aws_subscribe(mutations: ["createGroupMessage"])
}

type Query {
	none: String
}
```

Definisci un filtro di invalidazione nel codice del mutation resolver: `removeUserFromGroup`

```
import { extensions } from '@aws-appsync/utils';

export function request(ctx) {
	return { payload: null };
}

export function response(ctx) {
	const { userId, groupId } = ctx.args;
	extensions.invalidateSubscriptions({
		subscriptionField: 'onGroupMessageCreated',
		payload: { userId, groupId },
	});
	return { userId, groupId };
}
```

Quando viene richiamata la mutazione, i dati definiti nell'`payload`oggetto vengono utilizzati per annullare l'iscrizione definita in. `subscriptionField` Un filtro di invalidazione è inoltre definito nel modello di mappatura delle risposte dell'`onGroupMessageCreated`abbonamento. 

Se il `extensions.invalidateSubscriptions()` payload contiene un ID che corrisponde a quello del IDs client sottoscritto come definito nel filtro, l'abbonamento corrispondente viene annullato. Inoltre, la connessione è chiusa. WebSocket Definisci il codice del resolver di sottoscrizione per l'`onGroupMessageCreated`abbonamento:

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = { groupId: { eq: ctx.args.groupId } };
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));

	const invalidation = { groupId: { eq: ctx.args.groupId }, userId: { eq: ctx.args.userId } };
	extensions.setSubscriptionInvalidationFilter(util.transform.toSubscriptionFilter(invalidation));

	return null;
}
```

Tieni presente che il gestore della risposta alla sottoscrizione può avere sia filtri di sottoscrizione che filtri di invalidazione definiti contemporaneamente.

Ad  esempio, supponiamo che il client A iscriva un nuovo utente con l'ID `user-1` al gruppo con l'ID `group-1` utilizzando la seguente richiesta di iscrizione:

```
onGroupMessageCreated(userId : "user-1", groupId: :"group-1"){...}
```

AWS AppSync esegue il resolver di sottoscrizione, che genera filtri di sottoscrizione e invalidazione come definito nel precedente modello di mappatura delle risposte. `onGroupMessageCreated` Per il client A, i filtri di sottoscrizione consentono l'invio dei dati solo a`group-1`, mentre i filtri di invalidazione sono definiti per entrambi e. `user-1` `group-1`

Supponiamo ora che il client B sottoscriva un utente con l'ID `user-2` a un gruppo con l'ID `group-2` utilizzando la seguente richiesta di iscrizione:

```
onGroupMessageCreated(userId : "user-2", groupId: :"group-2"){...}
```

AWS AppSync esegue il resolver di sottoscrizione, che genera filtri di sottoscrizione e invalidazione. Per il client B, i filtri di sottoscrizione consentono l'invio dei dati solo a`group-2`, mentre i filtri di invalidazione sono definiti per entrambi e. `user-2` `group-2`

Quindi, supponiamo che un nuovo messaggio di gruppo con l'ID `message-1` venga creato utilizzando una richiesta di mutazione come nell'esempio seguente:

```
createGroupMessage(id: "message-1", groupId :
      "group-1", message: "test message"){...}
```

I client abbonati che corrispondono ai filtri definiti ricevono automaticamente il seguente payload di dati tramite: WebSockets

```
{
  "data": {
    "onGroupMessageCreated": {
      "id": "message-1",
      "groupId": "group-1",
      "message": "test message",
    }
  }
}
```

Il client A riceve il messaggio perché i criteri di filtraggio corrispondono al filtro di sottoscrizione definito. Tuttavia, il client B non riceve il messaggio, in quanto l'utente non ne fa parte`group-1`. Inoltre, la richiesta non corrisponde al filtro di sottoscrizione definito nel resolver di sottoscrizione.

Infine, supponiamo che `user-1` venga rimosso dall'`group-1`utilizzo della seguente richiesta di mutazione:

```
removeUserFromGroup(userId: "user-1", groupId : "group-1"){...}
```

La mutazione avvia un'invalidazione dell'abbonamento come definito nel codice del gestore della risposta del resolver. `extensions.invalidateSubscriptions()` AWS AppSync quindi annulla l'iscrizione al client A e chiude la sua connessione. WebSocket Il client B non è interessato, poiché il payload di invalidazione definito nella mutazione non corrisponde al suo utente o gruppo.

Quando AWS AppSync invalida una connessione, il client riceve un messaggio che conferma che l'iscrizione è stata annullata:

```
{
  "message": "Subscription complete."
}
```

## Utilizzo di variabili di contesto nei filtri di invalidazione delle sottoscrizioni
<a name="aws-appsync-real-time-invalidation-context"></a>

Come per i filtri di sottoscrizione avanzati, puoi utilizzare la [`context`variabile](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) nell'estensione del filtro di invalidazione dell'abbonamento per accedere a determinati dati.

Ad esempio, è possibile configurare un indirizzo e-mail come payload di invalidazione nella mutazione, quindi confrontarlo con l'attributo email o la dichiarazione di un utente abbonato autorizzato con i pool di utenti di Amazon Cognito o OpenID Connect. Il filtro di invalidazione definito nell'invalidatore dell'`extensions.setSubscriptionInvalidationFilter()`abbonamento verifica se l'indirizzo e-mail impostato dal `extensions.invalidateSubscriptions()` payload della mutazione corrisponde all'indirizzo e-mail recuperato dal token JWT dell'utente`context.identity.claims.email`, avviando l'invalidazione.

# WebSocket Creazione di un client in tempo reale in AWS AppSync
<a name="real-time-websocket-client"></a>

**Importante**  
A partire dal 13 marzo 2025, puoi creare un' PubSub API in tempo reale basata su WebSockets AWS AppSync Events. Per ulteriori informazioni, consulta [Pubblicare eventi tramite WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) nella *AWS AppSync Events Developer Guide*.

AWS AppSyncil WebSocket client in tempo reale abilita gli abbonamenti GraphQL attraverso un processo in più fasi. Il client stabilisce innanzitutto una WebSocket connessione con l'endpoint AWS AppSync in tempo reale, invia un messaggio di inizializzazione della connessione e attende la conferma. Dopo una connessione riuscita, il client registra gli abbonamenti inviando messaggi di avvio con query uniche e IDs GraphQL. AWS AppSync conferma gli abbonamenti eseguiti con successo con messaggi di conferma. Il client ascolta quindi gli eventi di sottoscrizione, che vengono attivati dalle mutazioni corrispondenti. Per mantenere la connessione, AWS AppSync invia messaggi keep-alive periodici. Al termine, il client annulla la registrazione degli abbonamenti inviando messaggi di arresto. Questo sistema supporta più abbonamenti su una singola WebSocket connessione e supporta varie modalità di autorizzazione, tra cui chiavi API, pool di utenti Amazon Cognito, IAM e Lambda.

## Implementazione WebSocket client in tempo reale per gli abbonamenti GraphQL
<a name="appsynclong-real-time-websocket-client-implementation-guide-for-graphql-subscriptions"></a>

Il diagramma di sequenza e i passaggi seguenti mostrano il flusso di lavoro degli abbonamenti in tempo reale tra il WebSocket client, il client HTTP e. AWS AppSync

![\[Sequence diagram showing WebSocket client, AppSync endpoints, and HTTP client interactions for real-time subscriptions.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/realtime-client-flow.png)


1. Il client stabilisce una WebSocket connessione con l'endpoint in tempo reale. AWS AppSync Se si verifica un errore di rete, il client dovrebbe eseguire un backoff esponenziale jittered. Per ulteriori informazioni, consulta [Exponential backoff and jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) sul blog di architettura. AWS 

1. (Facoltativo) Dopo aver stabilito correttamente la WebSocket connessione, il client invia un messaggio. `connection_init`

1. Se `connection_init` viene inviato, il client attende un `connection_ack` messaggio da AWS AppSync. Questo messaggio include un `connectionTimeoutMs` parametro, che è il tempo di attesa massimo in millisecondi per un messaggio `"ka"` (keep-alive).

1. AWS AppSync `"ka"`invia messaggi periodicamente. Il client tiene traccia dell'ora in cui ha ricevuto ogni `"ka"` messaggio. Se il client non riceve un `"ka"` messaggio entro `connectionTimeoutMs` millisecondi, deve chiudere la connessione.

1. Il client registra la sottoscrizione inviando un messaggio di sottoscrizione `start`. Una singola WebSocket connessione supporta più abbonamenti, anche se sono in modalità di autorizzazione diverse.

1. Il client attende l'invio di `start_ack` messaggi AWS AppSync per confermare l'avvenuta sottoscrizione. Se c'è un errore, AWS AppSync restituisce un `"type": "error"` messaggio.

1. Il client ascolta gli eventi di sottoscrizione, che vengono inviati dopo la chiamata di una mutazione corrispondente. Le interrogazioni e le mutazioni vengono generalmente inviate `https://` all'endpoint GraphQL AWS AppSync . Le sottoscrizioni fluiscono attraverso l'endpoint AWS AppSync in tempo reale utilizzando secure (). WebSocket `wss://`

1. Il client annulla la registrazione della sottoscrizione inviando un messaggio di sottoscrizione `stop`.

1. Dopo aver annullato la registrazione di tutti gli abbonamenti e aver verificato che non vi siano messaggi trasferiti tramite il WebSocket, il client può disconnettersi dalla connessione. WebSocket 

## Stabilisci i dettagli della stretta di mano per stabilire la connessione WebSocket
<a name="handshake-details-to-establish-the-websocket-connection"></a>

Per connettersi e avviare una stretta di mano di successo con AWS AppSync, un WebSocket client deve disporre di quanto segue:
+ L' AWS AppSync endpoint in tempo reale
+ Intestazioni: contengono informazioni relative all' AWS AppSync endpoint e all'autorizzazione. AWS AppSync supporta i seguenti tre metodi per fornire le intestazioni: 
  + Intestazioni tramite stringa di query
    + Le informazioni sull'intestazione sono codificate come una stringa base64, derivata da un oggetto JSON con stringhe. Questo oggetto JSON contiene dettagli relativi all'endpoint e all'autorizzazione. AWS AppSync Il contenuto dell'oggetto JSON varia a seconda della modalità di autorizzazione.
  + Intestazioni tramite `Sec-WebSocket-Protocol`
    + Una stringa con codifica Base64URL proveniente dall'oggetto JSON con stringhe che contiene informazioni relative all' AWS AppSyncendpoint e all'autorizzazione viene passata come protocollo nell'intestazione. `Sec-WebSocket-Protocol` Il contenuto dell'oggetto JSON varia a seconda della modalità di autorizzazione.
  + Intestazioni tramite intestazioni HTTP standard:
    + Le intestazioni possono essere passate come intestazioni HTTP standard nella richiesta di connessione, in modo simile a come vengono passate le intestazioni per le query e le mutazioni GraphQL. AWS AppSync Tuttavia, il passaggio di intestazioni tramite intestazioni HTTP standard non è supportato per le richieste di connessione API private.
+  `payload`— Stringa codificata in Base64 di. `payload` Il payload è necessario solo se le intestazioni vengono fornite utilizzando la stringa di query

Con questi requisiti, un WebSocket client può connettersi all'URL, che contiene l'endpoint in tempo reale con la stringa di query, utilizzato `graphql-ws` come protocollo. WebSocket 

### Rilevamento dell'endpoint in tempo reale dall'endpoint GraphQL
<a name="discovering-the-appsync-real-time-endpoint-from-the-appsync-graphql-endpoint"></a>

L'endpoint AWS AppSync GraphQL e l'endpoint AWS AppSync in tempo reale sono leggermente diversi nel protocollo e nel dominio. È possibile recuperare l'endpoint GraphQL utilizzando AWS Command Line Interface il AWS CLI comando (). `aws appsync get-graphql-api`

****AWS AppSync Endpoint GraphQL:****  
 `https://example1234567890000.appsync-api.us-east-1.amazonaws.com/graphql`

****AWS AppSync endpoint in tempo reale:****  
 `wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql`

Le applicazioni possono connettersi all'endpoint AWS AppSync GraphQL (`https://`) utilizzando qualsiasi client HTTP per query e mutazioni. Le applicazioni possono connettersi all'endpoint AWS AppSync in tempo reale (`wss://`) utilizzando qualsiasi client per le sottoscrizioni. WebSocket 

Con i nomi di dominio personalizzati, puoi interagire con entrambi gli endpoint utilizzando un unico dominio. Ad esempio, se configuri `api.example.com` come dominio personalizzato, puoi interagire con GraphQL e gli endpoint in tempo reale utilizzando questi: URLs

**AWS AppSync endpoint GraphQL di dominio personalizzato:**  
`https://api.example.com/graphql`

**AWS AppSync endpoint in tempo reale con dominio personalizzato:**  
`wss://api.example.com/graphql/realtime`

## Formato dei parametri di intestazione basato sulla modalità di autorizzazione AWS AppSync API
<a name="header-parameter-format-based-on-appsync-api-authorization-mode"></a>

Il formato dell'`header`oggetto utilizzato nella stringa di query di connessione varia a seconda della modalità di autorizzazione dell' AWS AppSync API. Il `host` campo nell'oggetto si riferisce all'endpoint AWS AppSync GraphQL, che viene utilizzato per convalidare la connessione anche se la `wss://` chiamata viene effettuata sull'endpoint in tempo reale. Per avviare l'handshake e stabilire la connessione autorizzata, `payload` deve essere un oggetto JSON vuoto. Il payload è necessario solo se le intestazioni vengono passate tramite una stringa di query.

Le sezioni seguenti mostrano i formati di intestazione per ciascuna modalità di autorizzazione.

### Chiave API
<a name="api-key"></a>

#### Intestazione della chiave API
<a name="api-key-list"></a>

**Contenuto dell'intestazione**
+  `"host": <string>`: l'host per l'endpoint AWS AppSync GraphQL o il nome di dominio personalizzato.
+  `"x-api-key": <string>`: la chiave API configurata per l' AWS AppSync API.

**Esempio**

```
{
    "host":"example1234567890000.appsync-api.us-east-1.amazonaws.com",
    "x-api-key":"da2-12345678901234567890123456"
}
```

**Intestazioni tramite stringa di query**

Innanzitutto, un oggetto JSON contenente `host` and the `x-api-key` viene convertito in una stringa. Successivamente, questa stringa viene codificata utilizzando la codifica base64. La stringa risultante con codifica base64 viene aggiunta come parametro di query denominato all' WebSocketURL per stabilire la connessione con l'endpoint `header` in tempo reale. AWS AppSync L'URL della richiesta risultante assume il formato seguente:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJob3N0IjoiZXhhbXBsZTEyMzQ1Njc4OTAwMDAuYXBwc3luYy1hcGkudXMtZWFzdC0xLmFtYXpvbmF3cy5jb20iLCJ4LWFtei1kYXRlIjoiMjAyMDA0MDFUMDAxMDEwWiIsIngtYXBpLWtleSI6ImRhMi16NHc0NHZoczV6Z2MzZHRqNXNranJsbGxqaSJ9&payload=e30=
```

È importante notare che oltre all'oggetto header con codifica base64, anche un oggetto JSON vuoto \$1\$1 è codificato in base64 e incluso come parametro di query separato denominato nell'URL. `payload` WebSocket

**Intestazioni tramite `Sec-WebSocket-Protocol`**

Un oggetto JSON contenente `host` and the `x-api-key` viene convertito in una stringa e quindi codificato utilizzando la codifica Base64url. La stringa con codifica Base64URL risultante ha il prefisso. `header-` Questa stringa con prefisso viene quindi utilizzata come nuovo sottoprotocollo oltre che nell'`Sec-WebSocket-Protocol`intestazione quando si stabilisce la connessione con l'`graphql-ws`endpoint in tempo reale. WebSocket AWS AppSync 

L'URL della richiesta risultante assume il seguente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

L'`Sec-WebSocket-Protocol`intestazione contiene il seguente valore:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ewogICAgImhvc3QiOiJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsCiAgICAieC1hcGkta2V5IjoiZGEyLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Igp9"]
```

**Intestazioni tramite intestazioni HTTP standard**

In questo metodo, le informazioni sull'host e sulla chiave API vengono trasmesse utilizzando intestazioni HTTP standard quando si stabilisce la WebSocket connessione con l' AWS AppSync endpoint in tempo reale. L'URL della richiesta risultante assume il seguente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Le intestazioni della richiesta includerebbero quanto segue:

```
"sec-websocket-protocol" : ["graphql-ws"]
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com",
"x-api-key":"da2-12345678901234567890123456"
```

### Pool di utenti Amazon Cognito e OpenID Connect (OIDC)
<a name="amazon-cognito-user-pools-and-openid-connect-oidc"></a>

#### Amazon Cognito e header OIDC
<a name="amazon-cognito-user-pools-and-openid-connect-oidc-list"></a>

Contenuti dell'intestazione:
+  `"Authorization": <string>`: Un token ID JWT. L'intestazione può utilizzare uno schema [Bearer](https://datatracker.ietf.org/doc/html/rfc6750#section-2.1).
+  `"host": <string>`: l'host per l'endpoint AWS AppSync GraphQL o il nome di dominio personalizzato.

Esempio:

```
{
    "Authorization":"eyEXAMPLEiJjbG5xb3A5eW5MK09QYXIrMTJHWEFLSXBieU5WNHhsQjEXAMPLEnM2WldvPSIsImFsZyI6IlEXAMPLEn0.eyEXAMPLEiJhNmNmMjcwNy0xNjgxLTQ1NDItOWYxOC1lNjY0MTg2NjlkMzYiLCJldmVudF9pZCI6ImVkMzM5MmNkLWNjYTMtNGM2OC1hNDYyLTJlZGI3ZTNmY2FjZiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE1Njk0NTc3MTgsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zb3V0aGVhc3QtMl83OHY0SVZibVAiLCJleHAiOjE1Njk0NjEzMjAsImlhdCI6MTU2OTQ1NzcyMCwianRpIjoiNTgzZjhmYmMtMzk2MS00YzA4LWJhZTAtYzQyY2IxMTM5NDY5IiwiY2xpZW50X2lkIjoiM3FlajVlMXZmMzd1N3RoZWw0dG91dDJkMWwiLCJ1c2VybmFtZSI6ImVsb3EXAMPLEn0.B4EXAMPLEFNpJ6ikVp7e6DRee95V6Qi-zEE2DJH7sHOl2zxYi7f-SmEGoh2AD8emxQRYajByz-rE4Jh0QOymN2Ys-ZIkMpVBTPgu-TMWDyOHhDUmUj2OP82yeZ3wlZAtr_gM4LzjXUXmI_K2yGjuXfXTaa1mvQEBG0mQfVd7SfwXB-jcv4RYVi6j25qgow9Ew52ufurPqaK-3WAKG32KpV8J4-Wejq8t0c-yA7sb8EnB551b7TU93uKRiVVK3E55Nk5ADPoam_WYE45i3s5qVAP_-InW75NUoOCGTsS8YWMfb6ecHYJ-1j-bzA27zaT9VjctXn9byNFZmEXAMPLExw",
    "host":"example1234567890000.appsync-api.us-east-1.amazonaws.com"
}
```

**Intestazioni tramite stringa di query**

Innanzitutto, un oggetto JSON contenente `host` and the `Authorization` viene convertito in una stringa. Successivamente, questa stringa viene codificata utilizzando la codifica base64. La stringa risultante con codifica base64 viene aggiunta come parametro di query denominato all' WebSocket URL per stabilire la connessione con l'endpoint `header` in tempo reale. AWS AppSync L'URL della richiesta risultante assume il formato seguente:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoiZXlKcmFXUWlPaUpqYkc1eGIzQTVlVzVNSzA5UVlYSXJNVEpIV0VGTFNYQmllVTVXTkhoc1FqaFBWVzlZTW5NMldsZHZQU0lzSW1Gc1p5STZJbEpUTWpVMkluMC5leUp6ZFdJaU9pSmhObU5tTWpjd055MHhOamd4TFRRMU5ESXRPV1l4T0MxbE5qWTBNVGcyTmpsa016WWlMQ0psZG1WdWRGOXBaQ0k2SW1Wa016TTVNbU5rTFdOallUTXROR00yT0MxaE5EWXlMVEpsWkdJM1pUTm1ZMkZqWmlJc0luUnZhMlZ1WDNWelpTSTZJbUZqWTJWemN5SXNJbk5qYjNCbElqb2lZWGR6TG1OdloyNXBkRzh1YzJsbmJtbHVMblZ6WlhJdVlXUnRhVzRpTENKaGRYUm9YM1JwYldVaU9qRTFOamswTlRjM01UZ3NJbWx6Y3lJNkltaDBkSEJ6T2x3dlhDOWpiMmR1YVhSdkxXbGtjQzVoY0MxemIzVjBhR1ZoYzNRdE1pNWhiV0Y2YjI1aGQzTXVZMjl0WEM5aGNDMXpiM1YwYUdWaGMzUXRNbDgzT0hZMFNWWmliVkFpTENKbGVIQWlPakUxTmprME5qRXpNakFzSW1saGRDSTZNVFUyT1RRMU56Y3lNQ3dpYW5ScElqb2lOVGd6WmpobVltTXRNemsyTVMwMFl6QTRMV0poWlRBdFl6UXlZMkl4TVRNNU5EWTVJaXdpWTJ4cFpXNTBYMmxrSWpvaU0zRmxhalZsTVhabU16ZDFOM1JvWld3MGRHOTFkREprTVd3aUxDSjFjMlZ5Ym1GdFpTSTZJbVZzYjNKNllXWmxJbjAuQjRjZEp0aDNLRk5wSjZpa1ZwN2U2RFJlZTk1VjZRaS16RUUyREpIN3NIT2wyenhZaTdmLVNtRUdvaDJBRDhlbXhRUllhakJ5ei1yRTRKaDBRT3ltTjJZcy1aSWtNcFZCVFBndS1UTVdEeU9IaERVbVVqMk9QODJ5ZVozd2xaQXRyX2dNNEx6alhVWG1JX0syeUdqdVhmWFRhYTFtdlFFQkcwbVFmVmQ3U2Z3WEItamN2NFJZVmk2ajI1cWdvdzlFdzUydWZ1clBxYUstM1dBS0czMktwVjhKNC1XZWpxOHQwYy15QTdzYjhFbkI1NTFiN1RVOTN1S1JpVlZLM0U1NU5rNUFEUG9hbV9XWUU0NWkzczVxVkFQXy1Jblc3NU5Vb09DR1RzUzhZV01mYjZlY0hZSi0xai1iekEyN3phVDlWamN0WG45YnlORlptS0xwQTJMY3h3IiwiaG9zdCI6ImV4YW1wbGUxMjM0NTY3ODkwMDAwLmFwcHN5bmMtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tIn0=&payload=e30=
```

È importante notare che oltre all'oggetto header con codifica base64, anche un oggetto JSON vuoto \$1\$1 è codificato in base64 e incluso come parametro di query separato denominato nell'URL. `payload` WebSocket

**Intestazioni tramite `Sec-WebSocket-Protocol`**

Un oggetto JSON contenente `host` and the `Authorization` viene convertito in una stringa e quindi codificato utilizzando la codifica Base64url. La stringa con codifica Base64URL risultante ha il prefisso. `header-` Questa stringa con prefisso viene quindi utilizzata come nuovo sottoprotocollo oltre che nell'`Sec-WebSocket-Protocol`intestazione quando si stabilisce la connessione con l'`graphql-ws`endpoint in tempo reale. WebSocket AWS AppSync 

L'URL della richiesta risultante assume il seguente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

L'`Sec-WebSocket-Protocol`intestazione contiene il seguente valore:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ewogICAgImhvc3QiOiJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsCiAgICAieC1hcGkta2V5IjoiZGEyLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Igp9"]
```

**Intestazioni tramite intestazioni HTTP standard**

In questo metodo, le informazioni sull'host e sull'autorizzazione vengono trasmesse utilizzando intestazioni HTTP standard quando si stabilisce la WebSocket connessione con l' AWS AppSync endpoint in tempo reale. L'URL della richiesta risultante assume il seguente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Le intestazioni della richiesta includerebbero quanto segue:

```
"sec-websocket-protocol" : ["graphql-ws"]
"Authorization":"eyEXAMPLEiJjbG5xb3A5eW5MK09QYXIrMTJHWEFLSXBieU5WNHhsQjEXAMPLEnM2WldvPSIsImFsZyI6IlEXAMPLEn0.eyEXAMPLEiJhNmNmMjcwNy0xNjgxLTQ1NDItOWYxOC1lNjY0MTg2NjlkMzYiLCJldmVudF9pZCI6ImVkMzM5MmNkLWNjYTMtNGM2OC1hNDYyLTJlZGI3ZTNmY2FjZiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE1Njk0NTc3MTgsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zb3V0aGVhc3QtMl83OHY0SVZibVAiLCJleHAiOjE1Njk0NjEzMjAsImlhdCI6MTU2OTQ1NzcyMCwianRpIjoiNTgzZjhmYmMtMzk2MS00YzA4LWJhZTAtYzQyY2IxMTM5NDY5IiwiY2xpZW50X2lkIjoiM3FlajVlMXZmMzd1N3RoZWw0dG91dDJkMWwiLCJ1c2VybmFtZSI6ImVsb3EXAMPLEn0.B4EXAMPLEFNpJ6ikVp7e6DRee95V6Qi-zEE2DJH7sHOl2zxYi7f-SmEGoh2AD8emxQRYajByz-rE4Jh0QOymN2Ys-ZIkMpVBTPgu-TMWDyOHhDUmUj2OP82yeZ3wlZAtr_gM4LzjXUXmI_K2yGjuXfXTaa1mvQEBG0mQfVd7SfwXB-jcv4RYVi6j25qgow9Ew52ufurPqaK-3WAKG32KpV8J4-Wejq8t0c-yA7sb8EnB551b7TU93uKRiVVK3E55Nk5ADPoam_WYE45i3s5qVAP_-InW75NUoOCGTsS8YWMfb6ecHYJ-1j-bzA27zaT9VjctXn9byNFZmEXAMPLExw",
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com"
```

### IAM
<a name="iam"></a>

#### Intestazione IAM
<a name="iam-list"></a>

**Contenuto dell'intestazione**
+  `"accept": "application/json, text/javascript"`: un parametro `<string>` costante.
+  `"content-encoding": "amz-1.0"`: un parametro `<string>` costante.
+  `"content-type": "application/json; charset=UTF-8"`: un parametro `<string>` costante.
+  `"host": <string>`: Questo è l'host per l'endpoint AWS AppSync GraphQL.
  + `"x-amz-date": <string>`: Il timestamp deve essere in UTC e nel seguente formato ISO 8601: YYYYMMDD'T'HHMMSS'Z'. Ad esempio, 20150830T123600Z è un timestamp valido. Non includere i millisecondi nel time stamp. Per ulteriori informazioni[, vedere Gestione delle date *Riferimenti generali di AWS*nella](https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html) versione 4 di Signature in.
  +  `"X-Amz-Security-Token": <string>`: Il token di AWS sessione, necessario quando si utilizzano credenziali di sicurezza temporanee. Per ulteriori informazioni, consulta [Utilizzo di credenziali temporanee con le risorse AWS](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_credentials_temp_use-resources.html) nella *Guida per l'utente IAM*.
  +  `"Authorization": <string>`: Signature Version 4 (SigV4): informazioni di firma per l'endpoint. AWS AppSync Per ulteriori informazioni sul processo di firma, vedere [Attività 4: aggiungere la firma alla richiesta HTTP](https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html) in. *Riferimenti generali di AWS*

La richiesta HTTP di firma Sigv4 include un URL canonico, che è l'endpoint AWS AppSync GraphQL con `/connect` aggiunto. La AWS regione dell'endpoint del servizio è la stessa regione in cui stai utilizzando l' AWS AppSync API e il nome del servizio è «appsync». La richiesta HTTP da firmare è la seguente:

```
{
  url: "https://example1234567890000.appsync-api.us-east-1.amazonaws.com/graphql/connect",
  data: "{}",
  method: "POST",
  headers: {
    "accept": "application/json, text/javascript",
    "content-encoding": "amz-1.0",
    "content-type": "application/json; charset=UTF-8",
  }
}
```

**Esempio**

```
{
  "accept": "application/json, text/javascript",
  "content-encoding": "amz-1.0",
  "content-type": "application/json; charset=UTF-8",
  "host": "example1234567890000.appsync-api.us-east-1.amazonaws.com",
  "x-amz-date": "20200401T001010Z",
  "X-Amz-Security-Token": "AgEXAMPLEZ2luX2VjEAoaDmFwLXNvdXRoZWFEXAMPLEcwRQIgAh97Cljq7wOPL8KsxP3YtDuyc/9hAj8PhJ7Fvf38SgoCIQDhJEXAMPLEPspioOztj++pEagWCveZUjKEn0zyUhBEXAMPLEjj//////////8BEXAMPLExODk2NDgyNzg1NSIMo1mWnpESWUoYw4BkKqEFSrm3DXuL8w+ZbVc4JKjDP4vUCKNR6Le9C9pZp9PsW0NoFy3vLBUdAXEXAMPLEOVG8feXfiEEA+1khgFK/wEtwR+9zF7NaMMMse07wN2gG2tH0eKMEXAMPLEQX+sMbytQo8iepP9PZOzlZsSFb/dP5Q8hk6YEXAMPLEYcKZsTkDAq2uKFQ8mYUVA9EtQnNRiFLEY83aKvG/tqLWNnGlSNVx7SMcfovkFDqQamm+88y1OwwAEYK7qcoceX6Z7GGcaYuIfGpaX2MCCELeQvZ+8WxEgOnIfz7GYvsYNjLZSaRnV4G+ILY1F0QNW64S9Nvj+BwDg3ht2CrNvpwjVYlj9U3nmxE0UG5ne83LL5hhqMpm25kmL7enVgw2kQzmU2id4IKu0C/WaoDRuO2F5zE63vJbxN8AYs7338+4B4HBb6BZ6OUgg96Q15RA41/gIqxaVPxyTpDfTU5GfSLxocdYeniqqpFMtZG2n9d0u7GsQNcFkNcG3qDZm4tDo8tZbuym0a2VcF2E5hFEgXBa+XLJCfXi/77OqAEjP0x7Qdk3B43p8KG/BaioP5RsV8zBGvH1zAgyPha2rN70/tT13yrmPd5QYEfwzexjKrV4mWIuRg8NTHYSZJUaeyCwTom80VFUJXG+GYTUyv5W22aBcnoRGiCiKEYTLOkgXecdKFTHmcIAejQ9Welr0a196Kq87w5KNMCkcCGFnwBNFLmfnbpNqT6rUBxxs3X5ntX9d8HVtSYINTsGXXMZCJ7fnbWajhg/aox0FtHX21eF6qIGT8j1z+l2opU+ggwUgkhUUgCH2TfqBj+MLMVVvpgqJsPKt582caFKArIFIvO+9QupxLnEH2hz04TMTfnU6bQC6z1buVe7h+tOLnh1YPFsLQ88anib/7TTC8k9DsBTq0ASe8R2GbSEsmO9qbbMwgEaYUhOKtGeyQsSJdhSk6XxXThrWL9EnwBCXDkICMqdntAxyyM9nWsZ4bL9JHqExgWUmfWChzPFAqn3F4y896UqHTZxlq3WGypn5HHcem2Hqf3IVxKH1inhqdVtkryEiTWrI7ZdjbqnqRbl+WgtPtKOOweDlCaRs3R2qXcbNgVhleMk4IWnF8D1695AenU1LwHjOJLkCjxgNFiWAFEPH9aEXAMPLExA==",
  "Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXX/20200401/us-east-1/appsync/aws4_request, SignedHeaders=accept;content-encoding;content-type;host;x-amz-date;x-amz-security-token, Signature=83EXAMPLEbcc1fe3ee69f75cd5ebbf4cb4f150e4f99cec869f149c5EXAMPLEdc"
}
```

**Intestazioni tramite stringa di query**

Innanzitutto, un oggetto JSON contenente `host` (endpoint AWS AppSync GraphQL) e le altre intestazioni di autorizzazione viene convertito in una stringa. Successivamente, questa stringa viene codificata utilizzando la codifica base64. La stringa con codifica base64 risultante viene aggiunta all'URL come parametro di query denominato. WebSocket `header` L'URL della richiesta risultante assume il formato seguente:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoiZXlKcmFXUWlPaUpqYkc1eGIzQTVlVzVNSzA5UVlYSXJNVEpIV0VGTFNYQmllVTVXTkhoc1FqaFBWVzlZTW5NMldsZHZQU0lzSW1Gc1p5STZJbEpUTWpVMkluMC5leUp6ZFdJaU9pSmhObU5tTWpjd055MHhOamd4TFRRMU5ESXRPV1l4T0MxbE5qWTBNVGcyTmpsa016WWlMQ0psZG1WdWRGOXBaQ0k2SW1Wa016TTVNbU5rTFdOallUTXROR00yT0MxaE5EWXlMVEpsWkdJM1pUTm1ZMkZqWmlJc0luUnZhMlZ1WDNWelpTSTZJbUZqWTJWemN5SXNJbk5qYjNCbElqb2lZWGR6TG1OdloyNXBkRzh1YzJsbmJtbHVMblZ6WlhJdVlXUnRhVzRpTENKaGRYUm9YM1JwYldVaU9qRTFOamswTlRjM01UZ3NJbWx6Y3lJNkltaDBkSEJ6T2x3dlhDOWpiMmR1YVhSdkxXbGtjQzVoY0MxemIzVjBhR1ZoYzNRdE1pNWhiV0Y2YjI1aGQzTXVZMjl0WEM5aGNDMXpiM1YwYUdWaGMzUXRNbDgzT0hZMFNWWmliVkFpTENKbGVIQWlPakUxTmprME5qRXpNakFzSW1saGRDSTZNVFUyT1RRMU56Y3lNQ3dpYW5ScElqb2lOVGd6WmpobVltTXRNemsyTVMwMFl6QTRMV0poWlRBdFl6UXlZMkl4TVRNNU5EWTVJaXdpWTJ4cFpXNTBYMmxrSWpvaU0zRmxhalZsTVhabU16ZDFOM1JvWld3MGRHOTFkREprTVd3aUxDSjFjMlZ5Ym1GdFpTSTZJbVZzYjNKNllXWmxJbjAuQjRjZEp0aDNLRk5wSjZpa1ZwN2U2RFJlZTk1VjZRaS16RUUyREpIN3NIT2wyenhZaTdmLVNtRUdvaDJBRDhlbXhRUllhakJ5ei1yRTRKaDBRT3ltTjJZcy1aSWtNcFZCVFBndS1UTVdEeU9IaERVbVVqMk9QODJ5ZVozd2xaQXRyX2dNNEx6alhVWG1JX0syeUdqdVhmWFRhYTFtdlFFQkcwbVFmVmQ3U2Z3WEItamN2NFJZVmk2ajI1cWdvdzlFdzUydWZ1clBxYUstM1dBS0czMktwVjhKNC1XZWpxOHQwYy15QTdzYjhFbkI1NTFiN1RVOTN1S1JpVlZLM0U1NU5rNUFEUG9hbV9XWUU0NWkzczVxVkFQXy1Jblc3NU5Vb09DR1RzUzhZV01mYjZlY0hZSi0xai1iekEyN3phVDlWamN0WG45YnlORlptS0xwQTJMY3h3IiwiaG9zdCI6ImV4YW1wbGUxMjM0NTY3ODkwMDAwLmFwcHN5bmMtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tIn0=&payload=e30=
```

È importante notare che oltre all'oggetto header con codifica base64, anche un oggetto JSON vuoto \$1\$1 è codificato in base64 e incluso come parametro di query separato denominato nell'URL. `payload` WebSocket

**Intestazioni tramite `Sec-WebSocket-Protocol`**

Un oggetto JSON contenente le `host` e le altre intestazioni di autorizzazione viene convertito in una stringa e quindi codificato utilizzando la codifica Base64URL. La stringa con codifica Base64URL risultante ha il prefisso. `header-` Questa stringa con prefisso viene quindi utilizzata come nuovo sottoprotocollo oltre che nell'`Sec-WebSocket-Protocol`intestazione quando si stabilisce la connessione con l'`graphql-ws`endpoint in tempo reale. WebSocket AWS AppSync 

L'URL della richiesta risultante assume il seguente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

L'`Sec-WebSocket-Protocol`intestazione contiene il seguente valore:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ew0KICAiYWNjZXB0IjogImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCIsDQogICJjb250ZW50LWVuY29kaW5nIjogImFtei0xLjAiLA0KICAiY29udGVudC10eXBlIjogImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiLA0KICAiaG9zdCI6ICJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsDQogICJ4LWFtei1kYXRlIjogIjIwMjAwNDAxVDAwMTAxMFoiLA0KICAiWC1BbXotU2VjdXJpdHktVG9rZW4iOiAiQWdFWEFNUExFWjJsdVgyVmpFQW9hRG1Gd0xYTnZkWFJvWldGRVhBTVBMRWN3UlFJZ0FoOTdDbGpxN3dPUEw4S3N4UDNZdER1eWMvOWhBajhQaEo3RnZmMzhTZ29DSVFEaEpFWEFNUExFUHNwaW9PenRqKytwRWFnV0N2ZVpVaktFbjB6eVVoQkVYQU1QTEVqai8vLy8vLy8vLy84QkVYQU1QTEV4T0RrMk5EZ3lOemcxTlNJTW8xbVducEVTV1VvWXc0QmtLcUVGU3JtM0RYdUw4dytaYlZjNEpLakRQNHZVQ0tOUjZMZTlDOXBacDlQc1cwTm9GeTN2TEJVZEFYRVhBTVBMRU9WRzhmZVhmaUVFQSsxa2hnRksvd0V0d1IrOXpGN05hTU1Nc2UwN3dOMmdHMnRIMGVLTUVYQU1QTEVRWCtzTWJ5dFFvOGllcFA5UFpPemxac1NGYi9kUDVROGhrNllFWEFNUExFWWNLWnNUa0RBcTJ1S0ZROG1ZVVZBOUV0UW5OUmlGTEVZODNhS3ZHL3RxTFdObkdsU05WeDdTTWNmb3ZrRkRxUWFtbSs4OHkxT3d3QUVZSzdxY29jZVg2WjdHR2NhWXVJZkdwYVgyTUNDRUxlUXZaKzhXeEVnT25JZno3R1l2c1lOakxaU2FSblY0RytJTFkxRjBRTlc2NFM5TnZqK0J3RGczaHQyQ3JOdnB3alZZbGo5VTNubXhFMFVHNW5lODNMTDVoaHFNcG0yNWttTDdlblZndzJrUXptVTJpZDRJS3UwQy9XYW9EUnVPMkY1ekU2M3ZKYnhOOEFZczczMzgrNEI0SEJiNkJaNk9VZ2c5NlExNVJBNDEvZ0lxeGFWUHh5VHBEZlRVNUdmU0x4b2NkWWVuaXFxcEZNdFpHMm45ZDB1N0dzUU5jRmtOY0czcURabTR0RG84dFpidXltMGEyVmNGMkU1aEZFZ1hCYStYTEpDZlhpLzc3T3FBRWpQMHg3UWRrM0I0M3A4S0cvQmFpb1A1UnNWOHpCR3ZIMXpBZ3lQaGEyck43MC90VDEzeXJtUGQ1UVlFZnd6ZXhqS3JWNG1XSXVSZzhOVEhZU1pKVWFleUN3VG9tODBWRlVKWEcrR1lUVXl2NVcyMmFCY25vUkdpQ2lLRVlUTE9rZ1hlY2RLRlRIbWNJQWVqUTlXZWxyMGExOTZLcTg3dzVLTk1Da2NDR0Zud0JORkxtZm5icE5xVDZyVUJ4eHMzWDVudFg5ZDhIVnRTWUlOVHNHWFhNWkNKN2ZuYldhamhnL2FveDBGdEhYMjFlRjZxSUdUOGoxeitsMm9wVStnZ3dVZ2toVVVnQ0gyVGZxQmorTUxNVlZ2cGdxSnNQS3Q1ODJjYUZLQXJJRkl2Tys5UXVweExuRUgyaHowNFRNVGZuVTZiUUM2ejFidVZlN2grdE9MbmgxWVBGc0xRODhhbmliLzdUVEM4azlEc0JUcTBBU2U4UjJHYlNFc21POXFiYk13Z0VhWVVoT0t0R2V5UXNTSmRoU2s2WHhYVGhyV0w5RW53QkNYRGtJQ01xZG50QXh5eU05bldzWjRiTDlKSHFFeGdXVW1mV0NoelBGQXFuM0Y0eTg5NlVxSFRaeGxxM1dHeXBuNUhIY2VtMkhxZjNJVnhLSDFpbmhxZFZ0a3J5RWlUV3JJN1pkamJxbnFSYmwrV2d0UHRLT093ZURsQ2FSczNSMnFYY2JOZ1ZobGVNazRJV25GOEQxNjk1QWVuVTFMd0hqT0pMa0NqeGdORmlXQUZFUEg5YUVYQU1QTEV4QT09IiwNCiAgIkF1dGhvcml6YXRpb24iOiAiQVdTNC1ITUFDLVNIQTI1NiBDcmVkZW50aWFsPVhYWFhYWFhYWFhYWFhYWFhYWFgvMjAyMDA0MDEvdXMtZWFzdC0xL2FwcHN5bmMvYXdzNF9yZXF1ZXN0LCBTaWduZWRIZWFkZXJzPWFjY2VwdDtjb250ZW50LWVuY29kaW5nO2NvbnRlbnQtdHlwZTtob3N0O3gtYW16LWRhdGU7eC1hbXotc2VjdXJpdHktdG9rZW4sIFNpZ25hdHVyZT04M0VYQU1QTEViY2MxZmUzZWU2OWY3NWNkNWViYmY0Y2I0ZjE1MGU0Zjk5Y2VjODY5ZjE0OWM1RVhBTVBMRWRjIg0KfQ"]
```

**Intestazioni tramite intestazioni HTTP standard**

In questo metodo, l'host e le altre informazioni di autorizzazione vengono trasmesse utilizzando intestazioni HTTP standard quando si stabilisce la WebSocket connessione con l' AWS AppSync endpoint in tempo reale. L'URL della richiesta risultante assume il seguente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Le intestazioni della richiesta includerebbero quanto segue:

```
"sec-websocket-protocol" : ["graphql-ws"]
"accept": "application/json, text/javascript",
"content-encoding": "amz-1.0",
"content-type": "application/json; charset=UTF-8",
"host": "example1234567890000.appsync-api.us-east-1.amazonaws.com",
"x-amz-date": "20200401T001010Z",
"X-Amz-Security-Token": "AgEXAMPLEZ2luX2VjEAoaDmFwLXNvdXRoZWFEXAMPLEcwRQIgAh97Cljq7wOPL8KsxP3YtDuyc/9hAj8PhJ7Fvf38SgoCIQDhJEXAMPLEPspioOztj++pEagWCveZUjKEn0zyUhBEXAMPLEjj//////////8BEXAMPLExODk2NDgyNzg1NSIMo1mWnpESWUoYw4BkKqEFSrm3DXuL8w+ZbVc4JKjDP4vUCKNR6Le9C9pZp9PsW0NoFy3vLBUdAXEXAMPLEOVG8feXfiEEA+1khgFK/wEtwR+9zF7NaMMMse07wN2gG2tH0eKMEXAMPLEQX+sMbytQo8iepP9PZOzlZsSFb/dP5Q8hk6YEXAMPLEYcKZsTkDAq2uKFQ8mYUVA9EtQnNRiFLEY83aKvG/tqLWNnGlSNVx7SMcfovkFDqQamm+88y1OwwAEYK7qcoceX6Z7GGcaYuIfGpaX2MCCELeQvZ+8WxEgOnIfz7GYvsYNjLZSaRnV4G+ILY1F0QNW64S9Nvj+BwDg3ht2CrNvpwjVYlj9U3nmxE0UG5ne83LL5hhqMpm25kmL7enVgw2kQzmU2id4IKu0C/WaoDRuO2F5zE63vJbxN8AYs7338+4B4HBb6BZ6OUgg96Q15RA41/gIqxaVPxyTpDfTU5GfSLxocdYeniqqpFMtZG2n9d0u7GsQNcFkNcG3qDZm4tDo8tZbuym0a2VcF2E5hFEgXBa+XLJCfXi/77OqAEjP0x7Qdk3B43p8KG/BaioP5RsV8zBGvH1zAgyPha2rN70/tT13yrmPd5QYEfwzexjKrV4mWIuRg8NTHYSZJUaeyCwTom80VFUJXG+GYTUyv5W22aBcnoRGiCiKEYTLOkgXecdKFTHmcIAejQ9Welr0a196Kq87w5KNMCkcCGFnwBNFLmfnbpNqT6rUBxxs3X5ntX9d8HVtSYINTsGXXMZCJ7fnbWajhg/aox0FtHX21eF6qIGT8j1z+l2opU+ggwUgkhUUgCH2TfqBj+MLMVVvpgqJsPKt582caFKArIFIvO+9QupxLnEH2hz04TMTfnU6bQC6z1buVe7h+tOLnh1YPFsLQ88anib/7TTC8k9DsBTq0ASe8R2GbSEsmO9qbbMwgEaYUhOKtGeyQsSJdhSk6XxXThrWL9EnwBCXDkICMqdntAxyyM9nWsZ4bL9JHqExgWUmfWChzPFAqn3F4y896UqHTZxlq3WGypn5HHcem2Hqf3IVxKH1inhqdVtkryEiTWrI7ZdjbqnqRbl+WgtPtKOOweDlCaRs3R2qXcbNgVhleMk4IWnF8D1695AenU1LwHjOJLkCjxgNFiWAFEPH9aEXAMPLExA==",
"Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXX/20200401/us-east-1/appsync/aws4_request, SignedHeaders=accept;content-encoding;content-type;host;x-amz-date;x-amz-security-token, Signature=83EXAMPLEbcc1fe3ee69f75cd5ebbf4cb4f150e4f99cec869f149c5EXAMPLEdc"
```

Per firmare la richiesta utilizzando un dominio personalizzato:

```
{
  url: "https://api.example.com/graphql/connect",
  data: "{}",
  method: "POST",
  headers: {
    "accept": "application/json, text/javascript",
    "content-encoding": "amz-1.0",
    "content-type": "application/json; charset=UTF-8",
  }
}
```

**Esempio**

```
{
  "accept": "application/json, text/javascript",
  "content-encoding": "amz-1.0",
  "content-type": "application/json; charset=UTF-8",
  "host": "api.example.com",
  "x-amz-date": "20200401T001010Z",
  "X-Amz-Security-Token": "AgEXAMPLEZ2luX2VjEAoaDmFwLXNvdXRoZWFEXAMPLEcwRQIgAh97Cljq7wOPL8KsxP3YtDuyc/9hAj8PhJ7Fvf38SgoCIQDhJEXAMPLEPspioOztj++pEagWCveZUjKEn0zyUhBEXAMPLEjj//////////8BEXAMPLExODk2NDgyNzg1NSIMo1mWnpESWUoYw4BkKqEFSrm3DXuL8w+ZbVc4JKjDP4vUCKNR6Le9C9pZp9PsW0NoFy3vLBUdAXEXAMPLEOVG8feXfiEEA+1khgFK/wEtwR+9zF7NaMMMse07wN2gG2tH0eKMEXAMPLEQX+sMbytQo8iepP9PZOzlZsSFb/dP5Q8hk6YEXAMPLEYcKZsTkDAq2uKFQ8mYUVA9EtQnNRiFLEY83aKvG/tqLWNnGlSNVx7SMcfovkFDqQamm+88y1OwwAEYK7qcoceX6Z7GGcaYuIfGpaX2MCCELeQvZ+8WxEgOnIfz7GYvsYNjLZSaRnV4G+ILY1F0QNW64S9Nvj+BwDg3ht2CrNvpwjVYlj9U3nmxE0UG5ne83LL5hhqMpm25kmL7enVgw2kQzmU2id4IKu0C/WaoDRuO2F5zE63vJbxN8AYs7338+4B4HBb6BZ6OUgg96Q15RA41/gIqxaVPxyTpDfTU5GfSLxocdYeniqqpFMtZG2n9d0u7GsQNcFkNcG3qDZm4tDo8tZbuym0a2VcF2E5hFEgXBa+XLJCfXi/77OqAEjP0x7Qdk3B43p8KG/BaioP5RsV8zBGvH1zAgyPha2rN70/tT13yrmPd5QYEfwzexjKrV4mWIuRg8NTHYSZJUaeyCwTom80VFUJXG+GYTUyv5W22aBcnoRGiCiKEYTLOkgXecdKFTHmcIAejQ9Welr0a196Kq87w5KNMCkcCGFnwBNFLmfnbpNqT6rUBxxs3X5ntX9d8HVtSYINTsGXXMZCJ7fnbWajhg/aox0FtHX21eF6qIGT8j1z+l2opU+ggwUgkhUUgCH2TfqBj+MLMVVvpgqJsPKt582caFKArIFIvO+9QupxLnEH2hz04TMTfnU6bQC6z1buVe7h+tOLnh1YPFsLQ88anib/7TTC8k9DsBTq0ASe8R2GbSEsmO9qbbMwgEaYUhOKtGeyQsSJdhSk6XxXThrWL9EnwBCXDkICMqdntAxyyM9nWsZ4bL9JHqExgWUmfWChzPFAqn3F4y896UqHTZxlq3WGypn5HHcem2Hqf3IVxKH1inhqdVtkryEiTWrI7ZdjbqnqRbl+WgtPtKOOweDlCaRs3R2qXcbNgVhleMk4IWnF8D1695AenU1LwHjOJLkCjxgNFiWAFEPH9aEXAMPLExA==",
  "Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXX/20200401/us-east-1/appsync/aws4_request, SignedHeaders=accept;content-encoding;content-type;host;x-amz-date;x-amz-security-token, Signature=83EXAMPLEbcc1fe3ee69f75cd5ebbf4cb4f150e4f99cec869f149c5EXAMPLEdc"
}
```

**URL della richiesta con stringa di query**

```
wss://api.example.com/graphql?header=eyEXAMPLEHQiOiJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFEXAMPLEQiLCJjb250ZW50LWVuY29kaW5nIjoEXAMPLEEuMCIsImNvbnRlbnQtdHlwZSI6ImFwcGxpY2F0aW9EXAMPLE47IGNoYXJzZXQ9VVRGLTgiLCJob3N0IjoiZXhhbXBsZEXAMPLENjc4OTAwMDAuYXBwc3luYy1hcGkudXMtZWFzdC0xLmFtYEXAMPLEcy5jb20iLCJ4LWFtei1kYXRlIjoiMjAyMDA0MDFUMDAxMDEwWiIsIlgtEXAMPLElY3VyaXR5LVRva2VuIjoiQWdvSmIzSnBaMmx1WDJWakVBb2FEbUZ3TFhOdmRYUm9aV0Z6ZEMweUlrY3dSUUlnQWg5N0NsanE3d09QTDhLc3hQM1l0RHV5Yy85aEFqOFBoSjdGdmYzOFNnb0NJUURoSllKYkpsbmpQc3Bpb096dGorK3BFYWdXQ3ZlWlVqS0VuMHp5VWhCbXhpck5CUWpqLy8vLy8vLy8vLzhCRUFBYUREY3hPRGsyTkRneU56ZzFOU0lNbzFtV25wRVNXVW9ZdzRCa0txRUZTcm0zRFh1TDh3K1piVmM0SktqRFA0dlVDS05SNkxlOUM5cFpwOVBzVzBOb0Z5M3ZMQlVkQVh3dDZQSld1T1ZHOGZlWGZpRUVBKzFraGdGSy93RXR3Uis5ekY3TmFNTU1zZTA3d04yZ0cydEgwZUtNVFhuOEF3QVFYK3NNYnl0UW84aWVwUDlQWk96bFpzU0ZiL2RQNVE4aGs2WWpHVGFMMWVZY0tac1RrREFxMnVLRlE4bVlVVkE5RXRRbk5SaUZMRVk4M2FLdkcvdHFMV05uR2xTTlZ4N1NNY2ZvdmtGRHFRYW1tKzg4eTFPd3dBRVlLN3Fjb2NlWDZaN0dHY2FZdUlmR3BhWDJNQ0NFTGVRdlorOFd4RWdPbklmejdHWXZzWU5qTFpTYVJuVjRHK0lMWTFGMFFOVzY0UzlOdmorQndEZzNodDJDck52cHdqVllsajlVM25teEUwVUc1bmU4M0xMNWhocU1wbTI1a21MN2VuVmd3MmtRem1VMmlkNElLdTBDL1dhb0RSdU8yRjV6RTYzdkpieE44QVlzNzMzOCs0QjRIQmI2Qlo2T1VnZzk2UTE1UkE0MS9nSXF4YVZQeHlUcERmVFU1R2ZTTHhvY2RZZW5pcXFwRk10WkcybjlkMHU3R3NRTmNGa05jRzNxRFptNHREbzh0WmJ1eW0wYTJWY0YyRTVoRkVnWEJhK1hMSkNmWGkvNzdPcUFFalAweDdRZGszQjQzcDhLRy9CYWlvUDVSc1Y4ekJHdkgxekFneVBoYTJyTjcwL3RUMTN5cm1QZDVRWUVmd3pleGpLclY0bVdJdVJnOE5USFlTWkpVYWV5Q3dUb204MFZGVUpYRytHWVRVeXY1VzIyYUJjbm9SR2lDaUtFWVRMT2tnWGVjZEtGVEhtY0lBZWpROVdlbHIwYTE5NktxODd3NUtOTUNrY0NHRm53Qk5GTG1mbmJwTnFUNnJVQnh4czNYNW50WDlkOEhWdFNZSU5Uc0dYWE1aQ0o3Zm5iV2FqaGcvYW94MEZ0SFgyMWVGNnFJR1Q4ajF6K2wyb3BVK2dnd1Vna2hVVWdDSDJUZnFCaitNTE1WVnZwZ3FKc1BLdDU4MmNhRktBcklGSXZPKzlRdXB4TG5FSDJoejA0VE1UZm5VNmJRQzZ6MWJ1VmU3aCt0T0xuaDFZUEZzTFE4OGFuaWIvN1RUQzhrOURzQlRxMEFTZThSMkdiU0VzbU85cWJiTXdnRWFZVWhPS3RHZXlRc1NKZGhTazZYeFhUaHJXTDlFbndCQ1hEa0lDTXFkbnRBeHl5TTluV3NaNGJMOUpIcUV4Z1dVbWZXQ2h6UEZBcW4zRjR5ODk2VXFIVFp4bHEzV0d5cG41SEhjZW0ySHFmM0lWeEtIMWluaHFkVnRrcnlFaVRXckk3WmRqYnFucVJibCtXZ3RQdEtPT3dlRGxDYVJzM1IycVhjYk5nVmhsZU1rNElXbkY4RDE2OTVBZW5VMUx3SGpPSkxrQ2p4Z05GaVdBRkVQSDlhTklhcXMvWnhBPT0iLCJBdXRob3JpemF0aW9uIjoiQVdTNC1ITUFDLVNIQTI1NiBDcmVkZW50aWFsPVhYWFhYWFhYWFhYWFhYWFhYWFgvMjAxOTEwMDIvdXMtZWFzdC0xEXAMPLE5bmMvYXdzNF9yZXF1ZXN0LCBTaWduZWRIZWFkZXJzPWFjY2VwdDtjb250ZWEXAMPLE29kaW5nO2NvbnRlbnQtdHlwZTtob3EXAMPLEW16LWRhdGU7eC1hbXotc2VjdXJpdHktdG9rZW4sIFNpZ25hdHVyZT04MzE4EXAMPLEiY2MxZmUzZWU2OWY3NWNkEXAMPLE0Y2I0ZjE1MGU0Zjk5Y2VjODY5ZjE0OWM1ZDAzNDEXAMPLEn0=&payload=e30=
```

**Nota**  
Una WebSocket connessione può avere più abbonamenti (anche con diverse modalità di autenticazione). Un modo per implementarlo consiste nel creare una WebSocket connessione per il primo abbonamento e poi chiuderlo quando l'ultimo abbonamento non è registrato. Puoi ottimizzarlo attendendo qualche secondo prima di chiudere la WebSocket connessione, nel caso in cui l'app venga sottoscritta immediatamente dopo la cancellazione dell'ultimo abbonamento. Ad esempio, quando si passa da una schermata all'altra, quando si *smonta* un abbonamento si interrompe e, in caso di *montaggio*, si avvia un abbonamento diverso.

### Autorizzazione Lambda
<a name="lambda-auth"></a>

#### Intestazione di autorizzazione Lambda
<a name="lambda-auth-list"></a>

**Contenuto dell'intestazione**
+  `"Authorization": <string>`: Il valore che viene passato come`authorizationToken`.
+  `"host": <string>`: l'host per l'endpoint AWS AppSync GraphQL o il nome di dominio personalizzato.

**Esempio**

```
{
    "Authorization":"M0UzQzM1MkQtMkI0Ni00OTZCLUI1NkQtMUM0MTQ0QjVBRTczCkI1REEzRTIxLTk5NzItNDJENi1BQjMwLTFCNjRFNzQ2NzlCNQo=",
    "host":"example1234567890000.appsync-api.us-east-1.amazonaws.com"
}
```

**Intestazioni tramite stringa di query**

Innanzitutto, un oggetto JSON contenente `host` and the `Authorization` viene convertito in una stringa. Successivamente, questa stringa viene codificata utilizzando la codifica base64. La stringa risultante con codifica base64 viene aggiunta come parametro di query denominato all' WebSocket URL per stabilire la connessione con l'endpoint `header` in tempo reale. AWS AppSync L'URL della richiesta risultante assume il formato seguente:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoiZXlKcmFXUWlPaUpqYkc1eGIzQTVlVzVNSzA5UVlYSXJNVEpIV0VGTFNYQmllVTVXTkhoc1FqaFBWVzlZTW5NMldsZHZQU0lzSW1Gc1p5STZJbEpUTWpVMkluMC5leUp6ZFdJaU9pSmhObU5tTWpjd055MHhOamd4TFRRMU5ESXRPV1l4T0MxbE5qWTBNVGcyTmpsa016WWlMQ0psZG1WdWRGOXBaQ0k2SW1Wa016TTVNbU5rTFdOallUTXROR00yT0MxaE5EWXlMVEpsWkdJM1pUTm1ZMkZqWmlJc0luUnZhMlZ1WDNWelpTSTZJbUZqWTJWemN5SXNJbk5qYjNCbElqb2lZWGR6TG1OdloyNXBkRzh1YzJsbmJtbHVMblZ6WlhJdVlXUnRhVzRpTENKaGRYUm9YM1JwYldVaU9qRTFOamswTlRjM01UZ3NJbWx6Y3lJNkltaDBkSEJ6T2x3dlhDOWpiMmR1YVhSdkxXbGtjQzVoY0MxemIzVjBhR1ZoYzNRdE1pNWhiV0Y2YjI1aGQzTXVZMjl0WEM5aGNDMXpiM1YwYUdWaGMzUXRNbDgzT0hZMFNWWmliVkFpTENKbGVIQWlPakUxTmprME5qRXpNakFzSW1saGRDSTZNVFUyT1RRMU56Y3lNQ3dpYW5ScElqb2lOVGd6WmpobVltTXRNemsyTVMwMFl6QTRMV0poWlRBdFl6UXlZMkl4TVRNNU5EWTVJaXdpWTJ4cFpXNTBYMmxrSWpvaU0zRmxhalZsTVhabU16ZDFOM1JvWld3MGRHOTFkREprTVd3aUxDSjFjMlZ5Ym1GdFpTSTZJbVZzYjNKNllXWmxJbjAuQjRjZEp0aDNLRk5wSjZpa1ZwN2U2RFJlZTk1VjZRaS16RUUyREpIN3NIT2wyenhZaTdmLVNtRUdvaDJBRDhlbXhRUllhakJ5ei1yRTRKaDBRT3ltTjJZcy1aSWtNcFZCVFBndS1UTVdEeU9IaERVbVVqMk9QODJ5ZVozd2xaQXRyX2dNNEx6alhVWG1JX0syeUdqdVhmWFRhYTFtdlFFQkcwbVFmVmQ3U2Z3WEItamN2NFJZVmk2ajI1cWdvdzlFdzUydWZ1clBxYUstM1dBS0czMktwVjhKNC1XZWpxOHQwYy15QTdzYjhFbkI1NTFiN1RVOTN1S1JpVlZLM0U1NU5rNUFEUG9hbV9XWUU0NWkzczVxVkFQXy1Jblc3NU5Vb09DR1RzUzhZV01mYjZlY0hZSi0xai1iekEyN3phVDlWamN0WG45YnlORlptS0xwQTJMY3h3IiwiaG9zdCI6ImV4YW1wbGUxMjM0NTY3ODkwMDAwLmFwcHN5bmMtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tIn0=&payload=e30=
```

È importante notare che oltre all'oggetto header con codifica base64, anche un oggetto JSON vuoto \$1\$1 è codificato in base64 e incluso come parametro di query separato denominato nell'URL. `payload` WebSocket

**Intestazioni tramite `Sec-WebSocket-Protocol`**

Un oggetto JSON contenente `host` and the `Authorization` viene convertito in una stringa e quindi codificato utilizzando la codifica Base64url. La stringa con codifica Base64URL risultante ha il prefisso. `header-` Questa stringa con prefisso viene quindi utilizzata come nuovo sottoprotocollo oltre che nell'`Sec-WebSocket-Protocol`intestazione quando si stabilisce la connessione con l'`graphql-ws`endpoint in tempo reale. WebSocket AWS AppSync 

L'URL della richiesta risultante assume il seguente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

L'`Sec-WebSocket-Protocol`intestazione contiene il seguente valore:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ewogICAgImhvc3QiOiJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsCiAgICAieC1hcGkta2V5IjoiZGEyLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Igp9"]
```

**Intestazioni tramite intestazioni HTTP standard**

In questo metodo, le informazioni sull'host e sull'autorizzazione vengono trasmesse utilizzando intestazioni HTTP standard quando si stabilisce la WebSocket connessione con l' AWS AppSync endpoint in tempo reale. L'URL della richiesta risultante assume il seguente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Le intestazioni della richiesta includerebbero quanto segue:

```
"sec-websocket-protocol" : ["graphql-ws"]
"Authorization":"eyEXAMPLEiJjbG5xb3A5eW5MK09QYXIrMTJHWEFLSXBieU5WNHhsQjEXAMPLEnM2WldvPSIsImFsZyI6IlEXAMPLEn0.eyEXAMPLEiJhNmNmMjcwNy0xNjgxLTQ1NDItOWYxOC1lNjY0MTg2NjlkMzYiLCJldmVudF9pZCI6ImVkMzM5MmNkLWNjYTMtNGM2OC1hNDYyLTJlZGI3ZTNmY2FjZiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE1Njk0NTc3MTgsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zb3V0aGVhc3QtMl83OHY0SVZibVAiLCJleHAiOjE1Njk0NjEzMjAsImlhdCI6MTU2OTQ1NzcyMCwianRpIjoiNTgzZjhmYmMtMzk2MS00YzA4LWJhZTAtYzQyY2IxMTM5NDY5IiwiY2xpZW50X2lkIjoiM3FlajVlMXZmMzd1N3RoZWw0dG91dDJkMWwiLCJ1c2VybmFtZSI6ImVsb3EXAMPLEn0.B4EXAMPLEFNpJ6ikVp7e6DRee95V6Qi-zEE2DJH7sHOl2zxYi7f-SmEGoh2AD8emxQRYajByz-rE4Jh0QOymN2Ys-ZIkMpVBTPgu-TMWDyOHhDUmUj2OP82yeZ3wlZAtr_gM4LzjXUXmI_K2yGjuXfXTaa1mvQEBG0mQfVd7SfwXB-jcv4RYVi6j25qgow9Ew52ufurPqaK-3WAKG32KpV8J4-Wejq8t0c-yA7sb8EnB551b7TU93uKRiVVK3E55Nk5ADPoam_WYE45i3s5qVAP_-InW75NUoOCGTsS8YWMfb6ecHYJ-1j-bzA27zaT9VjctXn9byNFZmEXAMPLExw",
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com"
```

## Funzionamento in tempo reale WebSocket
<a name="real-time-websocket-operation"></a>

Dopo aver avviato con successo una WebSocket stretta di mano con AWS AppSync, il client deve inviare un messaggio successivo a cui connettersi AWS AppSync per diverse operazioni. Questi messaggi richiedono i seguenti dati:
+  `type`: il tipo di operazione.
+  `id`: un identificatore univoco per l'abbonamento. Si consiglia di utilizzare un UUID per questo scopo.
+  `payload`: Il payload associato, a seconda del tipo di operazione.

Il `type` campo è l'unico campo obbligatorio; i `payload` campi `id` e sono facoltativi.

### Sequenza di eventi
<a name="sequence-of-events"></a>

Per avviare, stabilire, registrare ed elaborare correttamente la richiesta di iscrizione, il cliente deve seguire la seguente sequenza:

1. Inizializza connessione (`connection_init`)

1. Riconoscimento connessione (`connection_ack`)

1. Registrazione sottoscrizione (`start`)

1. Riconoscimento sottoscrizione (`start_ack`)

1. Elaborazione della sottoscrizione (`data`)

1. Annullamento sottoscrizione (`stop`)

## Messaggio init di connessione
<a name="connection-init-message"></a>

(Facoltativo) Dopo una stretta di mano riuscita, il client può inviare il `connection_init` messaggio per iniziare a comunicare con l' AWS AppSyncendpoint in tempo reale. Il messaggio è una stringa ottenuta stringendo l'oggetto JSON come segue:

```
{ "type": "connection_init" }
```

## Messaggio di conferma connessione
<a name="connection-acknowledge-message"></a>

Dopo aver inviato il messaggio `connection_init`, il client deve attendere il messaggio `connection_ack`. Tutti i messaggi inviati prima della ricezione vengono ignorati. `connection_ack` Il messaggio dovrebbe essere letto come segue:

```
{
  "type": "connection_ack",
  "payload": {
    // Time in milliseconds waiting for ka message before the client should terminate the WebSocket connection
    "connectionTimeoutMs": 300000
  }
}
```

## Messaggio keep-alive
<a name="keep-alive-message"></a>

Oltre al messaggio di conferma della connessione, il client riceve periodicamente messaggi keep-alive. Se il client non riceve un messaggio keep-alive entro il periodo di timeout della connessione, deve chiudere la connessione. AWS AppSync continua a inviare questi messaggi e a gestire gli abbonamenti registrati fino a quando non interrompe automaticamente la connessione (dopo 24 ore). I messaggi Keep-alive sono battiti cardiaci e non è necessario che il client li riconosca.

```
{ "type": "ka" }
```

## Messaggio di registrazione dell'abbonamento
<a name="subscription-registration-message"></a>

Dopo aver ricevuto un `connection_ack` messaggio, il client può inviare messaggi di registrazione dell'abbonamento a. AWS AppSync Questo tipo di messaggio è un oggetto JSON con stringhe che contiene i seguenti campi:
+  `"id": <string>`: L'ID dell'abbonamento. Questo ID deve essere univoco per ogni abbonamento, altrimenti il server restituisce un errore che indica che l'ID dell'abbonamento è duplicato.
+  `"type": "start"`: un parametro `<string>` costante.
+  `"payload": <Object>`: Un oggetto che contiene le informazioni relative all'abbonamento.
  +  `"data": <string>`: un oggetto JSON con stringhe che contiene una query GraphQL e variabili.
    +  `"query": <string>`: Un'operazione GraphQL.
    +  `"variables": <Object>`: Un oggetto che contiene le variabili per la query.
  +  `"extensions": <Object>`: Un oggetto che contiene un oggetto di autorizzazione.
+  `"authorization": <Object>`: Un oggetto che contiene i campi richiesti per l'autorizzazione.

### Oggetto autorizzazione per la registrazione della sottoscrizione
<a name="authorization-object-for-subscription-registration"></a>

Le stesse regole della [Formato dei parametri di intestazione basato sulla modalità di autorizzazione AWS AppSync API](#header-parameter-format-based-on-appsync-api-authorization-mode) sezione si applicano all'oggetto di autorizzazione. L'unica eccezione è per IAM, in cui le informazioni sulla firma SigV4 sono leggermente diverse. Per ulteriori dettagli, vedere l'esempio di IAM.

Esempio di utilizzo di pool di utenti Amazon Cognito:

```
{
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69",
  "payload": {
    "data": "{\"query\":\"subscription onCreateMessage {\\n onCreateMessage {\\n __typename\\n message\\n }\\n }\",\"variables\":{}}",
      "extensions": {
        "authorization": {
          "Authorization": "eyEXAMPLEiJjbG5xb3A5eW5MK09QYXIrMTJEXAMPLEBieU5WNHhsQjhPVW9YMnM2WldvPSIsImFsZyI6IlEXAMPLEn0.eyJzdWIiOiJhNmNmMjcwNy0xNjgxLTQ1NDItEXAMPLENjY0MTg2NjlkMzYiLCJldmVudF9pZCI6ImU3YWVmMzEyLWUEXAMPLEY0Zi04YjlhLTRjMWY5M2Q5ZTQ2OCIsInRva2VuX3VzZSI6ImFjY2VzcyIsIEXAMPLEIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE1Njk2MTgzMzgsImlzcyI6Imh0dEXAMPLEXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zbEXAMPLEc3QtMl83OHY0SVZibVAiLCJleHAiOjE1NzAyNTQ3NTUsImlhdCI6MTU3MDI1MTE1NSwianRpIjoiMmIEXAMPLEktZTVkMi00ZDhkLWJiYjItNjA0YWI4MDEwOTg3IiwiY2xpZW50X2lkIjoiM3FlajVlMXZmMzd1EXAMPLE0dG91dDJkMWwiLCJ1c2VybmFtZSI6ImVsb3J6YWZlIn0.CT-qTCtrYeboUJ4luRSTPXaNewNeEXAMPLE14C6sfg05tO0fOMpiUwj9k19gtNCCMqoSsjtQoUweFnH4JYa5EXAMPLEVxOyQEQ4G7jQrt5Ks6STn53vuseR3zRW9snWgwz7t3ZmQU-RWvW7yQU3sNQRLEXAMPLEcd0yufBiCYs3dfQxTTdvR1B6Wz6CD78lfNeKqfzzUn2beMoup2h6EXAMPLE4ow8cUPUPvG0DzRtHNMbWskjPanu7OuoZ8iFO_Eot9kTtAlVKYoNbWkZhkD8dxutyoU4RSH5JoLAnrGF5c8iKgv0B2dfEXAMPLEIihxaZVJ9w9w48S4EXAMPLEcA",
          "host": "example1234567890000.appsync-api.us-east-1.amazonaws.com"
         }
      }
  },
  "type": "start"
}
```

Esempio di utilizzo di IAM:

```
{
  "id": "eEXAMPLE-cf23-1234-5678-152EXAMPLE69",
  "payload": {
    "data": "{\"query\":\"subscription onCreateMessage {\\n onCreateMessage {\\n __typename\\n message\\n }\\n }\",\"variables\":{}}",
    "extensions": {
      "authorization": {
        "accept": "application/json, text/javascript",
        "content-type": "application/json; charset=UTF-8",
        "X-Amz-Security-Token": "AgEXAMPLEZ2luX2VjEAoaDmFwLXNvdXRoZWFEXAMPLEcwRQIgAh97Cljq7wOPL8KsxP3YtDuyc/9hAj8PhJ7Fvf38SgoCIQDhJEXAMPLEPspioOztj++pEagWCveZUjKEn0zyUhBEXAMPLEjj//////////8BEXAMPLExODk2NDgyNzg1NSIMo1mWnpESWUoYw4BkKqEFSrm3DXuL8w+ZbVc4JKjDP4vUCKNR6Le9C9pZp9PsW0NoFy3vLBUdAXEXAMPLEOVG8feXfiEEA+1khgFK/wEtwR+9zF7NaMMMse07wN2gG2tH0eKMEXAMPLEQX+sMbytQo8iepP9PZOzlZsSFb/dP5Q8hk6YEXAMPLEYcKZsTkDAq2uKFQ8mYUVA9EtQnNRiFLEY83aKvG/tqLWNnGlSNVx7SMcfovkFDqQamm+88y1OwwAEYK7qcoceX6Z7GGcaYuIfGpaX2MCCELeQvZ+8WxEgOnIfz7GYvsYNjLZSaRnV4G+ILY1F0QNW64S9Nvj+BwDg3ht2CrNvpwjVYlj9U3nmxE0UG5ne83LL5hhqMpm25kmL7enVgw2kQzmU2id4IKu0C/WaoDRuO2F5zE63vJbxN8AYs7338+4B4HBb6BZ6OUgg96Q15RA41/gIqxaVPxyTpDfTU5GfSLxocdYeniqqpFMtZG2n9d0u7GsQNcFkNcG3qDZm4tDo8tZbuym0a2VcF2E5hFEgXBa+XLJCfXi/77OqAEjP0x7Qdk3B43p8KG/BaioP5RsV8zBGvH1zAgyPha2rN70/tT13yrmPd5QYEfwzexjKrV4mWIuRg8NTHYSZJUaeyCwTom80VFUJXG+GYTUyv5W22aBcnoRGiCiKEYTLOkgXecdKFTHmcIAejQ9Welr0a196Kq87w5KNMCkcCGFnwBNFLmfnbpNqT6rUBxxs3X5ntX9d8HVtSYINTsGXXMZCJ7fnbWajhg/aox0FtHX21eF6qIGT8j1z+l2opU+ggwUgkhUUgCH2TfqBj+MLMVVvpgqJsPKt582caFKArIFIvO+9QupxLnEH2hz04TMTfnU6bQC6z1buVe7h+tOLnh1YPFsLQ88anib/7TTC8k9DsBTq0ASe8R2GbSEsmO9qbbMwgEaYUhOKtGeyQsSJdhSk6XxXThrWL9EnwBCXDkICMqdntAxyyM9nWsZ4bL9JHqExgWUmfWChzPFAqn3F4y896UqHTZxlq3WGypn5HHcem2Hqf3IVxKH1inhqdVtkryEiTWrI7ZdjbqnqRbl+WgtPtKOOweDlCaRs3R2qXcbNgVhleMk4IWnF8D1695AenU1LwHjOJLkCjxgNFiWAFEPH9aEXAMPLExA==",
        "Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXXX/20200401/us-east-1/appsync/aws4_request, SignedHeaders=accept;content-encoding;content-type;host;x-amz-date;x-amz-security-token, Signature=b90131a61a7c4318e1c35ead5dbfdeb46339a7585bbdbeceeaff51f4022eb1fd",
        "content-encoding": "amz-1.0",
        "host": "example1234567890000.appsync-api.us-east-1.amazonaws.com",
        "x-amz-date": "20200401T001010Z"
      }
    }
  },
  "type": "start"
}
```

Esempio di utilizzo di un nome di dominio personalizzato:

```
{
  "id": "key-cf23-4cb8-9fcb-152ae4fd1e69",
  "payload": {
    "data": "{\"query\":\"subscription onCreateMessage {\\n onCreateMessage {\\n __typename\\n message\\n }\\n }\",\"variables\":{}}",
      "extensions": {
        "authorization": {
          "x-api-key": "da2-12345678901234567890123456",
          "host": "api.example.com"
         }
      }
  },
  "type": "start"
}
```

Non è necessario aggiungere la firma SigV4 `/connect` all'URL e l'operazione GraphQL con stringa JSON la sostituisce. `data` Di seguito è riportato un esempio di richiesta di firma SigV4:

```
{
  url: "https://example1234567890000.appsync-api.us-east-1.amazonaws.com/graphql",
  data: "{\"query\":\"subscription onCreateMessage {\\n onCreateMessage {\\n __typename\\n message\\n }\\n }\",\"variables\":{}}",
  method: "POST",
  headers: {
    "accept": "application/json, text/javascript",
    "content-encoding": "amz-1.0",
    "content-type": "application/json; charset=UTF-8",
  }
}
```

## Messaggio di conferma dell'iscrizione
<a name="subscription-acknowledge-message"></a>

Dopo aver inviato il messaggio di avvio dell'abbonamento, il cliente deve AWS AppSync attendere l'invio del `start_ack` messaggio. Il `start_ack` messaggio indica che l'abbonamento è andato a buon fine.

Esempio di riconoscimento dell'abbonamento:

```
{
  "type": "start_ack",
  "id": "eEXAMPLE-cf23-1234-5678-152EXAMPLE69"
}
```

## Messaggio di errore
<a name="error-message"></a>

Se l'avvio della connessione o la registrazione dell'abbonamento falliscono o se una sottoscrizione viene interrotta dal server, il server invia un messaggio di errore al client. Se l'errore si verifica durante l'avvio della connessione, la connessione verrà chiusa dal server.
+  `"type": "error"`: un parametro `<string>` costante.
+  `"id": <string>`: L'ID dell'abbonamento registrato corrispondente, se pertinente.
+  `"payload" <Object>`: Un oggetto che contiene le informazioni di errore corrispondenti.

Esempio:

```
{
  "type": "error",
  "payload": {
    "errors": [
      {
        "errorType": "LimitExceededError",
        "message": "Rate limit exceeded"
      }
    ]
  }
}
```

## Elaborazione dei messaggi dati
<a name="processing-data-messages"></a>

Quando un client invia una mutazione, AWS AppSync identifica tutti gli abbonati interessati e invia un `"type":"data"` messaggio a ciascuno di essi utilizzando l'abbonamento corrispondente `id` dall'operazione di sottoscrizione. `"start"` Il client dovrebbe tenere traccia dell'abbonamento inviato in modo `id` che, quando riceve un messaggio di dati, possa abbinarlo all'abbonamento corrispondente.
+  `"type": "data"`: un parametro `<string>` costante.
+  `"id": <string>`: L'ID dell'abbonamento registrato corrispondente.
+  `"payload" <Object>`: Un oggetto che contiene le informazioni sulla sottoscrizione.

Esempio:

```
{
  "type": "data",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69",
  "payload": {
    "data": {
      "onCreateMessage": {
        "__typename": "Message",
        "message": "test"
      }
    }
  }
}
```

## Messaggio di annullamento registrazione sottoscrizione
<a name="subscription-unregistration-message"></a>

Quando l'app desidera interrompere l'ascolto degli eventi di sottoscrizione, il client deve inviare un messaggio con il seguente oggetto JSON con stringhe:
+  `"type": "stop"`: un parametro `<string>` costante.
+  `"id": <string>`: L'ID dell'abbonamento di cui annullare la registrazione.

Esempio:

```
{
  "type":"stop",
  "id":"ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69"
}
```

AWS AppSync restituisce un messaggio di conferma con il seguente oggetto JSON con stringhe:
+  `"type": "complete"`: un parametro `<string>` costante.
+  `"id": <string>`: L'ID dell'abbonamento non registrato.

Dopo aver ricevuto il messaggio di conferma, il cliente non riceve più messaggi per questo particolare abbonamento.

Esempio:

```
{
  "type":"complete",
  "id":"eEXAMPLE-cf23-1234-5678-152EXAMPLE69"
}
```

## Disconnettere il WebSocket
<a name="disconnecting-the-websocket"></a>

Prima della disconnessione, per evitare la perdita di dati, il client deve disporre della logica necessaria per verificare che al momento non sia in corso alcuna operazione tramite la WebSocket connessione. Tutti gli abbonamenti devono essere annullati prima di disconnettersi da. WebSocket

# Fusione APIs AWS AppSync
<a name="merged-api"></a>

Man mano che l'uso di GraphQL si espande all'interno di un'organizzazione, possono sorgere compromessi tra API ease-of-use e velocità di sviluppo delle API. Da un lato, le organizzazioni adottano AWS AppSync GraphQL per semplificare lo sviluppo delle applicazioni. Ciò offre agli sviluppatori un'API flessibile che possono utilizzare per accedere, manipolare e combinare in modo sicuro i dati di uno o più domini di dati con una singola chiamata di rete. D'altra parte, i team all'interno di un'organizzazione responsabili dei diversi domini di dati combinati in un unico endpoint dell'API GraphQL potrebbero desiderare la possibilità di creare, gestire e distribuire gli aggiornamenti delle API indipendentemente l'uno dall'altro. Ciò aumenta la loro velocità di sviluppo. 

Per risolvere questa tensione, la APIs funzionalità AWS AppSync Merged consente ai team di diversi domini di dati di creare e implementare in modo indipendente AWS AppSync APIs (ad esempio schemi GraphQL, resolver, fonti di dati e funzioni), che possono quindi essere combinati in un'unica API unita. Ciò offre alle organizzazioni la possibilità di mantenere un'API multidominio semplice da usare e un modo per i diversi team che contribuiscono a tale API di effettuare aggiornamenti delle API in modo rapido e indipendente.

Il diagramma seguente mostra il flusso di lavoro delle API unite:

![\[Diagramma che mostra il flusso di lavoro delle API unite con più fonti APIs combinate in un unico endpoint API unito\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/merged-api-workflow.png)


Utilizzando Merged APIs, le organizzazioni possono importare le risorse di più fonti indipendenti AWS AppSync APIs in un unico endpoint API unito. AWS AppSync A tale scopo, AWS AppSync consente di creare un elenco di fonti e quindi unire tutti i metadati associati alla fonte AWS AppSync APIs, APIs inclusi schema, tipi, origini dati, resolver e funzioni, in una nuova API unita. AWS AppSync 

Durante le unioni, esiste la possibilità che si verifichi un conflitto di unione a causa di incongruenze nel contenuto dei dati dell'API di origine, ad esempio conflitti di denominazione dei tipi quando si combinano più schemi. Per casi d'uso semplici in cui nessuna definizione nell'origine è in APIs conflitto, non è necessario modificare gli schemi dell'API di origine. L'API Merged risultante importa semplicemente tutti i tipi, i resolver, le fonti di dati e le funzioni dalla fonte originale. AWS AppSync APIs Nei casi d'uso complessi in cui sorgono conflitti, users/teams dovranno risolverli con vari mezzi. AWS AppSync fornisce agli utenti diversi strumenti ed esempi in grado di ridurre i conflitti di fusione. 

Le fusioni successive configurate in AWS AppSync propagheranno le modifiche apportate nell'origine APIs all'API unita associata.

## Unione e federazione APIs
<a name="merged-api-federation"></a>

Esistono molte soluzioni e modelli nella community GraphQL per combinare schemi GraphQL e consentire la collaborazione in team attraverso un grafico condiviso. AWS AppSync Merged APIs adotta un approccio alla composizione dello schema basato sulla fase di *compilazione*, in cui APIs i sorgenti vengono combinati in un'API unita separata. Un approccio alternativo consiste nel sovrapporre un router in fase di *esecuzione* su più sorgenti APIs o sottografi. In questo approccio, il router riceve una richiesta, fa riferimento a uno schema combinato che mantiene come metadati, costruisce un piano di richiesta e quindi distribuisce gli elementi della richiesta tra i sottografi/server sottostanti. La tabella seguente confronta l'approccio in fase di compilazione dell'API AWS AppSync unita con gli approcci di run-time basati su router alla composizione dello schema GraphQL:


|  |  |  | 
| --- |--- |--- |
| Funzionalità | AppSync API unita | Soluzioni basate su router | 
| Sottografi gestiti in modo indipendente | Sì  | Sì | 
| Sottografi indirizzabili indipendentemente | Sì  | Sì | 
| Composizione automatica dello schema | Sì  | Sì | 
| Rilevamento automatico dei conflitti | Sì  | Sì | 
| Risoluzione dei conflitti tramite direttive dello schema | Sì  | Sì | 
| Server di sottografi supportati | AWS AppSync\$1 | Può variare | 
| Complessità della rete | Un'unica API unita significa nessun salto di rete aggiuntivo. | L'architettura a più livelli richiede la pianificazione e la delega delle query, l'analisi e la serializzazione/deserializzazione delle sottoquery e l'utilizzo di resolver di riferimento in sottografi per eseguire i join. | 
| Supporto all'osservabilità | Monitoraggio, registrazione e tracciamento integrati. Un unico server API integrato significa un debug semplificato. | Build-your-own osservabilità sul router e su tutti i server di sottografo associati. Debug complesso su sistemi distribuiti. | 
| Supporto per l'autorizzazione | Supporto integrato per più modalità di autorizzazione. | Build-your-own regole di autorizzazione. | 
| Sicurezza su più account | Supporto integrato per le associazioni di account tra AWS cloud. | Build-your-own modello di sicurezza. | 
| Supporto per gli abbonamenti | Sì | No | 

\$1 L' AWS AppSync unione APIs può essere associata AWS AppSync solo alla fonte. APIs Se hai bisogno di supporto per la composizione dello schema tra AWS AppSync e non AWS AppSync sotto grafici, puoi connettere uno o più GraphQL and/or Merged a una AWS AppSync soluzione basata su router. APIs [Ad esempio, consulta il blog di riferimento per l'aggiunta AWS AppSync APIs come sottografo utilizzando un'architettura basata su router con Apollo Federation v2: Apollo GraphQL Federation with. AWS AppSync](https://aws.amazon.com/blogs/mobile/federation-appsync-subgraph/) 

**Topics**
+ [Unione e federazione APIs](#merged-api-federation)
+ [Risoluzione unificata dei conflitti tramite API](#merged-api-conflict-resolution)
+ [Configurazione degli schemi](#configuring-schemas-merged-api)
+ [Configurazione delle modalità di autorizzazione](#configuring-authorization-merged-api)
+ [Configurazione dei ruoli di esecuzione](#execution-roles-merged-api)
+ [Configurazione della fusione tra account tramite APIs AWS RAM](#cross-account-merged-api)
+ [Unire](#merges)
+ [Supporto aggiuntivo per Merged APIs](#merge-api-additional-support)
+ [Limitazioni delle API unite](#merged-api-limits)
+ [Considerazioni sull'API unita](#merged-api-considerations)
+ [Creazione di un sistema unito APIs](#creating-merged-api)

## Risoluzione unificata dei conflitti tramite API
<a name="merged-api-conflict-resolution"></a>

In caso di conflitto di fusione, AWS AppSync fornisce agli utenti diversi strumenti ed esempi per aiutare a risolvere il/i problema/i.

### Direttive dello schema API unite
<a name="merged-api-schema-directive"></a>

 AWS AppSync ha introdotto diverse direttive GraphQL che possono essere utilizzate per ridurre o risolvere i conflitti tra i sorgenti: APIs
+ *@canonical*: questa direttiva imposta la precedenza di tipi/campi con nomi e dati simili. Se due o più sorgenti APIs hanno lo stesso tipo o campo GraphQL, una di esse APIs può annotare il loro tipo o campo come *canonico*, a cui verrà data la priorità durante l'unione. Le informazioni in conflitto types/fields che non sono annotate con questa direttiva in un'altra fonte vengono ignorate quando vengono unite. APIs 
+ *@hidden*: questa direttiva incapsula alcuni elementi types/fields per rimuoverla dal processo di fusione. I team potrebbero voler rimuovere o nascondere tipi o operazioni specifici nell'API di origine in modo che solo i client interni possano accedere a dati digitati specifici. Con questa direttiva allegata, i tipi o i campi non vengono uniti nell'API Merged. 
+ *@renamed*: questa direttiva modifica i nomi di types/fields per ridurre i conflitti di denominazione. Ci sono situazioni in cui diversi APIs hanno lo stesso tipo o nome di campo. Tuttavia, devono essere tutti disponibili nello schema unito. Un modo semplice per includerli tutti nell'API Merged consiste nel rinominare il campo con qualcosa di simile ma diverso. 

Per mostrare lo schema di utilità fornito dalle direttive, considera il seguente esempio:

In questo esempio, supponiamo di voler unire due sorgenti. APIs Ci vengono forniti due schemi per creare e recuperare i post (ad esempio, sezione commenti o post sui social media). Supponendo che i tipi e i campi siano molto simili, c'è un'alta probabilità di conflitto durante un'operazione di unione. I frammenti seguenti mostrano i tipi e i campi di ogni schema.

Il primo file, chiamato *Source1.graphQL*, è uno schema GraphQL che consente a un utente di creare utilizzando la mutazione. `Posts` `putPost` Ciascuno `Post` contiene un titolo e un ID. L'ID viene utilizzato per fare riferimento alle informazioni del poster (e-mail e indirizzo) e al`Message`, o al payload (contenuto). `User` Il `User` tipo è annotato con il tag *@canonical*.

```
# This snippet represents a file called Source1.graphql

type Mutation {
    putPost(id: ID!, title: String!): Post
}

type Post {
    id: ID!
    title: String!
}

type Message {
   id: ID!
   content: String
}

type User @canonical {
   id: ID!
   email: String!
   address: String!
}

type Query {
    singlePost(id: ID!): Post
    getMessage(id: ID!): Message
}
```

*Il secondo file, chiamato *Source2.graphQL, è uno schema GraphQL* che fa cose molto simili a Source1.graphQL.* Tuttavia, notate che i campi di ogni tipo sono diversi. Quando si uniscono questi due schemi, si verificheranno conflitti di unione dovuti a queste differenze. 

Nota anche come *Source2.graphQL* contenga anche diverse direttive per ridurre questi conflitti. Il `Post` tipo è annotato con un tag *@hidden per offuscarsi durante* l'operazione di unione. Il `Message` tipo è annotato con il tag *@renamed* per modificare il nome del tipo `ChatMessage` in caso di conflitto di denominazione con un altro tipo. `Message`

```
# This snippet represents a file called Source2.graphql

type Post @hidden  {
    id: ID!
    title: String!
    internalSecret: String!
}

type Message @renamed(to: "ChatMessage") {
   id: ID!
   chatId: ID!
   from: User!
   to: User!
}

# Stub user so that we can link the canonical definition from Source1
type User {
   id: ID!
}

type Query {
    getPost(id: ID!): Post
    getMessage(id: ID!): Message @renamed(to: "getChatMessage")
}
```

Quando si verifica l'unione, il risultato produrrà il file: `MergedSchema.graphql`

```
# This snippet represents a file called MergedSchema.graphql

type Mutation {
    putPost(id: ID!, title: String!): Post
}

# Post from Source2 was hidden so only uses the Source1 definition. 
type Post {
    id: ID!
    title: String!
}

# Renamed from Message to resolve the conflict
type ChatMessage {
   id: ID!
   chatId: ID!
   from: User!
   to: User!
}

type Message {
   id: ID!
   content: String
}

# Canonical definition from Source1
type User {
   id: ID!
   email: String!
   address: String!
}

type Query {
    singlePost(id: ID!): Post
    getMessage(id: ID!): Message
    
    # Renamed from getMessage
    getChatMessage(id: ID!): ChatMessage
}
```

Durante l'unione si sono verificate diverse cose:
+ **Il `User` tipo di *Source1.graphQL ha avuto la priorità rispetto a quello di Source2.graphQL* grazie all'annotazione `User` @canonical.**
+ Il `Message` tipo di *Source1.graphQL* è stato incluso nell'unione. Tuttavia, il file di *Source2.graphQL presentava un `Message` conflitto di denominazione*. Grazie alla sua annotazione *@renamed*, è stata inclusa anche nell'unione ma con il nome alternativo. `ChatMessage`
+ *Il `Post` tipo di *Source1.graphQL* è stato incluso, ma non il tipo di Source2.graphQL. `Post`* Normalmente, si verificava un conflitto su questo tipo, ma poiché il `Post` tipo di *Source2.GraphQL aveva un'annotazione *@hidden*, i suoi dati erano offuscati* e non inclusi nell'unione. Ciò non ha provocato conflitti.
+ Il `Query` tipo è stato aggiornato per includere il contenuto di entrambi i file. Tuttavia, una `GetMessage` query è stata rinominata in `GetChatMessage` base alla direttiva. Ciò ha risolto il conflitto di denominazione tra le due query con lo stesso nome.

C'è anche il caso in cui nessuna direttiva venga aggiunta a un tipo in conflitto. Qui, il tipo unito includerà l'unione di tutti i campi di tutte le definizioni di origine di quel tipo. Ad esempio, si consideri il seguente esempio:

Questo schema, chiamato *Source1.graphQL*, consente la creazione e il recupero. `Posts` La configurazione è simile all'esempio precedente, ma con meno informazioni.

```
# This snippet represents a file called Source1.graphql

type Mutation {
    putPost(id: ID!, title: String!): Post
}

type Post  {
    id: ID!
    title: String!
}

type Query {
    getPost(id: ID!): Post
}
```

Questo schema, chiamato *Source2.GraphQL*, consente di creare e recuperare `Reviews` (ad esempio, la valutazione dei film o le recensioni dei ristoranti). `Reviews`sono associati allo stesso valore ID. `Post` Insieme, contengono il titolo, l'ID del post e il messaggio di payload del post completo della recensione.

Durante la fusione, si verificherà un conflitto tra i due `Post` tipi. Poiché non esistono annotazioni per risolvere questo problema, il comportamento predefinito consiste nell'eseguire un'operazione di unione sui tipi in conflitto.

```
# This snippet represents a file called Source2.graphql

type Mutation {
    putReview(id: ID!, postId: ID!, comment: String!): Review
}

type Post  {
    id: ID!
    reviews: [Review]
}

type Review {
   id: ID!
   postId: ID!
   comment: String!
}

type Query {
    getReview(id: ID!): Review
}
```

Quando si verifica l'unione, il risultato produrrà il file: `MergedSchema.graphql`

```
# This snippet represents a file called MergedSchema.graphql

type Mutation {
    putReview(id: ID!, postId: ID!, comment: String!): Review
    putPost(id: ID!, title: String!): Post
}

type Post  {
    id: ID!
    title: String!
    reviews: [Review]
}

type Review {
   id: ID!
   postId: ID!
   comment: String!
}

type Query {
    getPost(id: ID!): Post
    getReview(id: ID!): Review
}
```

Durante l'unione si sono verificate diverse cose:
+ Il `Mutation` tipo non ha avuto conflitti ed è stato unito.
+ I campi `Post` tipo sono stati combinati tramite un'operazione di unione. Notate come l'unione tra i due abbia prodotto un singolo `id``title`, un e un singolo`reviews`.
+ Il `Review` tipo non ha subito conflitti ed è stato unito.
+ Il `Query` tipo non ha riscontrato conflitti ed è stato unito.

### Gestione dei resolver su tipi condivisi
<a name="resolvers-shared-types-merged-api"></a>

Nell'esempio precedente, considera il caso in cui *Source1.GraphQL* ha configurato un resolver di unità su, `Query.getPost` che utilizza un'origine dati DynamoDB denominata. `PostDatasource` Questo resolver restituirà un tipo e. `id` `title` `Post` Consideriamo ora che *Source2.graphQL* ha configurato un resolver di pipeline su, che esegue due funzioni. `Post.reviews` `Function1`ha una fonte di `None` dati allegata per eseguire controlli di autorizzazione personalizzati. `Function2`ha un'origine dati DynamoDB allegata per interrogare la tabella. `reviews`

```
query GetPostQuery {
    getPost(id: "1") {
        id,
        title,
        reviews
    }
}
```

Quando la query precedente viene eseguita da un client all'endpoint Merged API, il AWS AppSync servizio esegue innanzitutto il resolver di unità per `Query.getPost` from`Source1`, che chiama `PostDatasource` e restituisce i dati da DynamoDB. Quindi, esegue il resolver della `Post.reviews` pipeline in cui `Function1` esegue una logica di autorizzazione personalizzata e restituisce le recensioni fornite. `Function2` `id` `$context.source` Il servizio elabora la richiesta come una singola esecuzione GraphQL e questa semplice richiesta richiederà solo un singolo token di richiesta.

### Gestione dei conflitti dei resolver su tipi condivisi
<a name="resolver-conflict-shared-type-merged-api"></a>

Considera il seguente caso in cui implementiamo anche un resolver on per fornire più campi contemporaneamente oltre al resolver di campo `Query.getPost` in cui è inserito. `Source2` *Source1.graphQL può assomigliare a* questo:

```
# This snippet represents a file called Source1.graphql

type Post  {
    id: ID!
    title: String!
    date: AWSDateTime!
}

type Query {
    getPost(id: ID!): Post
}
```

*Source2.graphQL può assomigliare a* questo:

```
# This snippet represents a file called Source2.graphql

type Post  {
  id: ID!
  content: String!
  contentHash: String! 
  author: String! 
}

type Query {
    getPost(id: ID!): Post
}
```

Il tentativo di unire questi due schemi genererà un errore di unione perché Merged APIs non consente di collegare più AWS AppSync resolver di origine allo stesso campo. Per risolvere questo conflitto, puoi implementare un pattern di risoluzione dei campi che richieda a *Source2.GraphQL di aggiungere un tipo separato che definirà i campi di sua proprietà* rispetto al tipo. `Post` *Nell'esempio seguente, aggiungiamo un tipo chiamato`PostInfo`, che contiene i campi content e author che verranno risolti da Source2.graphQL.* *Source1.graphQL* implementerà il resolver collegato a`Query.getPost`, mentre *Source2.graphQL* ora collegherà un resolver per garantire che tutti i dati possano essere recuperati con successo: `Post.postInfo`

```
type Post  {
  id: ID!
  postInfo: PostInfo
}

type PostInfo {
   content: String!
   contentHash: String!
   author: String!
}

type Query {
    getPost(id: ID!): Post
}
```

Sebbene la risoluzione di tale conflitto richieda la riscrittura degli schemi delle API di origine e, potenzialmente, la modifica delle query da parte dei clienti, il vantaggio di questo approccio è che la proprietà dei resolver uniti rimane chiara tra i team di origine.

## Configurazione degli schemi
<a name="configuring-schemas-merged-api"></a>

Due parti sono responsabili della configurazione degli schemi per la creazione di un'API unita:
+ Proprietari delle **API unite: i proprietari** delle API unite devono configurare la logica di autorizzazione dell'API unita e le impostazioni avanzate come la registrazione, il tracciamento, la memorizzazione nella cache e il supporto WAF.
+ Proprietari delle **API di origine associate: i proprietari** delle API associate devono configurare gli schemi, i resolver e le origini dati che compongono l'API unita.

**Poiché lo schema dell'API Merged viene creato dagli schemi della fonte associata, è di sola lettura. APIs** Ciò significa che le modifiche allo schema devono essere avviate nella fonte. APIs **Nella AWS AppSync console, puoi passare dallo schema Merged ai singoli schemi della fonte APIs inclusi nell'API Merged utilizzando l'elenco a discesa sopra la finestra Schema.**

## Configurazione delle modalità di autorizzazione
<a name="configuring-authorization-merged-api"></a>

Sono disponibili diverse modalità di autorizzazione per proteggere l'API unita. Per ulteriori informazioni sulle modalità di autorizzazione in AWS AppSync, consulta [Autorizzazione e autenticazione](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html).

Le seguenti modalità di autorizzazione sono disponibili per l'uso con Merged: APIs
+  **Chiave API**: la strategia di autorizzazione più semplice. Tutte le richieste devono includere una chiave API sotto l'intestazione della `x-api-key` richiesta. Le chiavi API scadute vengono conservate per 60 giorni dopo la data di scadenza. 
+  **AWS Identity and Access Management (IAM)**: AWS la strategia di autorizzazione IAM autorizza tutte le richieste **firmate** con sigv4. 
+  Pool di **utenti Amazon Cognito: autorizza i tuoi utenti tramite i pool** di utenti di Amazon Cognito per ottenere un controllo più preciso. 
+  **AWS Autorizzatori Lambda**: una funzione serverless che consente di autenticare e autorizzare l'accesso all'API utilizzando una logica personalizzata. AWS AppSync 
+ **OpenID Connect**: questo tipo di autorizzazione applica i token OpenID connect (OIDC) forniti da un servizio conforme a OIDC. La tua applicazione può usare gli utenti e i privilegi definiti dal provider OIDC per controllare l'accesso.

Le modalità di autorizzazione di un'API unita sono configurate dal proprietario dell'API unita. Al momento di un'operazione di unione, l'API unita deve includere la modalità di autorizzazione principale configurata su un'API di origine come modalità di autorizzazione principale propria o come modalità di autorizzazione secondaria. In caso contrario, sarà incompatibile e l'operazione di unione avrà esito negativo a causa di un conflitto. Quando si utilizzano direttive multi-auth nell'origine APIs, il processo di fusione è in grado di unire automaticamente queste direttive nell'endpoint unificato. Nel caso in cui la modalità di autorizzazione primaria dell'API di origine non corrisponda alla modalità di autorizzazione principale dell'API unita, aggiungerà automaticamente queste direttive di autenticazione per garantire che la modalità di autorizzazione per i tipi nell'API di origine sia coerente.

## Configurazione dei ruoli di esecuzione
<a name="execution-roles-merged-api"></a>

Quando si crea un'API unita, è necessario definire un ruolo di servizio. Un ruolo AWS di servizio è un ruolo di AWS Identity and Access Management (IAM) utilizzato AWS dai servizi per eseguire attività per conto dell'utente.

In questo contesto, è necessario che l'API Merged esegua resolver che accedano ai dati dalle fonti di dati configurate nell'origine. APIs Il ruolo di servizio richiesto a tal fine è`mergedApiExecutionRole`, e deve disporre dell'accesso esplicito all'esecuzione delle richieste sull'origine APIs inclusa nell'API unita tramite l'autorizzazione IAM. `appsync:SourceGraphQL` Durante l'esecuzione di una richiesta GraphQL, il AWS AppSync servizio assumerà questo ruolo di servizio e autorizzerà il ruolo a eseguire l'azione. `appsync:SourceGraphQL`

AWS AppSync supporta l'autorizzazione o la negazione di questa autorizzazione su specifici campi di primo livello all'interno della richiesta, ad esempio il funzionamento della modalità di autorizzazione IAM per IAM. APIs Per non-top-level i campi, AWS AppSync richiede di definire l'autorizzazione sull'ARN dell'API di origine stesso. *Per limitare l'accesso a non-top-level campi specifici nell'API Merged, ti consigliamo di implementare una logica personalizzata all'interno di Lambda o di nascondere i campi dell'API di origine all'API Merged utilizzando la direttiva @hidden.* Se desideri consentire al ruolo di eseguire tutte le operazioni sui dati all'interno di un'API di origine, puoi aggiungere la politica seguente. Tieni presente che la prima voce di risorsa consente l'accesso a tutti i campi di primo livello e la seconda voce riguarda i resolver secondari che autorizzano la risorsa API di origine stessa: 

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [{
        "Effect": "Allow", 
        "Action": [ "appsync:SourceGraphQL"], 
        "Resource": [ 
            "arn:aws:appsync:us-west-2:123456789012:apis/YourSourceGraphQLApiId/*", 
            "arn:aws:appsync:us-west-2:123456789012:apis/YourSourceGraphQLApiId"] 
    }] 
}
```

------

Se desideri limitare l'accesso solo a uno specifico campo di primo livello, puoi utilizzare una politica come questa:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [{
        "Effect": "Allow", 
        "Action": [ "appsync:SourceGraphQL"], 
        "Resource": [ 
            "arn:aws:appsync:us-west-2:123456789012:apis/YourSourceGraphQLApiId/types/Query/fields/<Field-1>",
            "arn:aws:appsync:us-west-2:123456789012:apis/YourSourceGraphQLApiId"] 
    }] 
}
```

------

Puoi anche utilizzare la procedura guidata di creazione dell'API della AWS AppSync console per generare un ruolo di servizio che consenta all'API unita di accedere alle risorse configurate nel codice sorgente APIs che si trovano nello stesso account dell'API unita. Nel caso in cui la fonte non si APIs trovi nello stesso account dell'API unita, devi prima condividere le tue AWS risorse utilizzando Resource Access Manager (AWS RAM). 

## Configurazione della fusione tra account tramite APIs AWS RAM
<a name="cross-account-merged-api"></a>

Quando crei un'API unita, puoi facoltativamente associare la fonte APIs da altri account che sono stati condivisi tramite AWS Resource Access Manager ()AWS RAM. AWS RAM ti aiuta a condividere le tue risorse in modo sicuro tra AWS gli account, all'interno dell'organizzazione o delle unità organizzative (OUs) e con i ruoli e gli utenti IAM.

AWS AppSync si integra con AWS RAM per supportare la configurazione e l'accesso ai sorgenti APIs su più account da un'unica API unita. AWS RAM consente di creare una condivisione di risorse o un contenitore di risorse e i set di autorizzazioni che verranno condivisi per ciascuna di esse. È possibile aggiungere AWS AppSync APIs a una condivisione di risorse in AWS RAM. All'interno di una condivisione di risorse, AWS AppSync fornisce tre diversi set di autorizzazioni che possono essere associati a un' AWS AppSync API nella RAM:

1. `AWSRAMPermissionAppSyncSourceApiOperationAccess`: il set di autorizzazioni predefinito che viene aggiunto quando si condivide un' AWS AppSync API AWS RAM se non viene specificata nessun'altra autorizzazione. Questo set di autorizzazioni viene utilizzato per condividere un' AWS AppSync API di origine con un proprietario di un'API unita. Questo set di autorizzazioni include l'autorizzazione per `appsync:AssociateMergedGraphqlApi` l'API di origine e l'`appsync:SourceGraphQL`autorizzazione richiesta per accedere alle risorse dell'API di origine in fase di esecuzione.

1. `AWSRAMPermissionAppSyncMergedApiOperationAccess`: questo set di autorizzazioni deve essere configurato quando si condivide un'API unita con un proprietario dell'API di origine. Questo set di autorizzazioni darà all'API di origine la possibilità di configurare l'API unita, inclusa la possibilità di associare qualsiasi origine di APIs proprietà del principale di destinazione all'API unita e di leggere e aggiornare le associazioni delle API di origine dell'API unita.

1. `AWSRAMPermissionAppSyncAllowSourceGraphQLAccess`: Questo set di autorizzazioni consente di utilizzare l'`appsync:SourceGraphQL`autorizzazione con un'API. AWS AppSync È destinato a essere utilizzato per condividere un'API di origine con un proprietario di un'API unita. A differenza del set di autorizzazioni predefinito per l'accesso alle operazioni dell'API di origine, questo set di autorizzazioni include solo l'autorizzazione `appsync:SourceGraphQL` di runtime. Se un utente sceglie di condividere l'accesso all'operazione Merged API con un proprietario dell'API di origine, dovrà inoltre condividere questa autorizzazione dall'API di origine al proprietario dell'API unita per avere accesso al runtime tramite l'endpoint dell'API unita.

AWS AppSync supporta anche le autorizzazioni gestite dal cliente. Quando una delle autorizzazioni AWS gestite fornite non funziona, puoi creare un'autorizzazione gestita dal cliente personalizzata. Le autorizzazioni gestite dal cliente sono autorizzazioni gestite che puoi creare e gestire specificando con precisione quali azioni possono essere eseguite in quali condizioni con risorse condivise. AWS RAM AWS AppSync consente di scegliere tra le seguenti azioni durante la creazione delle proprie autorizzazioni:

1. `appsync:AssociateSourceGraphqlApi`

1. `appsync:AssociateMergedGraphqlApi`

1. `appsync:GetSourceApiAssociation`

1. `appsync:UpdateSourceApiAssociation`

1. `appsync:StartSchemaMerge`

1. `appsync:ListTypesByAssociation`

1. `appsync:SourceGraphQL`

Dopo aver condiviso correttamente un'API di origine o un'API unita AWS RAM e, se necessario, l'invito alla condivisione delle risorse è stato accettato, l'invito alla condivisione delle risorse sarà visibile nella AWS AppSync console quando si creano o si aggiornano le associazioni delle API di origine sulla Merged API. Puoi anche elencare tutto ciò AWS AppSync APIs che è stato condiviso AWS RAM con il tuo account indipendentemente dall'autorizzazione impostata richiamando l'`ListGraphqlApis`operazione fornita AWS AppSync e utilizzando il filtro del `OTHER_ACCOUNTS` proprietario. 

**Nota**  
La condivisione tramite AWS RAM richiede che il chiamante sia autorizzato a eseguire l'`appsync:PutResourcePolicy`azione su qualsiasi API condivisa. AWS RAM 

## Unire
<a name="merges"></a>

### Gestione delle unioni
<a name="managing-merges"></a>

 APIs Le fusioni hanno lo scopo di supportare la collaborazione in team su un endpoint AWS AppSync unificato. I team possono far evolvere in modo indipendente la propria fonte isolata APIs GraphQL nel backend, mentre AWS AppSync il servizio gestisce l'integrazione delle risorse nel singolo endpoint Merged API al fine di ridurre l'attrito nella collaborazione e ridurre i tempi di sviluppo.

### Unioni automatiche
<a name="auto-merge"></a>

L'origine APIs associata alla tua API AWS AppSync unita può essere configurata per l'unione automatica (unione automatica) nell'API unita dopo aver apportato modifiche all'API di origine. Ciò garantisce che le modifiche dall'API di origine vengano sempre propagate all'endpoint dell'API unita in background. Qualsiasi modifica nello schema dell'API di origine verrà aggiornata nell'API unita a condizione che non introduca un conflitto di fusione con una definizione esistente nell'API unita. Se l'aggiornamento nell'API di origine sta aggiornando un resolver, un'origine dati o una funzione, verrà aggiornata anche la risorsa importata. Quando viene introdotto un nuovo conflitto che non può essere risolto automaticamente (risolto automaticamente), l'aggiornamento dello schema dell'API unita viene rifiutato a causa di un conflitto non supportato durante l'operazione di unione. Il messaggio di errore è disponibile nella console per ogni associazione di API di origine con lo stato di. `MERGE_FAILED` Puoi anche controllare il messaggio di errore chiamando l'`GetSourceApiAssociation`operazione per una determinata associazione API di origine utilizzando l' AWS SDK o utilizzando la AWS CLI in questo modo:

```
aws appsync get-source-api-association --merged-api-identifier <Merged API ARN> --association-id <SourceApiAssociation id>
```

Ciò produrrà un risultato nel seguente formato:

```
{
    "sourceApiAssociation": {
        "associationId": "<association id>",
        "associationArn": "<association arn>",
        "sourceApiId": "<source api id>",
        "sourceApiArn": "<source api arn>",
        "mergedApiArn": "<merged api arn>",
        "mergedApiId": "<merged api id>",
        "sourceApiAssociationConfig": {
            "mergeType": "MANUAL_MERGE"
        },
        "sourceApiAssociationStatus": "MERGE_FAILED",
        "sourceApiAssociationStatusDetail": "Unable to resolve conflict on object with name title: Merging is not supported for fields with different types."
    }
}
```

### Unioni manuali
<a name="manual-merges"></a>

L'impostazione predefinita per un'API di origine è un'unione manuale. Per unire le modifiche apportate all'origine APIs dall'ultimo aggiornamento dell'API unita, il proprietario dell'API di origine può richiamare un'unione manuale dalla AWS AppSync console o tramite l'`StartSchemaMerge`operazione disponibile nell'SDK AWS e nella CLI. AWS 

## Supporto aggiuntivo per Merged APIs
<a name="merge-api-additional-support"></a>

### Configurazione degli abbonamenti
<a name="config-subscription"></a>

A differenza degli approcci basati su router alla composizione dello schema GraphQL, AWS AppSync Merged fornisce supporto APIs integrato per gli abbonamenti GraphQL. Tutte le operazioni di sottoscrizione definite nella fonte associata verranno automaticamente unite e APIs funzioneranno nell'API Merged senza modifiche. [Per ulteriori informazioni su come AWS AppSync supporta gli abbonamenti tramite WebSockets connessione serverless, consulta Dati in tempo reale.](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html)

### Configurazione dell'osservabilità
<a name="config-observability"></a>

AWS AppSync [Merged APIs fornisce registrazione, monitoraggio e metriche integrate tramite Amazon. CloudWatch](https://docs.aws.amazon.com/appsync/latest/devguide/monitoring.html) AWS AppSync fornisce anche supporto integrato per il tracciamento tramite. [AWS X-Ray](https://docs.aws.amazon.com/appsync/latest/devguide/x-ray-tracing.html) 

### Configurazione di domini personalizzati
<a name="config-custom-domain"></a>

AWS AppSync [Merged APIs fornisce supporto integrato per l'utilizzo di domini personalizzati con gli endpoint GraphQL e Real-time dell'API Merged.](https://docs.aws.amazon.com/appsync/latest/devguide/custom-domain-name.html) 

### Configurazione della memorizzazione nella cache
<a name="config-caching"></a>

AWS AppSync Merged APIs fornisce supporto integrato per la memorizzazione opzionale nella cache delle risposte a livello di richiesta e/o a livello di resolver, nonché per la compressione delle risposte. [Per ulteriori informazioni, consulta Caching e compressione.](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html) 

### Configurazione privata APIs
<a name="config-private-api"></a>

AWS AppSync [Merged APIs fornisce un supporto integrato per Private APIs che limita l'accesso agli endpoint GraphQL e Real-time dell'API Merged al traffico proveniente dagli endpoint VPC che puoi configurare.](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html) 

### Configurazione delle regole del firewall
<a name="config-firewall"></a>

AWS AppSync Merged APIs fornisce un supporto integrato per AWS WAF, che consente di proteggere le [applicazioni Web APIs definendo regole di firewall](https://docs.aws.amazon.com/appsync/latest/devguide/WAF-Integration.html). 

### Configurazione dei log di controllo
<a name="config-audit"></a>

AWS AppSync Merged APIs fornisce supporto integrato per AWS CloudTrail, che consente di [configurare e gestire](https://docs.aws.amazon.com/appsync/latest/devguide/cloudtrail-logging.html) i registri di controllo. 

## Limitazioni delle API unite
<a name="merged-api-limits"></a>

Durante lo sviluppo di Merged APIs, prendi nota delle seguenti regole:

1. Un'API unita non può essere un'API di origine per un'altra API unita.

1. Un'API di origine non può essere associata a più di un'API unita.

1. Il limite di dimensione predefinito per un documento dello schema dell'API unita è di 10 MB.

1. Il numero predefinito di sorgenti APIs che può essere associato a un'API unita è 10. Tuttavia, puoi richiedere un aumento del limite se hai bisogno di più di 10 sorgenti APIs nella tua API unita.

## Considerazioni sull'API unita
<a name="merged-api-considerations"></a>

Durante la progettazione e l'implementazione di Merged APIs, tenete presente quanto segue:

L'unione di più sorgenti APIs in un unico endpoint può aumentare le dimensioni e la complessità dello schema e delle query GraphQL. Man mano che lo schema unito cresce, potrebbe essere necessario che le query attraversino più resolver per soddisfare una singola richiesta, il che può aggiungere latenza al tempo complessivo della richiesta. Ad esempio, una query che accede ai campi da più fonti APIs può richiedere l'esecuzione di resolver da ciascuna API di origine in sequenza, con ogni resolver che si aggiunge AWS AppSync al tempo di risposta totale.

Ti consigliamo vivamente di testare APIs accuratamente i dispositivi Merged durante lo sviluppo e in condizioni di carico realistiche per assicurarti che soddisfino i requisiti aziendali. Presta particolare attenzione a:
+ La profondità e la complessità dello schema unito, in particolare delle query che accedono ai campi di più fonti. APIs
+ Il numero di resolver che devono essere eseguiti per soddisfare i modelli di query comuni.
+ Le caratteristiche prestazionali delle sorgenti di dati e dei resolver in base al carico previsto.
+ L'impatto della latenza di rete sull'accesso alle risorse da più fonti. APIs

Prendi in considerazione l'implementazione di ottimizzazioni delle prestazioni come la memorizzazione nella cache, il raggruppamento in batch delle richieste di origine dati e la progettazione di schemi API di origine per ridurre al minimo il numero di esecuzioni di resolver necessarie per le operazioni comuni.

## Creazione di un sistema unito APIs
<a name="creating-merged-api"></a>

**Per creare un'API unita nella console**

1. Accedi Console di gestione AWS e apri la [AWS AppSync console](https://console.aws.amazon.com/appsync/).

   1. Nella **dashboard**, scegli **Crea API**.

1. Scegli **Merged API**, quindi scegli **Avanti**.

1. Nella pagina **Specificare i dettagli dell'API**, inserisci le seguenti informazioni: 

   1. In **Dettagli API**, inserisci le seguenti informazioni:

      1. Specificate il **nome dell'API** unita. Questo campo consente di etichettare l'API GraphQL per distinguerla facilmente dagli altri GraphQL. APIs 

      1. **Specificate i dati di contatto.** Questo campo è facoltativo e assegna un nome o un gruppo all'API GraphQL. Non è collegato o generato da altre risorse e funziona in modo molto simile al campo del nome dell'API. 

   1. In **Service role**, devi assegnare un ruolo di esecuzione IAM all'API unita in modo che AWS AppSync possa importare e utilizzare le tue risorse in modo sicuro in fase di esecuzione. Puoi scegliere di **creare e utilizzare un nuovo ruolo di servizio**, che ti consentirà di specificare le politiche e le risorse da utilizzare. AWS AppSync Puoi anche importare un ruolo IAM esistente selezionando **Usa un ruolo di servizio esistente**, quindi selezionando il ruolo dall'elenco a discesa. 

   1. In **Configurazione API privata**, puoi scegliere di abilitare le funzionalità dell'API privata. Tieni presente che questa scelta non può essere modificata dopo aver creato l'API unita. Per ulteriori informazioni su private APIs, consulta [Using AWS AppSync Private APIs](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html). 

      Dopo aver finito, scegli **Avanti**. 

1. Successivamente, è necessario aggiungere il GraphQL APIs che verrà utilizzato come base per l'API unita. Nella APIs pagina **Seleziona fonte**, inserisci le seguenti informazioni: 

   1. Nella tabella **APIs dal tuo AWS account**, scegli **Aggiungi fonte APIs**. Nell'elenco di GraphQL APIs, ogni voce conterrà i seguenti dati:

      1. **Nome**: il campo del **nome** dell'API GraphQL. 

      1. **ID API**: il valore ID univoco dell'API GraphQL.

      1. Modalità di **autenticazione primaria: la modalità** di autorizzazione predefinita per l'API GraphQL. Per ulteriori informazioni sulle modalità di autorizzazione in AWS AppSync, vedere [Autorizzazione e autenticazione](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html). 

      1. Modalità di **autenticazione aggiuntiva: le modalità** di autorizzazione secondarie configurate nell'API GraphQL.

      1. **Scegli quella APIs che utilizzerai nell'API unita selezionando la casella di controllo accanto al campo Nome dell'API.** **Successivamente, scegli Aggiungi fonte. APIs** Il GraphQL selezionato APIs verrà visualizzato nella tabella **APIs dei tuoi AWS conti**.

   1. Nella tabella **APIs Da altri AWS conti**, scegli **Aggiungi sorgente APIs**. Il GraphQL APIs in questo elenco proviene da altri account che condividono le proprie risorse con l'utente tramite AWS Resource Access Manager ()AWS RAM. Il processo di selezione di GraphQL APIs in questa tabella è lo stesso del processo descritto nella sezione precedente. Per ulteriori informazioni sulla condivisione di risorse tramite AWS RAM, consulta [What is AWS Resource Access Manager?](https://docs.aws.amazon.com/ram/latest/userguide/what-is.html) .

      Scegli **Avanti** dopo aver finito.

   1. Aggiungi la tua modalità di autenticazione principale. Vedi [Autorizzazione e autenticazione](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html) per ulteriori informazioni. Scegli **Next (Successivo)**.

   1. Controlla i tuoi input, quindi scegli **Crea API**.

# Creazione di GraphQL APIs con l'introspezione RDS
<a name="rds-introspection"></a>

AWS AppSync l'utilità di introspezione può scoprire modelli dalle tabelle del database e proporre tipi GraphQL. La procedura guidata Create API della AWS AppSync console può generare istantaneamente un'API da un database Aurora MySQL o PostgreSQL. Crea automaticamente tipi e resolver per leggere e scrivere dati JavaScript .

AWS AppSync fornisce l'integrazione diretta con i database Amazon Aurora tramite l'API Amazon RDS Data. Anziché richiedere una connessione persistente al database, l'API Amazon RDS Data offre un endpoint HTTP sicuro a cui AWS AppSync connettersi per l'esecuzione SQL di istruzioni. Puoi usarlo per creare un'API di database relazionale per i tuoi carichi di lavoro MySQL e PostgreSQL su Aurora.

La creazione di un'API per il database relazionale presenta diversi vantaggi: AWS AppSync 
+ Il database non è esposto direttamente ai client, il che significa che il punto di accesso è separato dal database stesso. 
+ È possibile creare APIs soluzioni personalizzate in base alle esigenze di diverse applicazioni, eliminando la necessità di utilizzare logiche aziendali personalizzate nei frontend. Questo è in linea con lo schema (BFF). Backend-For-Frontend 
+ L'autorizzazione e il controllo degli accessi possono essere implementati a AWS AppSync livello utilizzando varie modalità di autorizzazione per controllare l'accesso. Non sono necessarie risorse di elaborazione aggiuntive per connettersi al database, ad esempio l'hosting di un server Web o l'invio di connessioni tramite proxy. 
+ È possibile aggiungere funzionalità in tempo reale tramite abbonamenti, con le mutazioni dei dati effettuate AppSync automaticamente tramite push ai client connessi. 
+ I client possono connettersi all'API tramite HTTPS utilizzando porte comuni come 443.

AWS AppSync semplifica la creazione APIs a partire da database relazionali esistenti. La sua utilità di introspezione può scoprire modelli dalle tabelle del database e proporre tipi GraphQL. La procedura guidata *Create API* della AWS AppSync console può generare istantaneamente un'API da un database Aurora MySQL o PostgreSQL. Crea automaticamente tipi e resolver per leggere e scrivere dati JavaScript. 

AWS AppSync fornisce JavaScript utilità integrate per semplificare la scrittura di istruzioni SQL nei resolver. È possibile utilizzare i modelli AWS AppSync di `sql` tag per istruzioni statiche con valori dinamici o le utilità del `rds` modulo per creare istruzioni a livello di codice. [Per ulteriori informazioni, consulta il [riferimento alla funzione resolver per le fonti di dati RDS e](https://docs.aws.amazon.com//appsync/latest/devguide/resolver-reference-rds-js.html) i moduli integrati.](https://docs.aws.amazon.com//appsync/latest/devguide/built-in-modules-js.html#built-in-rds-modules) 

## Utilizzo della funzione di introspezione (console)
<a name="using-introspection-console"></a>

Per un tutorial dettagliato e una guida introduttiva, vedi [Tutorial: Aurora PostgreSQL Serverless with Data API](https://docs.aws.amazon.com//appsync/latest/devguide/aurora-serverless-tutorial-js.html). 

La AWS AppSync console consente di creare un'API AWS AppSync GraphQL dal database Aurora esistente configurato con l'API Data in pochi minuti. Questo genera rapidamente uno schema operativo basato sulla configurazione del database. Puoi utilizzare l'API così com'è o basarti su di essa per aggiungere funzionalità. 

1. [Accedi a Console di gestione AWS e apri la AppSync console.](https://console.aws.amazon.com/appsync/)

   1. Nel **pannello di controllo**, scegliere **Create API (Crea API)**.

1. **In **Opzioni API**, scegli **GraphQL APIs**, **Inizia con un cluster Amazon Aurora**, quindi Avanti.**

   1. Inserisci un nome **API.** Verrà utilizzato come identificatore per l'API nella console.

   1. Per **i dettagli di contatto**, puoi inserire un punto di contatto per identificare un gestore dell'API. Questo campo è opzionale.

   1. In **Configurazione API privata**, puoi abilitare le funzionalità dell'API privata. È possibile accedere a un'API privata solo da un endpoint VPC configurato (VPCE). [Per ulteriori informazioni, consulta Privato. APIs](https://docs.aws.amazon.com//appsync/latest/devguide/using-private-apis.html)

      Non è consigliabile abilitare questa funzionalità per questo esempio. Scegli **Avanti** dopo aver esaminato i dati inseriti.

1. Nella pagina **Database**, scegli **Seleziona database**.

   1. È necessario scegliere il database dal cluster. Il primo passo è scegliere la **regione** in cui si trova il cluster.

   1. Scegli il **cluster Aurora** dall'elenco a discesa. Tieni presente che devi aver creato e [abilitato](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/data-api.html#data-api.enabling) un'API di dati corrispondente prima di utilizzare la risorsa.

   1. Successivamente, è necessario aggiungere le credenziali del database al servizio. Questo viene fatto principalmente utilizzando Gestione dei segreti AWS. Scegli la **regione** in cui esiste il tuo segreto. Per ulteriori informazioni su come recuperare informazioni segrete, consulta [Trova segreti](https://docs.aws.amazon.com//secretsmanager/latest/userguide/manage_search-secret.html) o [Recupera](https://docs.aws.amazon.com//secretsmanager/latest/userguide/retrieving-secrets.html) segreti.

   1. Aggiungi il tuo segreto dall'elenco a discesa. Tieni presente che l'utente deve disporre delle [autorizzazioni di lettura](https://docs.aws.amazon.com//AmazonRDS/latest/UserGuide/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-console) per il tuo database.

1. Scegli **Importa**.

   AWS AppSync inizierà a esaminare il database, scoprendo tabelle, colonne, chiavi primarie e indici. Verifica che le tabelle rilevate possano essere supportate in un'API GraphQL. Nota che per supportare la creazione di nuove righe, le tabelle necessitano di una chiave primaria, che può utilizzare più colonne. AWS AppSync mappa le colonne della tabella per digitare i campi come segue:     
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/rds-introspection.html)

1. Una volta completata l'individuazione delle tabelle, la sezione **Database** verrà popolata con le informazioni dell'utente. Nella nuova sezione **Tabelle del database**, i dati della tabella potrebbero già essere compilati e convertiti in un tipo adatto allo schema. **Se non vedi alcuni dei dati richiesti, puoi verificarli scegliendo **Aggiungi tabelle**, facendo clic sulle caselle di controllo relative a tali tipi nella finestra modale visualizzata, quindi scegliendo Aggiungi.** 

   **Per rimuovere un tipo dalla sezione **Tabelle del database**, fai clic sulla casella di controllo accanto al tipo che desideri rimuovere, quindi scegli Rimuovi.** I tipi rimossi verranno inseriti nella modalità **Aggiungi tabelle** se desideri aggiungerli nuovamente in un secondo momento.

   Nota che AWS AppSync utilizza i nomi delle tabelle come nomi di tipo, ma puoi rinominarli, ad esempio cambiando il nome di una tabella plurale simile *movies* al nome del tipo. *Movie* **Per rinominare un tipo nella sezione **Tabelle del database**, fai clic sulla casella di controllo del tipo che desideri rinominare, quindi fai clic sull'icona a forma di *matita nella colonna* Nome tipo.**

   **Per visualizzare in anteprima il contenuto dello schema in base alle tue selezioni, scegli Anteprima schema.** Tieni presente che questo schema non può essere vuoto, quindi dovrai convertire almeno una tabella in un tipo. Inoltre, questo schema non può superare 1 MB di dimensione.

   1. In **Ruolo di servizio**, scegli se creare un nuovo ruolo di servizio specifico per questa importazione o utilizzare un ruolo esistente.

1. Scegli **Next (Successivo)**.

1. Quindi, scegli se creare un'API di sola lettura (solo query) o un'API per leggere e scrivere dati (con query e mutazioni). Quest'ultima supporta anche sottoscrizioni in tempo reale innescate da mutazioni. 

1. Scegli **Next (Successivo)**.

1. **Controlla le tue scelte e poi scegli Crea API.** AWS AppSync creerà l'API e collegherà i resolver a query e mutazioni. L'API generata è completamente operativa e può essere estesa secondo necessità. 

## Utilizzo della funzione di introspezione (API)
<a name="using-introspection-api"></a>

Puoi utilizzare l'API di `StartDataSourceIntrospection` introspezione per scoprire i modelli nel tuo database a livello di codice. Per maggiori dettagli sul comando, consulta Utilizzo dell'API. [https://docs.aws.amazon.com//appsync/latest/APIReference/API_StartDataSourceIntrospection.html](https://docs.aws.amazon.com//appsync/latest/APIReference/API_StartDataSourceIntrospection.html) 

Per utilizzarlo`StartDataSourceIntrospection`, fornisci il nome Amazon Resource Name (ARN) del cluster Aurora, il nome del database e l'ARN segreto. Gestione dei segreti AWS Il comando avvia il processo di introspezione. È possibile recuperare i risultati con il comando. `GetDataSourceIntrospection` È possibile specificare se il comando deve restituire la stringa Storage Definition Language (SDL) per i modelli rilevati. Ciò è utile per generare una definizione dello schema SDL direttamente dai modelli scoperti.

 Ad esempio, se avete la seguente istruzione DDL (Data Definition Language) per una tabella semplice: `Todos`

```
create table if not exists public.todos  
(  
id serial constraint todos_pk primary key,  
description text,  
due timestamp,  
"createdAt" timestamp default now()  
);
```

Iniziate l'introspezione con quanto segue.

```
aws appsync start-data-source-introspection \ 
  --rds-data-api-config resourceArn=<cluster-arn>,secretArn=<secret-arn>,databaseName=database
```

Quindi, utilizzate il `GetDataSourceIntrospection` comando per recuperare il risultato.

```
aws appsync get-data-source-introspection \
  --introspection-id a1234567-8910-abcd-efgh-identifier \
  --include-models-sdl
```

Ciò restituisce il seguente risultato.

```
{
    "introspectionId": "a1234567-8910-abcd-efgh-identifier",
    "introspectionStatus": "SUCCESS",
    "introspectionStatusDetail": null,
    "introspectionResult": {
        "models": [
            {
                "name": "todos",
                "fields": [
                    {
                        "name": "description",
                        "type": {
                            "kind": "Scalar",
                            "name": "String",
                            "type": null,
                            "values": null
                        },
                        "length": 0
                    },
                    {
                        "name": "due",
                        "type": {
                            "kind": "Scalar",
                            "name": "AWSDateTime",
                            "type": null,
                            "values": null
                        },
                        "length": 0
                    },
                    {
                        "name": "id",
                        "type": {
                            "kind": "NonNull",
                            "name": null,
                            "type": {
                                "kind": "Scalar",
                                "name": "Int",
                                "type": null,
                                "values": null
                            },
                            "values": null
                        },
                        "length": 0
                    },
                    {
                        "name": "createdAt",
                        "type": {
                            "kind": "Scalar",
                            "name": "AWSDateTime",
                            "type": null,
                            "values": null
                        },
                        "length": 0
                    }
                ],
                "primaryKey": {
                    "name": "PRIMARY_KEY",
                    "fields": [
                        "id"
                    ]
                },
                "indexes": [],
                "sdl": "type todos\n{\ndescription: String\n\ndue: AWSDateTime\n\nid: Int!\n\ncreatedAt: AW
SDateTime\n}\n"
            }
        ],
        "nextToken": null
    }
}
```