AWS AppSync JavaScript referência da função de resolução para Amazon RDS - AWS AppSync

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

AWS AppSync JavaScript referência da função de resolução para Amazon RDS

A AWS AppSync RDS função e o resolvedor permitem que os desenvolvedores enviem SQL consulta um banco de dados de cluster do Amazon Aurora usando RDS os API dados e recupera o resultado dessas consultas. Você pode escrever SQL declarações que são enviadas aos Dados API usando o modelo sql marcado com o rds módulo AWS AppSync do ou usando as funções remove auxiliaresselect, insertupdate, e do rds módulo. AWS AppSync utiliza a ExecuteStatementação do Serviço de RDS Dados para executar SQL instruções no banco de dados.

SQLmodelo marcado

AWS AppSync O modelo sql marcado permite que você crie uma declaração estática que pode receber valores dinâmicos em tempo de execução usando expressões de modelo. AWS AppSync cria um mapa variável a partir dos valores da expressão para criar uma SqlParameterizedconsulta que é enviada aos dados sem servidor do Amazon Aurora. API Com esse método, não é possível que valores dinâmicos transmitidos em runtime modifiquem a declaração original, o que pode causar uma execução não intencional. Todos os valores dinâmicos são transmitidos como parâmetros, não podem modificar a declaração original e não são executados pelo banco de dados. Isso torna sua consulta menos vulnerável a SQL ataques de injeção.

nota

Em todos os casos, ao escrever SQL declarações, você deve seguir as diretrizes de segurança para lidar adequadamente com os dados que você recebe como entrada.

nota

O modelo marcado com sql só aceita a transmissão de valores de variáveis. Não é possível usar uma expressão para especificar dinamicamente nomes de colunas ou de tabelas. No entanto, é possível usar funções de utilitário para criar declarações dinâmicas.

No exemplo a seguir, criamos uma consulta que filtra com base no valor do argumento col definido dinamicamente na consulta do GraphQL em runtime. O valor só pode ser adicionado à declaração usando a expressão de 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); }

Ao transmitir todos os valores dinâmicos pelo mapa de variáveis, contamos com o mecanismo de banco de dados para processar e higienizar os valores com segurança.

Criar declarações

Funções e resolvedores podem interagir com os bancos de dados My SQL e PostgreSQL. Use createMySQLStatement e createPgStatement, respectivamente, para criar declarações. Por exemplo, createMySQLStatement pode criar uma Minha SQL consulta. Essas funções aceitam até duas declarações, o que é útil quando uma solicitação deve recuperar os resultados imediatamente. Com o MySQL, você pode fazer:

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 não inserem caracteres de escape nem citam declarações criadas com o modelo marcado com sql.

Recuperação de dados

O resultado da SQL instrução executada está disponível em seu manipulador de respostas no context.result objeto. O resultado é uma JSON string com os elementos de resposta da ExecuteStatement ação. Quando analisado, o resultado tem o seguinte formato:

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

Você pode usar o toJsonObject utilitário para transformar o resultado em uma lista de JSON objetos representando as linhas retornadas. Por exemplo:

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

Observe que o toJsonObject exibe uma matriz de resultados das declarações. Se você forneceu uma declaração, o tamanho da matriz será 1. Se você forneceu duas declarações, o tamanho da matriz será 2. Cada resultado na matriz contém 0 ou mais linhas. toJsonObject exibirá null se o valor do resultado for inválido ou inesperado.

Funções do utilitário

Você pode usar os auxiliares utilitários do AWS AppSync RDS módulo para interagir com seu banco de dados.

O utilitário select cria uma declaração SELECT para consultar o banco de dados relacional.

Uso básico

Na forma básica, é possível especificar a tabela que deseja consultar:

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

Observe também que é possível especificar o esquema no identificador da tabela:

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

Especificar colunas

É possível especificar colunas com a propriedade columns. Se isso não for definido como um valor, o padrão será *:

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

Também é possível especificar a tabela de uma coluna:

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

Limites e deslocamentos:

É possível aplicar limit e offset à 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

É possível classificar os resultados com a propriedade orderBy. Forneça uma matriz de objetos especificando a coluna e uma propriedade 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

É possível criar filtros usando o objeto de condição 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'}} })); }

Também é possível 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}} })); }

Também é possível criar declarações 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 } } ]} })); }

Também é possível negar uma condição com 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 } } ]} })); }

Também é possível usar os seguintes operadores para comparar valores:

Operador Descrição Tipos de valores possíveis
eq Equal número, string, booleano
um Not equal número, string, booleano
le Menor ou igual a número, seqüência
lt Menor que número, seqüência
idade Maior ou igual a número, seqüência
gt Maior que número, seqüência
contém Como string
notContains Não é como string
beginsWith Começa com o prefixo string
entre Entre dois valores número, seqüência
attributeExists O atributo não é nulo número, string, booleano
tamanho verifica o comprimento do elemento string

O utilitário insert oferece uma maneira simples de inserir itens de linha única no banco de dados com a operação INSERT.

Inserções de item único

Para inserir um item, especifique a tabela e, depois, transmita o objeto de valores. As chaves do objeto são associadas às colunas da tabela. São inseridos automaticamente caracteres de escape nos nomes das colunas e os valores são enviados ao banco de dados usando o mapa de variáveis:

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

Meu caso SQL de uso

É possível combinar um insert seguido por um select para recuperar a linha inserida:

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 do Postgres

Com o Postgres, é possível usar returning para obter dados da linha que você inseriu. Ele aceita * ou uma matriz de nomes de colunas:

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

O utilitário update permite atualizar as linhas existentes. É possível usar o objeto de condição para aplicar alterações às colunas especificadas em todas as linhas que atendam à condição. Por exemplo, digamos que temos um esquema que nos permita fazer essa mutação. Queremos atualizar o name de Person com o valor id de 3, mas somente se os conhecermos (known_since) desde o ano 2000:

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

Nosso resolvedor de atualização é semelhante a:

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 adicionar uma verificação à nossa condição para garantir que somente a linha que tem a chave primária id igual a 3 seja atualizada. Da mesma forma, para Postgres inserts, é possível usar returning para exibir os dados modificados.

O utilitário remove permite excluir as linhas existentes. É possível usar o objeto de condição em todas as linhas que atendam à condição. Observe que delete é uma palavra-chave reservada em JavaScript. removedeve ser usado em vez disso:

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

Conversão

Em alguns casos, convém ter maior especificidade sobre o tipo de objeto correto a ser usado na declaração. Você pode usar as dicas de tipo fornecidas para especificar o tipo dos seus parâmetros. AWS AppSync suporta o mesmo tipo de dicas que o DataAPI. Você pode converter seus parâmetros usando as typeHint funções do AWS AppSync rds módulo.

O exemplo a seguir permite que você envie uma matriz como um valor que é convertido como um JSON objeto. Usamos o -> operador para recuperar o elemento index 2 na 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 }

A conversão também é útil ao processar e comparar DATE, TIME e 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) }

Veja outro exemplo de como enviar a data e a hora atuais:

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

Dicas de tipo disponíveis

  • typeHint.DATE: o parâmetro correspondente é enviado como objeto do tipo DATE ao banco de dados. O formato aceito é YYYY-MM-DD.

  • typeHint.DECIMAL: o parâmetro correspondente é enviado como objeto do tipo DECIMAL ao banco de dados.

  • typeHint.JSON: o parâmetro correspondente é enviado como objeto do tipo JSON ao banco de dados.

  • typeHint.TIME: o valor de parâmetro de string correspondente é enviado como objeto do tipo TIME ao banco de dados. O formato aceito é HH:MM:SS[.FFF].

  • typeHint.TIMESTAMP: o valor de parâmetro de string correspondente é enviado como objeto do tipo TIMESTAMP ao banco de dados. O formato aceito é YYYY-MM-DD HH:MM:SS[.FFF].

  • typeHint.UUID: o valor de parâmetro de string correspondente é enviado como objeto do tipo UUID ao banco de dados.