AWS AppSync JavaScript referencia de la función de resolución para Amazon RDS - AWS AppSync

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

AWS AppSync JavaScript referencia de la función de resolución para Amazon RDS

La AWS AppSync RDS función y el solucionador permiten a los desarrolladores enviar SQL consulta una base de datos de clústeres de Amazon Aurora utilizando los RDS datos API y obtiene el resultado de estas consultas. Puede escribir SQL declaraciones que se envían a los datos API mediante la plantilla sql etiquetada como rds módulo AWS AppSync del rds módulo o mediante las funciones remove auxiliaresselect, insertupdate, y del módulo. AWS AppSync utiliza la ExecuteStatementacción del Servicio RDS de Datos para comparar las SQL declaraciones con la base de datos.

SQLplantilla etiquetada

AWS AppSync La plantilla sql etiquetada le permite crear una declaración estática que puede recibir valores dinámicos en tiempo de ejecución mediante el uso de expresiones de plantilla. AWS AppSync crea un mapa de variables a partir de los valores de la expresión para crear una SqlParameterizedconsulta que se envía a Amazon Aurora Serverless DataAPI. Con este método, no es posible que los valores dinámicos pasados en tiempo de ejecución modifiquen la instrucción original, lo que podría provocar una ejecución no intencionada. Todos los valores dinámicos se pasan como parámetros, no pueden modificar la instrucción original y la base de datos no los ejecuta. Esto hace que su consulta sea menos vulnerable a SQL ataques de inyección.

nota

En todos los casos, al escribir SQL En las declaraciones, debe seguir las pautas de seguridad para manejar adecuadamente los datos que reciba como entrada.

nota

La plantilla con etiquetas sql solo admite la transferencia de valores variables. No puede usar una expresión para especificar dinámicamente los nombres de las columnas o tablas. No obstante, puede usar funciones de utilidad para crear instrucciones dinámicas.

En el siguiente ejemplo, creamos una consulta que filtra en función del valor del argumento col que se establece dinámicamente en la consulta GraphQL en tiempo de ejecución. El valor solo se puede añadir a la instrucción mediante la expresión de etiquetas:

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); }

Al pasar todos los valores dinámicos por el mapa de variables, confiamos en el motor de la base de datos para gestionar y sanear los valores de forma segura.

Creación de instrucciones

Las funciones y los resolutores pueden interactuar con las bases de datos My SQL y PostgreSQL. Utilice createMySQLStatement y createPgStatement, respectivamente, para crear instrucciones. Por ejemplo, createMySQLStatement puede crear una consulta My. SQL Estas funciones aceptan hasta dos instrucciones, lo que resulta útil cuando una solicitud debe recuperar los resultados de forma inmediata. Con MySQL, puedes hacer lo siguiente:

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 y createMySQLStatement no escapa ni cita las instrucciones creadas con la plantilla etiquetada con sql.

Recuperación de datos

El resultado de la SQL sentencia ejecutada está disponible en el controlador de respuestas del context.result objeto. El resultado es una JSON cadena con los elementos de respuesta de la ExecuteStatement acción. Por ejemplo, puede utilizar la siguiente forma:

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

Puede utilizar la toJsonObject utilidad para transformar el resultado en una lista de JSON objetos que representen las filas devueltas. Por ejemplo:

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] }

Tenga en cuenta que toJsonObject devuelve una matriz de resultados de la instrucción. Si proporcionó una instrucción, la longitud de la matriz es 1. Si proporcionó dos instrucciones, la longitud de la matriz es 2. Cada resultado de la matriz contiene 0 o más filas. toJsonObject devuelve null si el valor del resultado no es válido o no es esperado.

Funciones de utilidad

Puede utilizar los ayudantes de utilidades del AWS AppSync RDS módulo para interactuar con la base de datos.

La utilidad select crea una instrucción SELECT para consultar la base de datos relacional.

Uso básico

En su forma básica, puede especificar la tabla que desea consultar:

import { select, createPgStatement } from '@aws-appsync/utils/rds'; export function request(ctx) { // Generates statement: // "SELECT * FROM "persons" return createPgStatement(select({table: 'persons'})); }

Tenga en cuenta que también puede especificar el esquema en el identificador de la tabla:

import { select, createPgStatement } from '@aws-appsync/utils/rds'; export function request(ctx) { // Generates statement: // SELECT * FROM "private"."persons" return createPgStatement(select({table: 'private.persons'})); }

Especificación de columnas

Puede especificar columnas con la propiedad columns. Si no se establece en un valor, el valor predeterminado es *:

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

También puede especificar la tabla de una columna:

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

Límites y desplazamientos

Puede aplicar limit y offset a la consulta:

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 })); }

Ordenar por

Puede ordenar los resultados con la propiedad orderBy. Proporcione una matriz de objetos especificando la columna y una propiedad dir opcional:

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'}] })); }

Filtros

Puede crear filtros con el objeto de condición especial:

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'}} })); }

También puede combinar filtros:

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}} })); }

También puede crear instrucciones OR:

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 } } ]} })); }

También puede negar una condición 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 } } ]} })); }

También puede utilizar los siguientes operadores para comparar valores:

Operador Descripción Tipos de valor posibles
eq Igualdad número, cadena, booleano
Uno Desigualdad número, cadena, booleano
mentira Menor que o igual a número, cadena
lt Menor que número, cadena
edad Mayor que o igual a número, cadena
gt Mayor que número, cadena
contiene Como cadena
notContains No como cadena
beginsWith Empieza con un prefijo cadena
entre Entre dos valores número, cadena
attributeExists El atributo no es nulo número, cadena, booleano
size comprueba la longitud del elemento cadena

La utilidad insert ofrece una forma sencilla de insertar elementos de una sola fila en la base de datos con la operación INSERT.

Inserciones de un solo elemento

Para insertar un elemento, especifique la tabla y, a continuación, transfiera su objeto de valores. Las claves de objetos se asignan a las columnas de la tabla. Los nombres de las columnas se escapan automáticamente y los valores se envían a la base de datos mediante el mapa de variables:

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) }

Mi caso SQL de uso

Puede combinar un insert seguido de un select para recuperar la fila insertada:

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 de uso de Postgres

Con Postgres, puede usar returning para obtener datos de la fila que insertó. Acepta * o una matriz de nombres de columna:

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) }

La utilidad update le permite actualizar las filas existentes. Puede utilizar el objeto de condición para aplicar cambios a las columnas especificadas en todas las filas que cumplan la condición. Por ejemplo, supongamos que tenemos un esquema que nos permite realizar esta mutación. Queremos actualizar el name de Person con el valor id de 3, pero solo si los conocemos (known_since) desde el año 2000:

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

Nuestro solucionador de actualización tendrá este aspecto:

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) }

Podemos añadir una comprobación a nuestra condición para asegurarnos de que solo se actualice la fila en la que la clave principal 3 sea igual a id. Del mismo modo, en el caso de inserts de Postgres, se puede utilizar returning para devolver los datos modificados.

La utilidad remove le permite eliminar las filas existentes. Puede utilizar el objeto de condición en todas las filas que cumplan la condición. Tenga en cuenta que delete es una palabra clave reservada en JavaScript. removedebería usarse en su lugar:

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) }

Conversión

En algunos casos, es posible que desee más especificidad sobre el tipo de objeto correcto para usar en su instrucción. Puede utilizar las sugerencias de tipo proporcionadas para especificar el tipo de parámetros. AWS AppSync admite las mismas sugerencias de tipo que los datosAPI. Puede convertir sus parámetros utilizando las typeHint funciones del AWS AppSync rds módulo.

El siguiente ejemplo le permite enviar una matriz como un valor que se convierte en un JSON objeto. Usamos el -> operador para recuperar el elemento que se encuentra index 2 en la JSON matriz:

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 }

La conversión también resulta útil al manipular y comparar DATE, TIME y 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) }

Aquí se muestra otro ejemplo de cómo puede enviar la fecha y hora actuales:

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)}`) }

Sugerencias de tipos disponibles

  • typeHint.DATE: el parámetro correspondiente se envía como un objeto de tipo DATE a la base de datos. El formato aceptado es YYYY-MM-DD.

  • typeHint.DECIMAL: el parámetro correspondiente se envía como un objeto de tipo DECIMAL a la base de datos.

  • typeHint.JSON: el parámetro correspondiente se envía como un objeto de tipo JSON a la base de datos.

  • typeHint.TIME: el valor del parámetro de cadena correspondiente se envía como un objeto de tipo TIME a la base de datos. El formato aceptado es HH:MM:SS[.FFF].

  • typeHint.TIMESTAMP: el valor del parámetro de cadena correspondiente se envía como un objeto de tipo TIMESTAMP a la base de datos. El formato aceptado es YYYY-MM-DD HH:MM:SS[.FFF].

  • typeHint.UUID: el valor del parámetro de cadena correspondiente se envía como un objeto de tipo UUID a la base de datos.