View a markdown version of this page

AWS AppSync JavaScript riferimento alla funzione resolver per Amazon RDS - AWS AppSync GraphQL

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

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'ExecuteStatementazione di RDS Data Service per eseguire istruzioni SQL sul database.

Modello con tag SQL

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 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'colargomento 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

Le funzioni e i resolver possono interagire con i database MySQL e PostgreSQL. createPgStatementUsa 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

createPgStatemente createMySQLStatement non sfugge né cita le istruzioni create con il modello sql contrassegnato.

Recupero dei dati

Il risultato dell'istruzione SQL eseguita è disponibile nel gestore delle risposte nell'context.resultoggetto. Il risultato è una stringa JSON con gli elementi di risposta dell'azioneExecuteStatement. Quando viene analizzato, il risultato ha la seguente forma:

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

È possibile utilizzare l'toJsonObjectutilità 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. toJsonObjectrestituisce null se il valore del risultato non è valido o non è previsto.

Funzioni di utilità

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

L'selectutilità crea un'SELECTistruzione 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 connot:

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

L'insertutilità 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 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) }

L'updateutilità 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'anno2000:

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 a3. Allo stesso modo, per Postgresinserts, puoi utilizzare returning per restituire i dati modificati.

L'removeutilità 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. removedovrebbe 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

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'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 eTIME: 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.