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á.
nota
Agora, oferecemos suporte principalmente ao runtime do APPSYNC_JS e sua documentação. Considere usar o runtime do APPSYNC_JS e seus guias disponíveis aqui.
Você pode usar AWS AppSync funções e resolvedores para invocar funções do Lambda localizadas em sua conta. Você pode moldar suas cargas úteis de solicitação e a resposta de suas funções do Lambda antes de devolvê-las aos seus clientes. Você também pode usar modelos de mapeamento para dar dicas AWS AppSync sobre a natureza da operação a ser invocada. Esta seção descreve os diferentes modelos de mapeamento para as operações do Lambda compatíveis.
Modelo de mapeamento de solicitações
O modelo de mapeamento de solicitações do Lambda manipula campos relacionados à sua função do Lambda:
{
"version": string,
"operation": Invoke|BatchInvoke,
"payload": any type,
"invocationType": RequestResponse|Event
}
Esta é a representação do esquema JSON do modelo de mapeamento de solicitações do Lambda quando resolvido:
{
"definitions": {},
"$schema": "https://json-schema.org/draft-06/schema#",
"$id": "https://aws.amazon.com/appsync/request-mapping-template.json",
"type": "object",
"properties": {
"version": {
"$id": "/properties/version",
"type": "string",
"enum": [
"2018-05-29"
],
"title": "The Mapping template version.",
"default": "2018-05-29"
},
"operation": {
"$id": "/properties/operation",
"type": "string",
"enum": [
"Invoke",
"BatchInvoke"
],
"title": "The Mapping template operation.",
"description": "What operation to execute.",
"default": "Invoke"
},
"payload": {},
"invocationType": {
"$id": "/properties/invocationType",
"type": "string",
"enum": [
"RequestResponse",
"Event"
],
"title": "The Mapping template invocation type.",
"description": "What invocation type to execute.",
"default": "RequestResponse"
}
},
"required": [
"version",
"operation"
],
"additionalProperties": false
}
Aqui está um exemplo que usa uma operação invoke
com seus dados de carga útil sendo o campo getPost
de um esquema GraphQL junto com seus argumentos do contexto:
{
"version": "2018-05-29",
"operation": "Invoke",
"payload": {
"field": "getPost",
"arguments": $util.toJson($context.arguments)
}
}
Todo o documento de mapeamento é passado como entrada para sua função do Lambda; assim, o exemplo anterior agora tem esta aparência:
{
"version": "2018-05-29",
"operation": "Invoke",
"payload": {
"field": "getPost",
"arguments": {
"id": "postId1"
}
}
}
Versão
Comum a todos os modelos de mapeamento de solicitação, version
define a versão usada pelo modelo. O version
é obrigatório e é um valor estático:
"version": "2018-05-29"
Operação
A fonte de dados do Lambda permite que você defina duas operações no campo operation
: Invoke
e BatchInvoke
. A Invoke
operação permite AWS AppSync que você chame sua função Lambda para cada resolvedor de campo do GraphQL. BatchInvoke
instrui as solicitações em lote AWS AppSync para o campo GraphQL atual. O campo operation
é obrigatório.
Para Invoke
, o modelo de mapeamento da solicitação resolvido corresponde à carga útil de entrada da função do Lambda. Vamos modificar o exemplo acima:
{
"version": "2018-05-29",
"operation": "Invoke",
"payload": {
"arguments": $util.toJson($context.arguments)
}
}
Isso é resolvido e passado para a função do Lambda, que poderá ser mais ou menos assim:
{
"version": "2018-05-29",
"operation": "Invoke",
"payload": {
"arguments": {
"id": "postId1"
}
}
}
Para BatchInvoke
, o modelo de mapeamento é aplicado a cada resolvedor do campo no lote. Para ser conciso, AWS AppSync mescla todos os payload
valores do modelo de mapeamento resolvido em uma lista sob um único objeto correspondente ao modelo de mapeamento. O exemplo de modelo a seguir mostra a mesclagem:
{
"version": "2018-05-29",
"operation": "BatchInvoke",
"payload": $util.toJson($context)
}
Esse modelo é resolvido para o seguinte documento de mapeamento:
{
"version": "2018-05-29",
"operation": "BatchInvoke",
"payload": [
{...}, // context for batch item 1
{...}, // context for batch item 2
{...} // context for batch item 3
]
}
Cada elemento da lista payload
corresponde a um único item de lote. Também se espera que a função do Lambda retorne uma resposta em forma de lista correspondente à ordem dos itens enviados na solicitação:
[
{ "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 1
{ "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 2
{ "data": {...}, "errorMessage": null, "errorType": null } // result for batch item 3
]
Carga útil
O campo payload
é um contêiner usado para passar qualquer JSON bem formado para a função do Lambda. Se o operation
campo estiver definido comoBatchInvoke
, AWS AppSync agrupa os payload
valores existentes em uma lista. O campo payload
é opcional.
Tipo de invocação
A fonte de dados do Lambda permite que você defina dois tipos de invocação: RequestResponse
e Event
. Os tipos de invocação são sinônimos dos tipos de invocação definidos na API do Lambda. O tipo de RequestResponse
invocação permite AWS AppSync chamar sua função Lambda de forma síncrona para aguardar uma resposta. A invocação Event
permite que você invoque sua função do Lambda de forma assíncrona. Para obter mais informações sobre como o Lambda lida com solicitações de tipo de invocação Event
, consulte Invocação assíncrona. O campo invocationType
é opcional. Se esse campo não for incluído na solicitação, o padrão AWS AppSync será o tipo de RequestResponse
invocação.
Para qualquer campo invocationType
, a solicitação resolvida corresponde à carga útil de entrada da função do Lambda. Vamos modificar o exemplo acima:
{
"version": "2018-05-29",
"operation": "Invoke",
"invocationType": "Event"
"payload": {
"arguments": $util.toJson($context.arguments)
}
}
Isso é resolvido e passado para a função do Lambda, que poderá ser mais ou menos assim:
{
"version": "2018-05-29",
"operation": "Invoke",
"invocationType": "Event",
"payload": {
"arguments": {
"id": "postId1"
}
}
}
Quando a BatchInvoke
operação é usada em conjunto com o campo do tipo de Event
invocação, AWS AppSync mescla o resolvedor de campo da mesma forma mencionada acima, e a solicitação é passada para sua função Lambda como um evento assíncrono, sendo uma lista de valores. payload
Recomendamos que você desative o cache do resolvedor para resolvedores do tipo de invocação Event
, pois eles não seriam enviados ao Lambda se houvesse um acerto do cache.
Modelo de mapeamento de respostas
Assim como em outras fontes de dados, sua função Lambda envia uma resposta AWS AppSync que deve ser convertida em um tipo GraphQL.
O resultado da função do Lambda será definido no objeto context
que está disponível por meio da propriedade $context.result
do Velocity Template Language (VTL).
Se a forma da resposta da função do Lambda corresponder exatamente à forma do tipo do GraphQL, você pode encaminhar a resposta usando o seguinte modelo de mapeamento da resposta:
$util.toJson($context.result)
Não existem campos obrigatórios ou restrições de forma que se aplicam ao modelo de mapeamento da resposta. No entanto, como o GraphQL tem vários tipos, o modelo de mapeamento resolvido deve corresponder ao tipo do GraphQL esperado.
Resposta em lote da função do Lambda
Se o campo operation
estiver definido como BatchInvoke
, o AWS AppSync espera de volta uma lista de itens da função do Lambda. Para AWS AppSync mapear cada resultado de volta ao item da solicitação original, a lista de respostas deve corresponder em tamanho e ordem. É válido ter itens null
na lista de respostas; $ctx.result
será adequadamente definido como nulo.
Resolvedores diretos do Lambda
Se você quiser contornar totalmente o uso de modelos de mapeamento, AWS AppSync pode fornecer uma carga padrão para sua função Lambda e uma resposta padrão da função Lambda para um tipo GraphQL. Você pode optar por fornecer um modelo de solicitação, um modelo de resposta ou nenhum dos dois e AWS AppSync tratá-los adequadamente.
Modelo de mapeamento da solicitação direta do Lambda
Quando o modelo de mapeamento da solicitação não for fornecido, AWS AppSync enviará o Context
objeto diretamente para sua função Lambda como uma Invoke
operação. Para obter mais informações sobre a estrutura do código-fonte do objeto Context
, consulte AWS AppSync referência de contexto do modelo de mapeamento do resolvedor.
Modelo de mapeamento da resposta direta do Lambda
Quando o modelo de mapeamento de resposta não é fornecido, AWS AppSync faz uma das duas coisas ao receber a resposta da função Lambda. Se você não forneceu um modelo de mapeamento de solicitação ou forneceu um modelo de mapeamento de solicitação com a versão 2018-05-29
, a resposta será equivalente ao seguinte modelo de mapeamento de resposta:
#if($ctx.error)
$util.error($ctx.error.message, $ctx.error.type, $ctx.result)
#end
$util.toJson($ctx.result)
Se você forneceu um modelo com a versão 2017-02-28
, a lógica de resposta funcionará de forma equivalente ao seguinte modelo de mapeamento de resposta:
$util.toJson($ctx.result)
Superficialmente, o desvio do modelo de mapeamento opera de forma semelhante ao uso de determinados modelos de mapeamento, conforme mostrado nos exemplos anteriores. No entanto, nos bastidores, a avaliação dos modelos de mapeamento é totalmente contornada. Como a etapa de avaliação do modelo é ignorada, em alguns cenários, as aplicações podem ter menos sobrecarga e latência durante a resposta em relação a uma função do Lambda com um modelo de mapeamento de resposta que precisa ser avaliado.
Tratamento personalizado de erros nas respostas do resolvedor direto do Lambda
Você pode personalizar as respostas de erro das funções do Lambda que os resolvedores diretos do Lambda invocam gerando uma exceção personalizada. O exemplo a seguir demonstra como criar uma exceção personalizada usando JavaScript:
class CustomException extends Error {
constructor(message) {
super(message);
this.name = "CustomException";
}
}
throw new CustomException("Custom message");
Quando exceções são geradas, errorType
e errorMessage
é name
emessage
, respectivamente, do erro personalizado que é gerado.
Se errorType
estiverUnauthorizedException
, AWS AppSync retorna a mensagem padrão ("You are not authorized to make this
call."
) em vez de uma mensagem personalizada.
Este é um exemplo de resposta do GraphQL que demonstra um errorType
personalizado:
{
"data": {
"query": null
},
"errors": [
{
"path": [
"query"
],
"data": null,
"errorType": "CustomException",
"errorInfo": null,
"locations": [
{
"line": 5,
"column": 10,
"sourceName": null
}
],
"message": "Custom Message"
}
]
}
Resolvedores diretos do Lambda: agrupamento em lotes ativado
Você pode habilitar o agrupamento em lotes para seu resolvedor direto do Lambda configurando maxBatchSize
no seu resolvedor. Quando maxBatchSize
é definido com um valor maior do que 0
para um resolvedor do Direct Lambda, AWS AppSync envia solicitações em lotes para sua função Lambda em tamanhos de até. maxBatchSize
Definir maxBatchSize
como 0
em um resolvedor direto do Lambda desativa o agrupamento em lotes.
Para obter mais informações sobre como funciona o agrupamento em lotes com os resolvedores do Lambda, consulte Caso de uso avançado: agrupamento em lotes.
Modelo de mapeamento de solicitações
Quando o agrupamento em lotes está ativado e o modelo de mapeamento da solicitação não é fornecido, AWS AppSync envia uma lista de Context
objetos como uma BatchInvoke
operação diretamente para sua função Lambda.
Modelo de mapeamento de respostas
Quando o agrupamento em lote está ativado e o modelo de mapeamento de resposta não é fornecido, a lógica de resposta é equivalente ao seguinte modelo de mapeamento de resposta:
#if( $context.result && $context.result.errorMessage )
$utils.error($context.result.errorMessage, $context.result.errorType,
$context.result.data)
#else
$utils.toJson($context.result.data)
#end
A função do Lambda deve retornar uma lista de resultados na mesma ordem da lista de objetos Context
que foram enviados. É possível retornar erros individuais fornecendo errorMessage
e errorType
para um resultado específico. Cada resultado na lista deve estar no seguinte formato:
{
"data" : { ... }, // your data
"errorMessage" : { ... }, // optional, if included an error entry is added to the "errors" object in the AppSync response
"errorType" : { ... } // optional, the error type
}
nota
Outros campos no objeto de resultado são ignorados.
Manuseio de erros do Lambda
Você pode retornar um erro para todos os resultados lançando uma exceção ou um erro na sua função do Lambda. Se a solicitação de payload ou o tamanho da resposta para sua solicitação em lote for muito grande, o Lambda retornará um erro. Nesse caso, você deve considerar reduzir maxBatchSize
ou o tamanho do payload da resposta.
Para obter informações sobre como lidar com erros individuais, consulte Retornar erros individuais.
Amostra de função do Lambda
Usando o esquema abaixo, você pode criar um resolvedor direto do Lambda para o resolvedor de campo Post.relatedPosts
e habilitar o agrupamento em lote definindo maxBatchSize
acima de 0
:
schema {
query: Query
mutation: Mutation
}
type Query {
getPost(id:ID!): Post
allPosts: [Post]
}
type Mutation {
addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!
}
type Post {
id: ID!
author: String!
title: String
content: String
url: String
ups: Int
downs: Int
relatedPosts: [Post]
}
Na consulta a seguir, a função do Lambda será chamada com lotes de solicitações para resolver relatedPosts
:
query getAllPosts {
allPosts {
id
relatedPosts {
id
}
}
}
Confira abaixo uma implementação simples de uma função do Lambda:
const posts = {
1: {
id: '1',
title: 'First book',
author: 'Author1',
url: 'https://amazon.com/',
content:
'SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1',
ups: '100',
downs: '10',
},
2: {
id: '2',
title: 'Second book',
author: 'Author2',
url: 'https://amazon.com',
content: 'SAMPLE TEXT AUTHOR 2 SAMPLE TEXT AUTHOR 2 SAMPLE TEXT',
ups: '100',
downs: '10',
},
3: { id: '3', title: 'Third book', author: 'Author3', url: null, content: null, ups: null, downs: null },
4: {
id: '4',
title: 'Fourth book',
author: 'Author4',
url: 'https://www.amazon.com/',
content:
'SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4',
ups: '1000',
downs: '0',
},
5: {
id: '5',
title: 'Fifth book',
author: 'Author5',
url: 'https://www.amazon.com/',
content: 'SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT',
ups: '50',
downs: '0',
},
}
const relatedPosts = {
1: [posts['4']],
2: [posts['3'], posts['5']],
3: [posts['2'], posts['1']],
4: [posts['2'], posts['1']],
5: [],
}
exports.handler = async (event) => {
console.log('event ->', event)
// retrieve the ID of each post
const ids = event.map((context) => context.source.id)
// fetch the related posts for each post id
const related = ids.map((id) => relatedPosts[id])
// return the related posts; or an error if none were found
return related.map((r) => {
if (r.length > 0) {
return { data: r }
} else {
return { data: null, errorMessage: 'Not found', errorType: 'ERROR' }
}
})
}