

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 riferimento alla funzione resolver per Amazon RDS
<a name="resolver-reference-rds-js"></a>

La funzione e il resolver AWS AppSync RDS consentono agli sviluppatori di inviare SQL query a un database cluster Amazon Aurora utilizzando l'API RDS Data e recuperare il risultato di queste query. Puoi scrivere SQL istruzioni che vengono inviate all'API Data utilizzando il modello con `sql` tag AWS AppSync del `rds` modulo o utilizzando le funzioni di supporto,, e di supporto del `rds` modulo. `select` `insert` `update` `remove` AWS AppSync utilizza l'[`ExecuteStatement`](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_ExecuteStatement.html)azione di RDS Data Service per eseguire istruzioni SQL sul database. 

**Argomenti**
+ [Modello con tag SQL](#sql-tagged-templates)
+ [Creazione di dichiarazioni](#creating-statements)
+ [Recupero dei dati](#retrieving-data)
+ [Funzioni di utilità](#utility-functions)
+ [Selezione SQL](#utility-functions-select)
+ [SQL Insert](#utility-functions-insert)
+ [Aggiornamento SQL](#utility-functions-update)
+ [SQL Delete](#utility-functions-delete)
+ [Casting](#casting)

## Modello con tag SQL
<a name="sql-tagged-templates"></a>

AWS AppSync il modello `sql` con tag consente di creare un'istruzione statica in grado di ricevere valori dinamici in fase di esecuzione utilizzando le espressioni del modello. AWS AppSync crea una mappa variabile dai valori delle espressioni per creare una [`SqlParameterized`](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_SqlParameter.html) query che viene inviata all'API Amazon Aurora Serverless Data. Con questo metodo, non è possibile che i valori dinamici passati in fase di esecuzione modifichino l'istruzione originale, il che potrebbe causare un'esecuzione involontaria. Tutti i valori dinamici vengono passati come parametri, non possono modificare l'istruzione originale e non vengono eseguiti dal database. Ciò rende la tua query meno vulnerabile agli attacchi di SQL iniezione.

**Nota**  
In tutti i casi, quando si scrivono SQL dichiarazioni, è necessario seguire le linee guida di sicurezza per gestire correttamente i dati che si ricevono come input.

**Nota**  
Il modello `sql` con tag supporta solo il passaggio di valori variabili. Non è possibile utilizzare un'espressione per specificare dinamicamente i nomi delle colonne o delle tabelle. Tuttavia, è possibile utilizzare le funzioni di utilità per creare istruzioni dinamiche.

Nel seguente esempio, creiamo una query che filtra in base al valore dell'`col`argomento impostato dinamicamente nella query GraphQL in fase di esecuzione. Il valore può essere aggiunto all'istruzione solo utilizzando l'espressione del tag:

```
import { sql, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
  const query = sql`
SELECT * FROM table 
WHERE column = ${ctx.args.col}`
  ;
  return createMySQLStatement(query);
}
```

Passando tutti i valori dinamici attraverso la mappa delle variabili, ci affidiamo al motore del database per gestire e sanificare i valori in modo sicuro.

## Creazione di dichiarazioni
<a name="creating-statements"></a>

Le funzioni e i resolver possono interagire con i database MySQL e PostgreSQL. `createPgStatement`Usa `createMySQLStatement` e rispettivamente per creare dichiarazioni. Ad esempio, `createMySQLStatement` può creare una query MySQL. Queste funzioni accettano fino a due istruzioni, utili quando una richiesta deve recuperare immediatamente i risultati. Con MySQL, potresti fare:

```
import { sql, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { id, text } = ctx.args;
    const s1 = sql`insert into Post(id, text) values(${id}, ${text})`;
    const s2 = sql`select * from Post where id = ${id}`;
    return createMySQLStatement(s1, s2);
}
```

**Nota**  
`createPgStatement`e `createMySQLStatement` non sfugge né cita le istruzioni create con il modello `sql` contrassegnato.

## Recupero dei dati
<a name="retrieving-data"></a>

Il risultato dell'istruzione SQL eseguita è disponibile nel gestore delle risposte nell'`context.result`oggetto. Il risultato è una stringa JSON con gli elementi di [ risposta ](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_ExecuteStatement.html#API_ExecuteStatement_ResponseElements) dell'azione`ExecuteStatement`. Quando viene analizzato, il risultato ha la seguente forma:

```
type SQLStatementResults = {
    sqlStatementResults: {
        records: any[];
        columnMetadata: any[];
        numberOfRecordsUpdated: number;
        generatedFields?: any[]
    }[]
}
```

È possibile utilizzare l'`toJsonObject`utilità per trasformare il risultato in un elenco di oggetti JSON che rappresentano le righe restituite. Ad esempio:

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

export function response(ctx) {
    const { error, result } = ctx;
    if (error) {
        return util.appendError(
            error.message,
            error.type,
            result
        )
    }
    return toJsonObject(result)[1][0]
}
```

Nota che `toJsonObject` restituisce una serie di risultati delle dichiarazioni. Se hai fornito un'istruzione, la lunghezza dell'array è`1`. Se hai fornito due istruzioni, la lunghezza dell'array è`2`. Ogni risultato nell'array contiene `0` o più righe. `toJsonObject`restituisce `null` se il valore del risultato non è valido o non è previsto.

## Funzioni di utilità
<a name="utility-functions"></a>

È possibile utilizzare gli helper di utilità del modulo AWS AppSync RDS per interagire con il database.

### Selezione SQL
<a name="utility-functions-select"></a>

L'`select`utilità crea un'`SELECT`istruzione per interrogare il database relazionale. 

**Uso di base **

Nella sua forma base, puoi specificare la tabella su cui vuoi interrogare:

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement: 
    // "SELECT * FROM "persons"
    return createPgStatement(select({table: 'persons'}));
}
```

Nota che puoi anche specificare lo schema nell'identificatore della tua tabella:

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement:
    // SELECT * FROM "private"."persons"
    return createPgStatement(select({table: 'private.persons'}));
}
```

**Specificare le colonne **

È possibile specificare le colonne con la `columns` proprietà. Se non è impostato su un valore, il valore predefinito è: `*`

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name']
    }));
}
```

Puoi anche specificare la tabella di una colonna:

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "persons"."name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'persons.name']
    }));
}
```

**Limiti e offset **

È possibile applicare `limit` e `offset` alla richiesta:

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name"
    // FROM "persons"
    // LIMIT :limit
    // OFFSET :offset
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        limit: 10,
        offset: 40
    }));
}
```

**Ordina per **

Puoi ordinare i risultati con la `orderBy` proprietà. Fornisci una serie di oggetti che specificano la colonna e una `dir` proprietà opzionale:

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name" FROM "persons"
    // ORDER BY "name", "id" DESC
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        orderBy: [{column: 'name'}, {column: 'id', dir: 'DESC'}]
    }));
}
```

**Filtri**

È possibile creare filtri utilizzando l'oggetto condizionale speciale:

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}}
    }));
}
```

Puoi anche combinare filtri:

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME and "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}, id: {gt: 10}}
    }));
}
```

Puoi anche creare `OR` dichiarazioni:

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME OR "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { or: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

Puoi anche annullare una condizione con`not`:

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE NOT ("name" = :NAME AND "id" > :ID)
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { not: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

È inoltre possibile utilizzare i seguenti operatori per confrontare i valori:


| 
| 
| Operatore | Description | Tipi di valori possibili | 
| --- |--- |--- |
| eq | Uguale | numero, stringa, booleano | 
| uno | Non uguale | numero, stringa, booleano | 
| le | Minore di o uguale a | numero, stringa | 
| lt | Less than | numero, stringa | 
| età | Maggiore di o uguale a | numero, stringa | 
| gt | Greater than | numero, stringa | 
| contiene | Mi piace | stringa | 
| NON contiene | Non mi piace | stringa | 
| Inizia con | Inizia con il prefisso | stringa | 
| tra | Tra due valori | numero, stringa | 
| L'attributo esiste | L'attributo non è nullo | numero, stringa, booleano | 
| formato | controlla la lunghezza dell'elemento | stringa | 

### SQL Insert
<a name="utility-functions-insert"></a>

L'`insert`utilità fornisce un modo semplice per inserire elementi a riga singola nel database con l'operazione. `INSERT`

**Inserimenti di elementi singoli **

Per inserire un elemento, specifica la tabella e quindi trasmetti il tuo oggetto di valori. Le chiavi dell'oggetto sono mappate alle colonne della tabella. I nomi delle colonne vengono eliminati automaticamente e i valori vengono inviati al database utilizzando la mappa delle variabili:

```
import { insert, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({ table: 'persons', values });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    return createMySQLStatement(insertStatement)
}
```

**Caso d'uso MySQL **

Puoi combinare un `insert` seguito da `select` a per recuperare la riga inserita:

```
import { insert, select, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({  table: 'persons', values });
    const selectStatement = select({
        table: 'persons',
        columns: '*',
        where: { id: { eq: values.id } },
        limit: 1,
    });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    // and
    // SELECT *
    // FROM `persons`
    // WHERE `id` = :ID
    return createMySQLStatement(insertStatement, selectStatement)
}
```

**Caso d'uso di Postgres **

Con Postgres, puoi utilizzarlo [`returning`](https://www.postgresql.org/docs/current/dml-returning.html) per ottenere dati dalla riga che hai inserito. Accetta `*` o un array di nomi di colonne:

```
import { insert, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({
        table: 'persons',
        values,
        returning: '*'
    });

    // Generates statement:
    // INSERT INTO "persons"("name")
    // VALUES(:NAME)
    // RETURNING *
    return createPgStatement(insertStatement)
}
```

### Aggiornamento SQL
<a name="utility-functions-update"></a>

L'`update`utilità consente di aggiornare le righe esistenti. È possibile utilizzare l'oggetto condizione per applicare le modifiche alle colonne specificate in tutte le righe che soddisfano la condizione. Ad esempio, supponiamo di avere uno schema che ci consenta di effettuare questa mutazione. Vogliamo aggiornare `name` of `Person` con il `id` valore di `3` ma solo se li conosciamo (`known_since`) dall'anno`2000`:

```
mutation Update {
    updatePerson(
        input: {id: 3, name: "Jon"},
        condition: {known_since: {ge: "2000"}}
    ) {
    id
    name
  }
}
```

Il nostro risolutore di aggiornamenti ha il seguente aspetto:

```
import { update, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id, ...values }, condition } = ctx.args;
    const where = {
        ...condition,
        id: { eq: id },
    };
    const updateStatement = update({
        table: 'persons',
        values,
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // UPDATE "persons"
    // SET "name" = :NAME, "birthday" = :BDAY, "country" = :COUNTRY
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

Possiamo aggiungere un controllo alla nostra condizione per assicurarci che venga aggiornata solo la riga con la chiave primaria `id` uguale a`3`. Allo stesso modo, per Postgres`inserts`, puoi utilizzare `returning` per restituire i dati modificati. 

### SQL Delete
<a name="utility-functions-delete"></a>

L'`remove`utilità consente di eliminare le righe esistenti. È possibile utilizzare l'oggetto condizione su tutte le righe che soddisfano la condizione. Nota che `delete` è una parola chiave riservata in JavaScript. `remove`dovrebbe essere usato invece:

```
import { remove, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id }, condition } = ctx.args;
    const where = { ...condition, id: { eq: id } };
    const deleteStatement = remove({
        table: 'persons',
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // DELETE "persons"
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

## Casting
<a name="casting"></a>

In alcuni casi, potresti volere una maggiore specificità sul tipo di oggetto corretto da utilizzare nella tua dichiarazione. È possibile utilizzare i suggerimenti di tipo forniti per specificare il tipo di parametri. AWS AppSync supporta gli [ stessi suggerimenti di tipo dell'](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_SqlParameter.html#rdsdtataservice-Type-SqlParameter-typeHint)API Data. Puoi trasmettere i tuoi parametri utilizzando le `typeHint` funzioni del AWS AppSync `rds` modulo. 

L'esempio seguente consente di inviare un array come valore che viene convertito come oggetto JSON. Usiamo l'`->`operatore per recuperare l'elemento `index` `2` nell'array JSON:

```
import { sql, createPgStatement, toJsonObject, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const arr = ctx.args.list_of_ids
    const statement = sql`select ${typeHint.JSON(arr)}->2 as value`
    return createPgStatement(statement)
}

export function response(ctx) {
    return toJsonObject(ctx.result)[0][0].value
}
```

Il casting è utile anche per la gestione e il confronto `DATE` e`TIME`: `TIMESTAMP`

```
import { select, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const when = ctx.args.when
    const statement = select({
        table: 'persons',
        where: { createdAt : { gt: typeHint.DATETIME(when) } }
    })
    return createPgStatement(statement)
}
```

Ecco un altro esempio che mostra come inviare la data e l'ora correnti:

```
import { sql, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const now = util.time.nowFormatted('YYYY-MM-dd HH:mm:ss')
    return createPgStatement(sql`select ${typeHint.TIMESTAMP(now)}`)
}
```

**Suggerimenti sui tipi disponibili **
+ `typeHint.DATE`- Il parametro corrispondente viene inviato come oggetto del `DATE` tipo al database. Il formato accettato è `YYYY-MM-DD`.
+ `typeHint.DECIMAL`- Il parametro corrispondente viene inviato come oggetto del `DECIMAL` tipo al database.
+ `typeHint.JSON`- Il parametro corrispondente viene inviato come oggetto del `JSON` tipo al database.
+ `typeHint.TIME`- Il valore del parametro stringa corrispondente viene inviato come oggetto del `TIME` tipo al database. Il formato accettato è `HH:MM:SS[.FFF]`. 
+ `typeHint.TIMESTAMP`- Il valore del parametro stringa corrispondente viene inviato come oggetto del `TIMESTAMP` tipo al database. Il formato accettato è `YYYY-MM-DD HH:MM:SS[.FFF]`.
+ `typeHint.UUID`- Il valore del parametro stringa corrispondente viene inviato come oggetto del `UUID` tipo al database.