Combinación de solucionadores de GraphQL en AWS AppSync - AWS AppSync GraphQL

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.

Combinación de solucionadores de GraphQL en AWS AppSync

nota

Ahora admitimos de forma básica el tiempo de ejecución APPSYNC_JS y su documentación. Considere la opción de utilizar el tiempo de ejecución APPSYNC_JS y sus guías aquí.

Los solucionadores y los campos de un esquema de GraphQL mantienen una relación 1:1 con un alto grado de flexibilidad. Puesto que se configura un origen de datos para cada solucionador independientemente de un esquema, tiene la posibilidad de resolver o manipular los tipos de GraphQL mediante orígenes de datos diferentes, combinándolos en el esquema que mejor se adapte a sus necesidades.

Los siguientes escenarios de ejemplo muestran cómo mezclar y hacer corresponder los orígenes de datos en su esquema. Antes de empezar, le recomendamos que esté familiarizado con la configuración de orígenes de datos y solucionadores para AWS Lambda Amazon DynamoDB y Amazon OpenSearch Service, tal y como se describe en los tutoriales anteriores.

Esquema de ejemplo

El siguiente esquema tiene un tipo Post con 3 operaciones Query y 3 operaciones Mutation definidas:

type Post { id: ID! author: String! title: String content: String url: String ups: Int downs: Int version: Int! } type Query { allPost: [Post] getPost(id: ID!): Post searchPosts: [Post] } type Mutation { addPost( id: ID!, author: String!, title: String, content: String, url: String ): Post updatePost( id: ID!, author: String!, title: String, content: String, url: String, ups: Int!, downs: Int!, expectedVersion: Int! ): Post deletePost(id: ID!): Post }

En este ejemplo tendría que asociar un total de 6 solucionadores. Una opción sería hacer que todas procedieran de una tabla de Amazon DynamoDB, denominada Posts, donde AllPosts ejecuta un análisis y searchPosts ejecuta una consulta, tal y como se describe en DynamoDB Resolver Mapping Template Reference. No obstante, existen alternativas para satisfacer las necesidades de su empresa, como hacer que estas consultas de GraphQL se resuelvan desde Lambda u OpenSearch Service.

Modificación de datos mediante solucionadores

Puede que sea necesario enviar a los clientes resultados de una base de datos como DynamoDB (o Amazon Aurora) con algunos de los atributos modificados. Esto puede deberse al formato de los tipos de datos, por ejemplo diferencias de marcas de tiempo en los clientes, o para gestionar problemas de compatibilidad con versiones anteriores. A título ilustrativo, en el siguiente ejemplo mostramos una función AWS Lambda que manipula las votaciones a favor y en contra de las publicaciones del blog asignándoles números aleatorios cada vez que se invoca el solucionador de GraphQL:

'use strict'; const doc = require('dynamodb-doc'); const dynamo = new doc.DynamoDB(); exports.handler = (event, context, callback) => { const payload = { TableName: 'Posts', Limit: 50, Select: 'ALL_ATTRIBUTES', }; dynamo.scan(payload, (err, data) => { const result = { data: data.Items.map(item =>{ item.ups = parseInt(Math.random() * (50 - 10) + 10, 10); item.downs = parseInt(Math.random() * (20 - 0) + 0, 10); return item; }) }; callback(err, result.data); }); };

Se trata de una función de Lambda perfectamente válida y puede asociarse al campo AllPosts del esquema de GraphQL para que cualquier consulta que devuelva todos los resultados obtenga números aleatorios para los votos a favor y en contra.

DynamoDB y OpenSearch Service

En algunas aplicaciones, puede realizar mutaciones o consultas de búsqueda sencilla en DynamoDB y tener un proceso en segundo plano para transferir documentos a OpenSearch Service. Luego, podría simplemente asociar el solucionador searchPosts al origen de datos de OpenSearch Service y devolver los resultados de la búsqueda (a partir de los datos originados en DynamoDB) mediante una consulta de GraphQL. Esto puede ser extremadamente útil al añadir operaciones de búsqueda avanzada a sus aplicaciones, como palabras clave, coincidencias parciales o incluso búsquedas geoespaciales. La transferencia de datos desde DynamoDB puede realizarse mediante un proceso ETL o, alternativamente, puede transmitir desde DynamoDB mediante Lambda. Puede lanzar un ejemplo completo con la siguiente pila de AWS CloudFormation en la región EE. UU. Oeste 2 (Oregón) en su cuenta de AWS:

Blue button labeled "Launch Stack" with an arrow icon indicating an action to start.

El esquema de este ejemplo le permite añadir publicaciones mediante un solucionador de DynamoDB, de este modo:

mutation add { putPost(author:"Nadia" title:"My first post" content:"This is some test content" url:"https://aws.amazon.com/appsync/" ){ id title } }

Esto escribe los datos en DynamoDB, que los transmite a través de Lambda a Amazon OpenSearch Service, donde puede buscar todas las publicaciones por diferentes campos. Por ejemplo, como los datos se encuentran en Amazon OpenSearch Service, puede buscar los campos de autor o contenido con texto libre, incluso con espacios, del siguiente modo:

query searchName{ searchAuthor(name:" Nadia "){ id title content } } query searchContent{ searchContent(text:"test"){ id title content } }

Como los datos se escriben directamente en DynamoDB, aún puede realizar operaciones eficientes de búsqueda de lista o de elemento en la tabla con las consultas allPosts{...} y singlePost{...}. Esta pila utiliza el siguiente código de ejemplo para los flujos de DynamoDB:

Nota: este código es solo un ejemplo.

var AWS = require('aws-sdk'); var path = require('path'); var stream = require('stream'); var esDomain = { endpoint: 'https://opensearch-domain-name.REGION.es.amazonaws.com', region: 'REGION', index: 'id', doctype: 'post' }; var endpoint = new AWS.Endpoint(esDomain.endpoint) var creds = new AWS.EnvironmentCredentials('AWS'); function postDocumentToES(doc, context) { var req = new AWS.HttpRequest(endpoint); req.method = 'POST'; req.path = '/_bulk'; req.region = esDomain.region; req.body = doc; req.headers['presigned-expires'] = false; req.headers['Host'] = endpoint.host; // Sign the request (Sigv4) var signer = new AWS.Signers.V4(req, 'es'); signer.addAuthorization(creds, new Date()); // Post document to ES var send = new AWS.NodeHttpClient(); send.handleRequest(req, null, function (httpResp) { var body = ''; httpResp.on('data', function (chunk) { body += chunk; }); httpResp.on('end', function (chunk) { console.log('Successful', body); context.succeed(); }); }, function (err) { console.log('Error: ' + err); context.fail(); }); } exports.handler = (event, context, callback) => { console.log("event => " + JSON.stringify(event)); var posts = ''; for (var i = 0; i < event.Records.length; i++) { var eventName = event.Records[i].eventName; var actionType = ''; var image; var noDoc = false; switch (eventName) { case 'INSERT': actionType = 'create'; image = event.Records[i].dynamodb.NewImage; break; case 'MODIFY': actionType = 'update'; image = event.Records[i].dynamodb.NewImage; break; case 'REMOVE': actionType = 'delete'; image = event.Records[i].dynamodb.OldImage; noDoc = true; break; } if (typeof image !== "undefined") { var postData = {}; for (var key in image) { if (image.hasOwnProperty(key)) { if (key === 'postId') { postData['id'] = image[key].S; } else { var val = image[key]; if (val.hasOwnProperty('S')) { postData[key] = val.S; } else if (val.hasOwnProperty('N')) { postData[key] = val.N; } } } } var action = {}; action[actionType] = {}; action[actionType]._index = 'id'; action[actionType]._type = 'post'; action[actionType]._id = postData['id']; posts += [ JSON.stringify(action), ].concat(noDoc?[]:[JSON.stringify(postData)]).join('\n') + '\n'; } } console.log('posts:',posts); postDocumentToES(posts, context); };

Puede utilizar flujos de DynamoDB para asociarlo a una tabla de DynamoDB con la clave principal id, y cualquier cambio en el origen de DynamoDB se transmitirá al dominio de OpenSearch Service. Para obtener más información sobre cómo configurarlo, consulte la documentación de flujos de DynamoDB.