

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

# AWS AppSync JavaScript panoramica dei resolver
<a name="resolver-reference-overview-js"></a>

AWS AppSync consente di rispondere alle richieste GraphQL eseguendo operazioni sulle fonti di dati. Per ogni campo GraphQL su cui si desidera eseguire una query, una mutazione o una sottoscrizione, è necessario allegare un resolver.

I resolver sono i connettori tra GraphQL e una fonte di dati. Spiegano AWS AppSync come tradurre una richiesta GraphQL in entrata in istruzioni per l'origine dati di backend e come tradurre la risposta da tale fonte di dati in una risposta GraphQL. Con AWS AppSync, puoi scrivere i tuoi resolver utilizzando JavaScript ed eseguirli nell'ambiente (). AWS AppSync `APPSYNC_JS` 

AWS AppSync consente di scrivere resolver di unità o resolver di pipeline composti da più funzioni in una pipeline. AWS AppSync 

## Funzionalità di runtime supportate
<a name="runtime-support-js"></a>

Il AWS AppSync JavaScript runtime fornisce un sottoinsieme di JavaScript librerie, utilità e funzionalità. Per un elenco completo delle caratteristiche e delle funzionalità supportate dal `APPSYNC_JS` runtime, consultate Funzionalità di [JavaScript runtime per resolver e funzioni](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html).

## Risolutori di unità
<a name="unit-resolver-js"></a>

Un resolver di unità è composto da codice che definisce un gestore di richieste e risposte che vengono eseguiti su un'origine dati. Il gestore delle richieste accetta un oggetto di contesto come argomento e restituisce il payload della richiesta utilizzato per chiamare l'origine dei dati. Il gestore della risposta riceve un payload dall'origine dati con il risultato della richiesta eseguita. Il gestore di risposte trasforma il payload in una risposta GraphQL per risolvere il campo GraphQL. Nell'esempio seguente, un resolver recupera un elemento da un'origine dati DynamoDB:

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
  return ddb.get({ key: { id: ctx.args.id } });
}

export const response = (ctx) => ctx.result;
```

## Anatomia di un resolver di pipeline JavaScript
<a name="anatomy-of-a-pipeline-resolver-js"></a>

Un pipeline resolver è composto da codice che definisce un gestore di richieste e risposte e un elenco di funzioni. Ogni funzione dispone di un gestore di **richieste** e **risposte** che esegue su un'origine dati. Poiché un resolver di pipeline delega l'esecuzione a un elenco di funzioni, non è quindi collegato a nessuna fonte di dati. Funzioni e resolver di unità sono primitive che eseguono un'operazione su origini dati.

### Gestore di richieste Pipeline Resolver
<a name="request-handler-js"></a>

Il gestore delle richieste di un risolutore di pipeline (il passaggio precedente) consente di eseguire una logica di preparazione prima di eseguire le funzioni definite.

### Elenco delle funzioni
<a name="functions-list-js"></a>

L'elenco delle funzioni eseguite in sequenza da un resolver di pipeline. Il risultato della valutazione del gestore di richieste del resolver pipeline viene reso disponibile alla prima funzione come. `ctx.prev.result` Ogni risultato della valutazione della funzione è disponibile per la funzione successiva come. `ctx.prev.result`

### Gestore di risposte del resolver Pipeline
<a name="response-handler-js"></a>

Il gestore di risposte di un resolver di pipeline consente di eseguire una logica finale dall'output dell'ultima funzione al tipo di campo GraphQL previsto. L'output dell'ultima funzione nell'elenco delle funzioni è disponibile nel gestore di risposte del resolver della pipeline come o. `ctx.prev.result` `ctx.result`

### Flusso di esecuzione
<a name="execution-flow-js"></a>

Dato un resolver a pipeline composto da due funzioni, l'elenco seguente rappresenta il flusso di esecuzione quando viene richiamato il resolver:

1.  Gestore delle richieste del resolver Pipeline

1.  Funzione 1: gestore di richieste di funzioni 

1.  Funzione 1: invocazione dell'origine dati 

1.  Funzione 1: gestore della risposta alla funzione 

1.  Funzione 2: gestore di richieste di funzioni 

1.  Funzione 2: invocazione dell'origine dati 

1.  Funzione 2: gestore della risposta alla funzione 

1.  Gestore di risposte del resolver Pipeline 

![\[GraphQL request flow diagram showing interactions between request, data sources, and response components.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/appsync-js-resolver-logic.png)


### Utili utilità integrate in runtime `APPSYNC_JS`
<a name="useful-utilities-js"></a>

Nell'utilizzo dei resolver di pipeline, è possibile avvalersi delle seguenti funzionalità.

#### ctx.stash
<a name="ctx-stash-js"></a>

Lo stash è un oggetto reso disponibile all'interno di ogni resolver e gestore di richieste e risposte di funzioni. La stessa istanza stash dura attraverso una singola esecuzione del resolver. Ciò significa che puoi utilizzare lo stash per passare dati arbitrari tra gestori di richieste e risposte e tra funzioni in un resolver di pipeline. Puoi testare lo stash come un normale oggetto. JavaScript 

#### ctx.prev.result
<a name="ctx-prev-result-js"></a>

La voce `ctx.prev.result` corrisponde al risultato dell'operazione precedentemente eseguita nella pipeline. Se l'operazione precedente era il gestore delle richieste del resolver della pipeline, allora `ctx.prev.result` viene reso disponibile alla prima funzione della catena. Se l'operazione precedente corrisponde alla prima funzione, `ctx.prev.result` è l'output della prima funzione, disponibile per la seconda funzione della pipeline. Se l'operazione precedente era l'ultima funzione, `ctx.prev.result` rappresenta l'output dell'ultima funzione e viene resa disponibile al gestore delle risposte del resolver della pipeline.

#### util.error
<a name="util-error-js"></a>

Con `util.error` è possibile generare un errore di campo. L'utilizzo `util.error` all'interno di un gestore di richieste o risposte di funzione genera immediatamente un errore di campo, che impedisce l'esecuzione delle funzioni successive. Per maggiori dettagli e altre `util.error` firme, visita le funzionalità di [JavaScriptruntime per resolver e funzioni](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html).

#### util.appendError
<a name="util-appenderror-js"></a>

`util.appendError`è simile a`util.error()`, con la principale distinzione che non interrompe la valutazione del gestore. Segnala invece che c'è stato un errore nel campo, ma consente di valutare il gestore e di conseguenza di restituire i dati. L'utilizzo di `util.appendError` all'interno di una funzione non interrompe il flusso di esecuzione della pipeline. Per maggiori dettagli e altre `util.error` firme, visita le funzionalità di [JavaScript runtime per resolver e funzioni](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html).

#### runtime.earlyreturn
<a name="runtime-earlyreturn-js"></a>

La `runtime.earlyReturn` funzione consente di tornare prematuramente da qualsiasi funzione di richiesta. Se si utilizza l'`runtime.earlyReturn`interno di un resolver, il gestore di richieste verrà restituito dal resolver. AWS AppSync La chiamata da un gestore di richieste di funzioni restituirà dalla funzione e continuerà l'esecuzione verso la funzione successiva nella pipeline o il gestore di risposte del resolver.

### Scrittura di resolver per pipeline
<a name="writing-resolvers"></a>

Un risolutore di pipeline dispone anche di un gestore di richiesta e di risposta che circonda l'esecuzione delle funzioni nella pipeline: il suo gestore di richieste viene eseguito prima della richiesta della prima funzione e il suo gestore di risposta viene eseguito dopo la risposta dell'ultima funzione. Il gestore delle richieste del resolver può impostare i dati che devono essere utilizzati dalle funzioni nella pipeline. Il gestore della risposta del resolver è responsabile della restituzione dei dati mappati al tipo di output del campo GraphQL. Nell'esempio seguente, un gestore di richieste di resolver definisce`allowedGroups`; i dati restituiti devono appartenere a uno di questi gruppi. Questo valore può essere utilizzato dalle funzioni del resolver per richiedere dati. Il gestore delle risposte del resolver esegue un controllo finale e filtra il risultato per assicurarsi che vengano restituiti solo gli elementi che appartengono ai gruppi consentiti.

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

/**
 * Called before the request function of the first AppSync function in the pipeline.
 *  @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
  ctx.stash.allowedGroups = ['admin'];
  ctx.stash.startedAt = util.time.nowISO8601();
  return {};
}
/**
 * Called after the response function of the last AppSync function in the pipeline.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  const result = [];
  for (const item of ctx.prev.result) {
    if (ctx.stash.allowedGroups.indexOf(item.group) > -1) result.push(item);
  }
  return result;
}
```

#### Funzioni di scrittura AWS AppSync
<a name="writing-functions"></a>

AWS AppSync le funzioni consentono di scrivere una logica comune che è possibile riutilizzare su più resolver dello schema. Ad esempio, puoi avere una AWS AppSync funzione chiamata `QUERY_ITEMS` responsabile dell'interrogazione di elementi da un'origine dati Amazon DynamoDB. Per i resolver con cui desideri interrogare gli elementi, aggiungi semplicemente la funzione alla pipeline del resolver e fornisci l'indice di query da utilizzare. La logica non deve essere reimplementata.

## Argomenti supplementari
<a name="supplemental-topics"></a>

**Argomenti**
+ [Esempio di risolutore di pipeline con Amazon DynamoDB](https://docs.aws.amazon.com/appsync/latest/devguide/writing-code.html)
+ [Configurazione delle utilità per il runtime `APPSYNC_JS`](https://docs.aws.amazon.com/appsync/latest/devguide/utility-resolvers.html)
+ [Raggruppamento e TypeScript mappe di origine per il runtime `APPSYNC_JS`](https://docs.aws.amazon.com/appsync/latest/devguide/additional-utilities.html)
+ [Verifica del resolver e dei gestori di funzioni](https://docs.aws.amazon.com/appsync/latest/devguide/test-resolvers.html)
+ [Migrazione da VTL a JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/migrating-resolvers.html)
+ [Scelta tra accesso diretto alla fonte di dati e invio di proxy tramite un'origine dati Lambda](https://docs.aws.amazon.com/appsync/latest/devguide/choosing-data-source.html)

# Esempio di risolutore di pipeline con Amazon DynamoDB
<a name="writing-code"></a>

Supponiamo di voler collegare un resolver di pipeline a un campo denominato `getPost(id:ID!)` che restituisce un `Post` tipo da un'origine dati Amazon DynamoDB con la seguente query GraphQL:

```
getPost(id:1){
    id
    title
    content
}
```

Innanzitutto, collega un semplice resolver a con il codice seguente. `Query.getPost` Questo è un esempio di codice resolver semplice. Non esiste una logica definita nel gestore della richiesta e il gestore della risposta restituisce semplicemente il risultato dell'ultima funzione.

```
/**
 * Invoked **before** the request handler of the first AppSync function in the pipeline.
 * The resolver `request` handler allows to perform some preparation logic
 * before executing the defined functions in your pipeline.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
  return {}
}

/**
 * Invoked **after** the response handler of the last AppSync function in the pipeline.
 * The resolver `response` handler allows to perform some final evaluation logic
 * from the output of the last function to the expected GraphQL field type.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  return ctx.prev.result
}
```

Quindi, definisci la funzione `GET_ITEM` che recupera un postitem dalla tua fonte di dati:

```
import { util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'

/**
 * Request a single item from the attached DynamoDB table datasource
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
	const { id } = ctx.args
	return ddb.get({ key: { id } })
}

/**
 * Returns the result
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
	const { error, result } = ctx
	if (error) {
		return util.appendError(error.message, error.type, result)
	}
	return ctx.result
}
```

Se si verifica un errore durante la richiesta, il gestore di risposte della funzione aggiunge un errore che verrà restituito al client chiamante nella risposta GraphQL. Aggiungi la `GET_ITEM` funzione all'elenco delle funzioni del resolver. Quando si esegue la query, il gestore delle richieste della `GET_ITEM` funzione utilizza gli strumenti forniti dal modulo AWS AppSync DynamoDB per creare una `DynamoDBGetItem` richiesta utilizzando come chiave. `id` `ddb.get({ key: { id } })`genera l'operazione appropriata: `GetItem`

```
{
    "operation" : "GetItem",
    "key" : {
        "id" : { "S" : "1" }
    }
}
```

AWS AppSync utilizza la richiesta per recuperare i dati da Amazon DynamoDB. Una volta restituiti, i dati vengono gestiti dal gestore delle risposte della `GET_ITEM` funzione, che verifica la presenza di errori e quindi restituisce il risultato. 

```
{
  "result" : {
    "id": 1,
    "title": "hello world",
    "content": "<long story>"
  }
}
```

Infine, il gestore di risposte del resolver restituisce direttamente il risultato.

## Lavorare con gli errori
<a name="working-with-errors"></a>

Se si verifica un errore nella funzione durante una richiesta, l'errore verrà reso disponibile nel gestore della risposta alla funzione in`ctx.error`. È possibile aggiungere l'errore alla risposta GraphQL utilizzando l'`util.appendError`utilità. È possibile rendere l'errore disponibile per altre funzioni della pipeline utilizzando lo stash. Vedere l'esempio di seguito.

```
/**
 * Returns the result
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  const { error, result } = ctx;
  if (error) {
    if (!ctx.stash.errors) ctx.stash.errors = []
    ctx.stash.errors.push(ctx.error)
    return util.appendError(error.message, error.type, result);
  }
  return ctx.result;
}
```

# Configurazione delle utilità per il runtime `APPSYNC_JS`
<a name="utility-resolvers"></a>

AWS AppSync fornisce due librerie che facilitano lo sviluppo di resolver con il runtime: `APPSYNC_JS` 
+ `@aws-appsync/eslint-plugin`- Rileva e corregge rapidamente i problemi durante lo sviluppo.
+ `@aws-appsync/utils`- Fornisce la convalida dei tipi e il completamento automatico negli editor di codice.

## Configurazione del plugin eslint
<a name="utility-resolvers-configuring-eslint-plugin"></a>

[ESLint](https://eslint.org/)è uno strumento che analizza staticamente il codice per trovare rapidamente i problemi. Puoi eseguirlo ESLint come parte della tua pipeline di integrazione continua. `@aws-appsync/eslint-plugin`è un ESLint plugin che rileva la sintassi non valida nel codice quando sfrutta il runtime. `APPSYNC_JS` Il plugin consente di ottenere rapidamente un feedback sul codice durante lo sviluppo senza dover inviare le modifiche al cloud.

`@aws-appsync/eslint-plugin`fornisce due set di regole che è possibile utilizzare durante lo sviluppo. 

**«plugin: @aws -appsync/base»** configura un set di regole di base che puoi sfruttare nel tuo progetto: 


| Regola | Description | 
| --- | --- | 
| no-async | I processi e le promesse asincroni non sono supportati. | 
| senza attesa | I processi e le promesse asincroni non sono supportati. | 
| nessuna classe | Le classi non sono supportate. | 
| no per | fornon è supportato (ad eccezione di for-in efor-of, che sono supportati) | 
| no-continue | continue non è supportato. | 
| senza generatori | I generatori non sono supportati. | 
| senza rendimento | yield non è supportato. | 
| senza etichette | Le etichette non sono supportate. | 
| no-questo | thisla parola chiave non è supportata. | 
| nessun tentativo | La struttura TRY/catch non è supportata. | 
| nel giro di poco | I loop While non sono supportati. | 
| no-disallowed-unary-operators | \$1\$1--, e gli operatori \$1 unari non sono consentiti. | 
| no-disallowed-binary-operators | L'instanceofoperatore non è consentito. | 
| nessuna promessa | I processi e le promesse asincroni non sono supportati. | 

**«plugin: @aws -appsync/recommended»** fornisce alcune regole aggiuntive ma richiede anche l'aggiunta di configurazioni al progetto. TypeScript 


| Regola | Description | 
| --- | --- | 
| nessuna ricorsione | Le chiamate di funzioni ricorsive non sono consentite. | 
| no-disallowed-methods | Alcuni metodi non sono consentiti. Vedi il [riferimento](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) per un set completo di funzioni integrate supportate. | 
| no-function-passing | Non è consentito passare funzioni come argomenti di funzione alle funzioni. | 
| no-function-reassign | Le funzioni non possono essere riassegnate. | 
| no-function-return | Le funzioni non possono essere il valore restituito dalle funzioni. | 

Per aggiungere il plugin al tuo progetto, segui i passaggi di installazione e utilizzo in [Getting Started with ESLint](https://eslint.org/docs/latest/user-guide/getting-started#installation-and-usage). Quindi, installa il [plugin](https://www.npmjs.com/package/@aws-appsync/eslint-plugin) nel tuo progetto usando il gestore dei pacchetti del progetto (ad esempio, npm, yarn o pnpm):

```
$ npm install @aws-appsync/eslint-plugin
```

Nel tuo `.eslintrc.{js,yml,json}` file, aggiungi **«plugin: @aws -appsync/base» o **«plugin:** @aws -appsync/recommended» alla** proprietà. `extends` Lo snippet riportato di seguito è un esempio di configurazione di base per: `.eslintrc` JavaScript 

```
{
  "extends": ["plugin:@aws-appsync/base"]
}
```

Per utilizzare il set di regole **«plugin: @aws -appsync/recommended»**, installa la dipendenza richiesta:

```
$ npm install -D @typescript-eslint/parser
```

Quindi, crea un file: `.eslintrc.js`

```
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2018,
    "project": "./tsconfig.json"
  },
  "extends": ["plugin:@aws-appsync/recommended"]
}
```

# Raggruppamento TypeScript e mappe di origine per il runtime `APPSYNC_JS`
<a name="additional-utilities"></a>

TypeScript migliora AWS AppSync lo sviluppo garantendo la sicurezza dei tipi e il rilevamento precoce degli errori. È possibile scrivere TypeScript codice localmente e traspilarlo JavaScript prima di utilizzarlo con il runtime. `APPSYNC_JS` Il processo inizia con l'installazione TypeScript e la configurazione di tsconfig.json per l'ambiente. `APPSYNC_JS` È quindi possibile utilizzare strumenti di raggruppamento come esbuild per compilare e raggruppare il codice. L'Amplify CLI genererà tipi dallo schema GraphQL, consentendoti di utilizzare questi tipi nel codice resolver. 

È possibile utilizzare librerie personalizzate ed esterne nel codice del resolver e della funzione, purché soddisfino i requisiti. `APPSYNC_JS` Gli strumenti di raggruppamento combinano il codice in un unico file da utilizzare. AWS AppSyncÈ possibile includere mappe di origine per facilitare il debug. 

## Sfruttare le librerie e raggruppare il codice
<a name="using-external-libraries"></a>

Nel codice del resolver e della funzione, puoi sfruttare sia le librerie personalizzate che quelle esterne purché soddisfino i requisiti. `APPSYNC_JS` In questo modo è possibile riutilizzare il codice esistente nell'applicazione. Per utilizzare librerie definite da più file, è necessario utilizzare uno strumento di raggruppamento, come [esbuild](https://esbuild.github.io/), per combinare il codice in un unico file che può quindi essere salvato nel AWS AppSync resolver o nella funzione.

Quando raggruppate il codice, tenete presente quanto segue:
+ `APPSYNC_JS`supporta solo ECMAScript moduli (ESM).
+ `@aws-appsync/*`i moduli sono integrati nel `APPSYNC_JS` codice e non devono essere inclusi nel codice.
+ L'ambiente `APPSYNC_JS` di runtime è simile a NodeJS in quanto il codice non viene eseguito in un ambiente browser.
+ È possibile includere una mappa di origine opzionale. Tuttavia, non includere il contenuto di origine.

  Per ulteriori informazioni sulle mappe di origine, consulta [Utilizzo delle mappe di origine](#source-maps).

Ad esempio, per raggruppare il codice del resolver che si trova in`src/appsync/getPost.resolver.js`, è possibile utilizzare il seguente comando ESbuild CLI:

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/getPost.resolver.js
```

## Creazione del codice e utilizzo di TypeScript
<a name="working-with-typescript"></a>

[TypeScript](https://www.typescriptlang.org/)è un linguaggio di programmazione sviluppato da Microsoft che offre tutte JavaScript le funzionalità insieme al sistema di TypeScript digitazione. Puoi usarlo TypeScript per scrivere codice type-safe e catturare errori e bug in fase di compilazione prima di salvare il codice in. AWS AppSync Il `@aws-appsync/utils` pacchetto è completamente digitato.

Il `APPSYNC_JS` runtime non supporta TypeScript direttamente. È necessario prima trascrivere il TypeScript codice in JavaScript codice supportato dal `APPSYNC_JS` runtime prima di salvarlo in. AWS AppSync Puoi usarlo TypeScript per scrivere il codice nell'ambiente di sviluppo integrato (IDE) locale, ma tieni presente che non puoi creare TypeScript codice nella AWS AppSync console.

Per iniziare, assicurati di averlo [TypeScript](https://www.typescriptlang.org/download)installato nel tuo progetto. Quindi, configurate le impostazioni di TypeScript transcompilazione in modo che funzionino con il `APPSYNC_JS` runtime utilizzando. [TSConfig](https://www.typescriptlang.org/tsconfig) Ecco un esempio di `tsconfig.json` file di base che puoi usare:

```
// tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
   "noEmit": true,
   "moduleResolution": "node",
  }
}
```

È quindi possibile utilizzare uno strumento di raggruppamento come esbuild per compilare e raggruppare il codice. Ad esempio, dato un progetto il cui AWS AppSync codice si trova in`src/appsync`, è possibile utilizzare il seguente comando per compilare e raggruppare il codice:

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/**/*.ts
```

### Usare il codegen Amplify
<a name="working-with-amplify-codegen"></a>

Puoi usare la CLI [Amplify](https://docs.amplify.aws/cli/) per generare i tipi per il tuo schema. Dalla directory in cui si trova il `schema.graphql` file, esegui il comando seguente e consulta le istruzioni per configurare il codegen:

```
$  npx @aws-amplify/cli codegen add
```

Per rigenerare il codegen in determinate circostanze (ad esempio, quando lo schema viene aggiornato), esegui il comando seguente:

```
$ npx @aws-amplify/cli codegen
```

È quindi possibile utilizzare i tipi generati nel codice del resolver. Ad esempio, dato lo schema seguente:

```
type Todo {
  id: ID!
  title: String!
  description: String
}

type Mutation {
  createTodo(title: String!, description: String): Todo
}

type Query {
  listTodos: Todo
}
```

È possibile utilizzare i tipi generati nella seguente AWS AppSync funzione di esempio:

```
import { Context, util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'
import { CreateTodoMutationVariables, Todo } from './API' // codegen

export function request(ctx: Context<CreateTodoMutationVariables>) {
	ctx.args.description = ctx.args.description ?? 'created on ' + util.time.nowISO8601()
	return ddb.put<Todo>({ key: { id: util.autoId() }, item: ctx.args })
}

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

### Utilizzo di farmaci generici in TypeScript
<a name="working-with-typescript-generics"></a>

È possibile utilizzare i farmaci generici con diversi dei tipi forniti. Ad esempio, lo snippet seguente è di un tipo: `Todo`

```
export type Todo = {
  __typename: "Todo",
  id: string,
  title: string,
  description?: string | null,
};
```

È possibile scrivere un resolver per un abbonamento che utilizza. `Todo` Nel tuo IDE, le definizioni dei tipi e i suggerimenti di completamento automatico ti guideranno nell'utilizzo corretto dell'utilità di `toSubscriptionFilter` trasformazione:

```
import { util, Context, extensions } from '@aws-appsync/utils'
import { Todo } from './API'

export function request(ctx: Context) {
  return {}
}

export function response(ctx: Context) {
  const filter = util.transform.toSubscriptionFilter<Todo>({
    title: { beginsWith: 'hello' },
    description: { contains: 'created' },
  })
  extensions.setSubscriptionFilter(filter)
  return null
}
```

## Elencare i pacchetti
<a name="using-lint-with-bundles"></a>

Puoi aggiungere automaticamente il linking ai tuoi pacchetti importando il plugin. `esbuild-plugin-eslint` È quindi possibile abilitarlo fornendo un `plugins` valore che abiliti le funzionalità di eslint. Di seguito è riportato uno snippet che utilizza l' JavaScript API esbuild in un file chiamato: `build.mjs`

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

## Utilizzo delle mappe di origine
<a name="source-maps"></a>

Puoi fornire una mappa sorgente in linea (`sourcemap`) con il tuo JavaScript codice. Le mappe di origine sono utili quando si crea un pacchetto JavaScript o si TypeScript codifica e si desidera visualizzare i riferimenti ai file sorgente di input nei log e nei messaggi di errore di runtime JavaScript .

Il tuo `sourcemap` deve apparire alla fine del codice. È definito da una singola riga di commento che segue il seguente formato:

```
//# sourceMappingURL=data:application/json;base64,<base64 encoded string>
```

Ecco un esempio:

```
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibGliLmpzIiwgImNvZGUuanMiXSwKICAibWFwcGluZ3MiOiAiO0FBQU8sU0FBUyxRQUFRO0FBQ3RCLFNBQU87QUFDVDs7O0FDRE8sU0FBUyxRQUFRLEtBQUs7QUFDM0IsU0FBTyxNQUFNO0FBQ2Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
```

Le mappe di origine possono essere create con esbuild. L'esempio seguente mostra come utilizzare l' JavaScriptAPI esbuild per includere una mappa sorgente in linea quando il codice viene creato e raggruppato:

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  sourcemap: 'inline',
  sourcesContent: false,
  
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

In particolare, le `sourcesContent` opzioni `sourcemap` and specificano che una mappa di origine deve essere aggiunta in linea alla fine di ogni build ma non deve includere il contenuto sorgente. Per convenzione, consigliamo di non includere il contenuto sorgente nel tuo`sourcemap`. Puoi disabilitarlo in esbuild impostando `sources-content` su`false`.

Per illustrare come funzionano le mappe di origine, guarda il seguente esempio in cui un codice resolver fa riferimento alle funzioni di supporto di una libreria di supporto. Il codice contiene istruzioni di registro nel codice del resolver e nella libreria helper:

**. /src/default.resolver.ts** (il tuo resolver)

```
import { Context } from '@aws-appsync/utils'
import { hello, logit } from './helper'

export function request(ctx: Context) {
  console.log('start >')
  logit('hello world', 42, true)
  console.log('< end')
  return 'test'
}

export function response(ctx: Context): boolean {
  hello()
  return ctx.prev.result
}
```

**.src/helper.ts (un file** di supporto)

```
export const logit = (...rest: any[]) => {
  // a special logger
  console.log('[logger]', ...rest.map((r) => `<${r}>`))
}

export const hello = () => {
  // This just returns a simple sentence, but it could do more.
  console.log('i just say hello..')
}
```

Quando create e raggruppate il file resolver, il codice del resolver includerà una mappa sorgente in linea. Quando il resolver è in esecuzione, nei log vengono visualizzate le seguenti voci: CloudWatch 

![\[CloudWatch log entries showing resolver code execution with inline source map information.\]](http://docs.aws.amazon.com/it_it/appsync/latest/devguide/images/cloudwatch-sourcemap.jpeg)


Esaminando le voci del CloudWatch registro, noterai che le funzionalità dei due file sono state raggruppate e vengono eseguite contemporaneamente. Il nome originale di ogni file si riflette chiaramente anche nei log.

# Verifica del resolver e dei gestori di funzioni in AWS AppSync
<a name="test-resolvers"></a>

È possibile utilizzare il comando `EvaluateCode` API per testare in remoto il resolver e i gestori di funzioni con dati simulati prima di salvare il codice su un resolver o su una funzione. Per iniziare a usare il comando, assicurati di aver aggiunto l'autorizzazione alla tua policy. `appsync:evaluatecode` 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 la [AWS[AWS SDKs](https://aws.amazon.com/tools/)CLI o](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/index.html). Ad esempio, per testare il codice utilizzando la CLI, è sufficiente puntare al file, fornire un contesto e specificare il gestore che si desidera valutare:

```
aws appsync evaluate-code \
  --code file://code.js \
  --function request \
  --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": "{\"operation\":\"PutItem\",\"key\":{\"id\":{\"S\":\"record-id\"}},\"attributeValues\":{\"owner\":{\"S\":\"John doe\"},\"expectedVersion\":{\"N\":2},\"authorId\":{\"S\":\"Sammy Davis\"}}}",
    "logs": [
        "INFO - code.js:5:3: \"current id\" \"record-id\"",
        "INFO - code.js:9:3: \"request evaluated\""
    ]
}
```

Il risultato della valutazione può essere analizzato come JSON, il che fornisce:

```
{
  "operation": "PutItem",
  "key": {
    "id": {
      "S": "record-id"
    }
  },
  "attributeValues": {
    "owner": {
      "S": "John doe"
    },
    "expectedVersion": {
      "N": 2
    },
    "authorId": {
      "S": "Sammy Davis"
    }
  }
}
```

Utilizzando l'SDK, puoi incorporare facilmente i test della tua suite di test per convalidare il comportamento del codice. Il nostro esempio qui utilizza il [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' })
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
```

# Migrazione da VTL a in JavaScript AWS AppSync
<a name="migrating-resolvers"></a>

AWS AppSync consente di scrivere la logica aziendale per i resolver e le funzioni utilizzando VTL o. JavaScript Con entrambi i linguaggi, si scrive una logica che istruisce il AWS AppSync servizio su come interagire con le fonti di dati. Con VTL, si scrivono modelli di mappatura che devono restituire una stringa con codifica JSON valida. Con JavaScript, si scrivono gestori di richieste e risposte che restituiscono oggetti. Non restituisci una stringa con codifica JSON.

Ad esempio, utilizza il seguente modello di mappatura VTL per ottenere un elemento Amazon DynamoDB:

```
{
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
    }
}
```

L'utilità `$util.dynamodb.toDynamoDBJson` restituisce una stringa con codifica JSON. Se `$ctx.args.id` è impostato su`<id>`, il modello restituisce una stringa con codifica JSON valida:

```
{
    "operation": "GetItem",
    "key": {
        "id": {"S": "<id>"},
    }
}
```

Quando si lavora con JavaScript, non è necessario stampare stringhe non elaborate con codifica JSON all'interno del codice e non è necessario utilizzare un'utilità simile. `toDynamoDBJson` Un esempio equivalente del modello di mappatura precedente è:

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'GetItem',
    key: {id: util.dynamodb.toDynamoDB(ctx.args.id)}
  };
}
```

Un'alternativa consiste nell'utilizzare`util.dynamodb.toMapValues`, che è l'approccio consigliato per gestire un oggetto di valori:

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'GetItem',
    key: util.dynamodb.toMapValues({ id: ctx.args.id }),
  };
}
```

Ciò equivale a:

```
{
  "operation": "GetItem",
  "key": {
    "id": {
      "S": "<id>"
    }
  }
}
```

**Nota**  
Consigliamo di utilizzare il modulo DynamoDB con sorgenti dati DynamoDB:  

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	ddb.get({ key: { id: ctx.args.id } })
}
```

Come altro esempio, prendi il seguente modello di mappatura per inserire un elemento in un'origine dati Amazon DynamoDB:

```
{
    "operation" : "PutItem",
    "key" : {
        "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

Una volta valutata, questa stringa del modello di mappatura deve produrre una stringa con codifica JSON valida. Quando si utilizza JavaScript, il codice restituisce direttamente l'oggetto della richiesta:

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { id = util.autoId(), ...values } = ctx.args;
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ id }),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

che restituisce:

```
{
  "operation": "PutItem",
  "key": {
    "id": { "S": "2bff3f05-ff8c-4ed8-92b4-767e29fc4e63" }
  },
  "attributeValues": {
    "firstname": { "S": "Shaggy" },
    "age": { "N": 4 }
  }
}
```

**Nota**  
Consigliamo di utilizzare il modulo DynamoDB con sorgenti dati DynamoDB:  

```
import { util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	const { id = util.autoId(), ...item } = ctx.args
	return ddb.put({ key: { id }, item })
}
```

# Scelta tra accesso diretto alla fonte di dati e invio di proxy tramite un'origine dati Lambda
<a name="choosing-data-source"></a>

Con AWS AppSync and the `APPSYNC_JS` runtime, puoi scrivere il tuo codice che implementa la tua logica aziendale personalizzata utilizzando AWS AppSync funzioni per accedere alle tue fonti di dati. Ciò semplifica l'interazione diretta con fonti di dati come Amazon DynamoDB, Aurora OpenSearch Serverless, Service APIs, HTTP AWS e altri servizi senza dover implementare servizi o infrastrutture di calcolo aggiuntivi. AWS AppSync semplifica inoltre l'interazione con una AWS Lambda funzione configurando un'origine dati Lambda. Le sorgenti dati Lambda consentono di eseguire logiche aziendali complesse utilizzando le funzionalità complete AWS Lambda di cui dispone per risolvere una richiesta GraphQL. Nella maggior parte dei casi, una AWS AppSync funzione connessa direttamente alla fonte di dati di destinazione fornirà tutte le funzionalità necessarie. In situazioni in cui è necessario implementare una logica aziendale complessa non supportata dal `APPSYNC_JS` runtime, è possibile utilizzare un'origine dati Lambda come proxy per interagire con l'origine dati di destinazione.


|  |  |  | 
| --- |--- |--- |
|  | Integrazione diretta delle fonti di dati | Fonte dati Lambda come proxy | 
| Caso d'uso | AWS AppSync le funzioni interagiscono direttamente con le fonti di dati API. | AWS AppSync le funzioni chiamano Lambda che interagiscono con le fonti di dati API. | 
| Runtime | APPSYNC\$1JS (JavaScript) | Qualsiasi runtime Lambda supportato | 
| Dimensione massima del codice | 32.000 caratteri per funzione AWS AppSync | 50 MB (zippato, per il caricamento diretto) per Lambda | 
| Moduli esterni | Limitato: solo funzionalità supportate da APPSYNC\$1JS | Sì | 
|  AWS Chiama qualsiasi servizio | Sì, utilizzando l'origine dati AWS AppSync HTTP | Sì, utilizzando SDK AWS  | 
| Accesso all'intestazione della richiesta | Sì | Sì | 
| Accesso alla rete | No | Sì | 
| Accesso al file system | No | Sì | 
| Registrazione e metriche | Sì | Sì | 
| Crea e testa interamente all'interno AppSync | Sì | No | 
| Avvio a freddo | No | No, con concorrenza preimpostata | 
| Dimensionamento automatico | Sì, in modo trasparente tramite AWS AppSync | Sì, come configurato in Lambda | 
| Prezzi | Nessun costo aggiuntivo | Addebitato per l'utilizzo di Lambda | 

AWS AppSync le funzioni che si integrano direttamente con la fonte di dati di destinazione sono ideali per casi d'uso come i seguenti:
+  Interazione con Amazon DynamoDB, Aurora Serverless e Service OpenSearch 
+  Interazione con HTTP e passaggio di intestazioni in entrata APIs 
+  Interazione con AWS i servizi utilizzando sorgenti dati HTTP (con firma AWS AppSync automatica delle richieste con il ruolo di origine dati fornito) 
+  Implementazione del controllo dell'accesso prima di accedere alle fonti di dati 
+  Implementazione del filtraggio dei dati recuperati prima di soddisfare una richiesta 
+  Implementazione di un'orchestrazione semplice con esecuzione sequenziale di funzioni in una pipeline di resolver AWS AppSync 
+  Controllo delle connessioni di caching e sottoscrizione nelle query e nelle mutazioni. 

AWS AppSync le funzioni che utilizzano un'origine dati Lambda come proxy sono ideali per casi d'uso come i seguenti:
+  Utilizzo di un linguaggio diverso JavaScript da Velocity Template Language (VTL) 
+  Regolazione e controllo della CPU o della memoria per ottimizzare le prestazioni 
+  Importazione di librerie di terze parti o richiesta di funzionalità non supportate in `APPSYNC_JS` 
+  Effettuare più richieste di rete, and/or ottenere l'accesso al file system per soddisfare una richiesta 
+  Richieste in batch utilizzando la configurazione in [batch.](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-lambda-js.html) 