DEV Community

loading...
Cover image for AWS AppSync: Retornando valores nullables em resolvers aninhados

AWS AppSync: Retornando valores nullables em resolvers aninhados

oieduardorabelo profile image Eduardo Rabelo ・3 min read

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

Discussion (0)

pic
Editor guide