Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
AWS AppSync JavaScript référence de la fonction de résolution pour Amazon RDS
La fonction et le résolveur AWS AppSync RDS permettent aux développeurs d'envoyer SQL des requêtes à une base de données de cluster Amazon Aurora à l'aide de l'API RDS Data et de récupérer le résultat de ces requêtes. Vous pouvez écrire SQL des instructions qui sont envoyées à l'API Data en utilisant le modèle sql étiqueté par rds module AWS AppSync du module ou en utilisant les rds fonctionsselect, insertupdate, et remove helper du module. AWS AppSync utilise l'ExecuteStatementaction du service de données RDS pour exécuter des instructions SQL sur la base de données.
Rubriques
Modèle balisé SQL
AWS AppSync Le modèle sql balisé de Microsoft vous permet de créer une instruction statique qui peut recevoir des valeurs dynamiques lors de l'exécution à l'aide d'expressions de modèle. AWS AppSync crée une carte variable à partir des valeurs d'expression pour créer une SqlParameterized requête qui est envoyée à l'API de données Amazon Aurora Serverless. Avec cette méthode, il n'est pas possible que les valeurs dynamiques transmises au moment de l'exécution modifient l'instruction d'origine, ce qui pourrait provoquer une exécution involontaire. Toutes les valeurs dynamiques sont transmises en tant que paramètres, ne peuvent pas modifier l'instruction d'origine et ne sont pas exécutées par la base de données. Cela rend votre requête moins vulnérable aux attaques SQL par injection.
Note
Dans tous les cas, lorsque vous rédigez SQL des déclarations, vous devez suivre les consignes de sécurité afin de gérer correctement les données que vous recevez en entrée.
Note
Le modèle sql balisé prend uniquement en charge la transmission de valeurs de variables. Vous ne pouvez pas utiliser d'expression pour spécifier dynamiquement les noms des colonnes ou des tables. Vous pouvez toutefois utiliser des fonctions utilitaires pour créer des instructions dynamiques.
Dans l'exemple suivant, nous créons une requête qui filtre en fonction de la valeur de l'colargument défini dynamiquement dans la requête GraphQL au moment de l'exécution. La valeur ne peut être ajoutée à l'instruction qu'à l'aide de l'expression de balise :
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); }
En transmettant toutes les valeurs dynamiques via la carte des variables, nous nous appuyons sur le moteur de base de données pour gérer et assainir les valeurs en toute sécurité.
Création de relevés
Les fonctions et les résolveurs peuvent interagir avec les bases de données MySQL et PostgreSQL. Utilisez createMySQLStatement et createPgStatement respectivement pour créer des déclarations. Par exemple, createMySQLStatement vous pouvez créer une requête MySQL. Ces fonctions acceptent jusqu'à deux instructions, ce qui est utile lorsqu'une requête doit récupérer des résultats immédiatement. Avec MySQL, vous pourriez faire :
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); }
Note
createPgStatementet createMySQLStatement n'échappe pas aux instructions créées avec le modèle sql balisé et ne les cite pas.
Récupération des données
Le résultat de l'instruction SQL exécutée est disponible dans le gestionnaire de réponses de l'context.resultobjet. Le résultat est une chaîne JSON contenant les éléments de réponse de l'ExecuteStatementaction. Une fois analysé, le résultat a la forme suivante :
type SQLStatementResults = { sqlStatementResults: { records: any[]; columnMetadata: any[]; numberOfRecordsUpdated: number; generatedFields?: any[] }[] }
Vous pouvez utiliser cet toJsonObject utilitaire pour transformer le résultat en une liste d'objets JSON représentant les lignes renvoyées. Par exemple :
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] }
Notez que cela toJsonObject renvoie un tableau de résultats de déclaration. Si vous avez fourni une seule instruction, la longueur du tableau est de1. Si vous avez fourni deux instructions, la longueur du tableau est de2. Chaque résultat du tableau contient 0 ou plusieurs lignes. toJsonObjectrenvoie null si la valeur du résultat n'est pas valide ou inattendue.
Fonctions utilitaires
Vous pouvez utiliser les utilitaires du module AWS AppSync RDS pour interagir avec votre base de données.
L'selectutilitaire crée une SELECT instruction pour interroger votre base de données relationnelle.
Utilisation de base
Dans sa forme de base, vous pouvez spécifier la table que vous souhaitez interroger :
import { select, createPgStatement } from '@aws-appsync/utils/rds'; export function request(ctx) { // Generates statement: // "SELECT * FROM "persons" return createPgStatement(select({table: 'persons'})); }
Notez que vous pouvez également spécifier le schéma dans l'identifiant de votre table :
import { select, createPgStatement } from '@aws-appsync/utils/rds'; export function request(ctx) { // Generates statement: // SELECT * FROM "private"."persons" return createPgStatement(select({table: 'private.persons'})); }
Spécification des colonnes
Vous pouvez spécifier des colonnes à l'aide de columns cette propriété. Si aucune valeur n'est définie, la valeur par défaut est la suivante : *
export function request(ctx) { // Generates statement: // SELECT "id", "name" // FROM "persons" return createPgStatement(select({ table: 'persons', columns: ['id', 'name'] })); }
Vous pouvez également spécifier le tableau d'une colonne :
export function request(ctx) { // Generates statement: // SELECT "id", "persons"."name" // FROM "persons" return createPgStatement(select({ table: 'persons', columns: ['id', 'persons.name'] })); }
Limites et décalages
Vous pouvez postuler limit et répondre offset à la requête :
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 })); }
Commander par
Vous pouvez trier vos résultats avec la orderBy propriété. Fournissez un tableau d'objets spécifiant la colonne et une dir propriété facultative :
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'}] })); }
Filtres
Vous pouvez créer des filtres à l'aide de l'objet de condition spéciale :
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'}} })); }
Vous pouvez également combiner des filtres :
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}} })); }
Vous pouvez également créer des OR relevés :
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 } } ]} })); }
Vous pouvez également annuler une condition avec 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 } } ]} })); }
Vous pouvez également utiliser les opérateurs suivants pour comparer les valeurs :
| Opérateur | Description | Types de valeurs possibles |
|---|---|---|
| eq | Égal à | nombre, chaîne de caractères, booléen |
| ne | Non égal à | nombre, chaîne de caractères, booléen |
| le | Inférieur ou égal à | numéro, chaîne |
| lt | Inférieur à | numéro, chaîne |
| gm | Supérieur ou égal à | numéro, chaîne |
| gt | Supérieur à | numéro, chaîne |
| contient | Comme | chaîne |
| Ne contient pas | Pas comme | chaîne |
| Commence par | Commence par un préfixe | chaîne |
| between | Entre deux valeurs | numéro, chaîne |
| L'attribut existe | L'attribut n'est pas nul | nombre, chaîne de caractères, booléen |
| size | vérifie la longueur de l'élément | chaîne |
L'insertutilitaire fournit un moyen simple d'insérer des éléments d'une seule ligne dans votre base de données à l'aide de cette INSERT opération.
Insertions d'articles uniques
Pour insérer un élément, spécifiez le tableau, puis transmettez votre objet de valeurs. Les clés des objets sont mappées aux colonnes de votre tableau. Les noms de colonnes sont automatiquement échappés et les valeurs sont envoyées à la base de données à l'aide de la variable map :
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) }
Cas d'utilisation de MySQL
Vous pouvez combiner un insert suivi d'un select pour récupérer la ligne que vous avez insérée :
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) }
Cas d'utilisation de Postgres
Avec Postgres, vous pouvez utiliser returning* ou un tableau de noms de colonnes :
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'updateutilitaire vous permet de mettre à jour les lignes existantes. Vous pouvez utiliser l'objet de condition pour appliquer des modifications aux colonnes spécifiées dans toutes les lignes qui satisfont à la condition. Par exemple, supposons que nous ayons un schéma qui nous permet d'effectuer cette mutation. Nous voulons mettre à jour le name of Person avec la id valeur de3, mais uniquement si nous les connaissons (known_since) depuis l'année 2000 :
mutation Update { updatePerson( input: {id: 3, name: "Jon"}, condition: {known_since: {ge: "2000"}} ) { id name } }
Notre résolveur de mises à jour ressemble à ceci :
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) }
Nous pouvons ajouter une vérification à notre condition pour nous assurer que seule la ligne dont la clé primaire est id égale à 3 est mise à jour. De même, pour Postgresinserts, vous pouvez utiliser returning pour renvoyer les données modifiées.
L'removeutilitaire vous permet de supprimer des lignes existantes. Vous pouvez utiliser l'objet de condition sur toutes les lignes qui satisfont à la condition. Notez qu'il delete s'agit d'un mot clé réservé dans JavaScript. removedoit être utilisé à la place :
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) }
Forçage de type
Dans certains cas, vous souhaiterez peut-être être plus précis quant au type d'objet correct à utiliser dans votre instruction. Vous pouvez utiliser les conseils de type fournis pour spécifier le type de vos paramètres. AWS AppSync prend en charge les mêmes indicateurs de type que l'API Data. Vous pouvez convertir vos paramètres à l'aide typeHint des fonctions du AWS AppSync rds module.
L'exemple suivant vous permet d'envoyer un tableau sous la forme d'une valeur convertie en objet JSON. Nous utilisons l'->opérateur pour récupérer l'élément situé index 2 dans le tableau 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 }
Le casting est également utile pour manipuler et comparer DATETIME, et 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) }
Voici un autre exemple montrant comment envoyer la date et l'heure actuelles :
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)}`) }
Indications de type disponibles
-
typeHint.DATE- Le paramètre correspondant est envoyé en tant qu'objet duDATEtype à la base de données. Le format accepté estYYYY-MM-DD. -
typeHint.DECIMAL- Le paramètre correspondant est envoyé en tant qu'objet duDECIMALtype à la base de données. -
typeHint.JSON- Le paramètre correspondant est envoyé en tant qu'objet duJSONtype à la base de données. -
typeHint.TIME- La valeur de paramètre de chaîne correspondante est envoyée en tant qu'objet duTIMEtype à la base de données. Le format accepté estHH:MM:SS[.FFF]. -
typeHint.TIMESTAMP- La valeur de paramètre de chaîne correspondante est envoyée en tant qu'objet duTIMESTAMPtype à la base de données. Le format accepté estYYYY-MM-DD HH:MM:SS[.FFF]. -
typeHint.UUID- La valeur de paramètre de chaîne correspondante est envoyée en tant qu'objet duUUIDtype à la base de données.