Enquanto trabalhava em um projeto de um cliente, encontrei um problema interessante com o AppSync, que não consegui encontrar uma resposta depois de pesquisar bastante. Espero que este artigo possa te poupar a mesma dor, caso você encontre o mesmo problema.
O problema é que, quando você tem um campo aninhado anulável, e que você deseja expandir seu tipo, precisamos manipular os valores nulos no modelo VTL e ignorá-los. Não era óbvio como fazer isso em um sistema gerenciado como o AppSync.
Para ter uma idéia melhor do que estou falando, aqui está uma versão drasticamente simplificada do esquema GraphQL.
type University {
name: String!
categories: [Category!]
}
type Category {
name: String!
sports: [CategorySport!]
}
type CategorySport {
name: String!
description: String
coach: Coach # in the DynamoDB table, this is stored as a String
}
type Coach {
id: ID!
firstName: String!
lastName: String!
}
Na tabela DynamoDB, as universidades são armazenadas na tabela University
e os usuários na tabela User
. Categorias e esportes são modelados como propriedades de uma universidade para minimizar o número de leituras no DynamoDB. E o campo CategorySport.coach
é o ID do perfil de um usuário na tabela User
.
Para tornar mais fácil para a interface do usuário consumir os dados, expandimos o campo CategorySport.coach
para ser um tipo Coach
completo.
Então, configurei o resolver para esse campo aninhado e apontei para a tabela User
.
Nota: Estou usando Serverless Framework com o excelente plugin serverless-appsync para me ajudar a configurar tudo isso.
mappingTemplates:
- type: CategorySport
field: coach
dataSource: userTable
dataSources:
- type: AMAZON_DYNAMODB
name: userTable
config:
tableName: !Ref UserTable
E eu configurei os modelos de VTL para a solicitação e resposta.
Solicitação:
{
"version" : "2017-02-28",
"operation" : "GetItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($context.source.coach)
}
}
Resposta:
$util.toJson($context.result)
E tudo funciona muito bem, exceto quando CategorySport.coach
é null
.
O que eu precisava era de uma maneira de fazer um curto-circuito na solicitação DynamoDB.GetItem
quando CategorySport.coach
for null
. Depois de muita pesquisa, meu googling não deu em nada e eu me virei para o meu bom amigo Heitor Lessa. Ele me indicou este útil artigo, que mencionava a palavra-chave #return
que permite fazer um curto-circuito na execução do resolver e retornar mais cedo.
O uso de #return no modelo de mapeamento de uma função retornará esses dados da função. Se você usá-lo em um modelo de mapeamento de solicitação, o modelo de mapeamento de resposta será ignorado. Da mesma forma, o uso de #return no modelo de mapeamento de um resolver retornará esses dados do resolver, encerrando prematuramente a execução do resolver.
Com isso, pude solucionar o problema adicionando apenas 3 linhas de código ao meu modelo de solicitação.
#if ($util.isNullOrEmpty($context.source.coach))
#return
#end
{
"version" : "2017-02-28",
"operation" : "GetItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($context.source.coach)
}
}
Uma coisa a observar é que você não pode ter #return(null)
mas #return
seria null
como resultado do resolver e pula a operação do DynamoDB.GetItem
e o modelo de resposta por completo.
Gostou deste artigo? Apoie-me no Patreon e obtenha ajuda direta de mim por meio de um canal privado do Slack ou por 1-2-1.
Créditos
- AppSync: skipping nullable nested resolvers by returning early, escrito originalmente por Yan Cui
Top comments (0)