Go, Graphql e Schemas dinâmicos
Já não é novidade que a GraphQL é uma tecnologia quente que vem ajudando muitas empresas no mercado atualmente. Buscando entender quais benefícios a RD teria em adotar essa tecnologia, Raphael Jansen fez uma apresentação no #3 go meetup em Joinvile sobre um estudo de caso de uso da GraphQL em um dos produtos da RD a CDP utilizando Go como linguagem.
Para entender como isso tudo funciona veja a apresentação abaixo sobre este tema explorando o um caso de uso na RD.
Na apresentação falamos sobre como a GraphQL funciona, agora vamos descrever o é a que Graphql e entender melhor a sua estrutura e principais características analisando o caso de uso de testes que fizemos para a CDP.
O que é a Graphql?
A GraphQL é uma linguagem de consulta criada pelo Facebook que visa descrever as operações de leitura (Queries) e de escrita (Mutations) separadamente. Sobre linguagem de consulta, podemos fazer uma comparação com o nosso amigo SQL que define uma linguagem para acesso ao banco porém diferente do SQL, a GraphQL visa em criar uma linguagem para acesso WEB facilitando a camada de transporte e focando em dar o máximo de desempenho aos clientes que a consultam.
Estrutura e características
A GraphQL utiliza como base um schema onde temos diversos componentes como descrevemos na imagem abaixo:
Schema
Responsável por descrever todos os types, queries, mutations e subscritions. Graças ao schema conseguimos realizar uma validação fortemente tipada em cada request recebido em nossa API.
Outro ponto importante é que ele permite queries de introspecção que permitem entender quais são os tipos de cada entidade descrita no schema da GraphQL.
Exemplo de um schema:
"""The `JSONType` scalar type represents an dynamic object."""
scalar JSONtype Project {
name: String
tagline: String
contributors: [User]
}type User {
id: ID
name: String
}type Query {
user(id: ID!): User
users(limit: Int!, filter: JSON, order: JSON): [User!]
project(id: ID!): Project
}type Mutation {
create_user(user: User!): User
create_project(Project: Project!): Project
}
Type
Estrutura dos dados da schema (sistema de tipos)
- Interface — Criar abstração de dados, atributos
- Type — Dados de saída do schema
- Input — Dados de entrada do schema
- Union — União de tipos
- Scalar — Tipos primitivos dos dados
Exemplo:
"""The `JSONType` scalar type represents an dynamic object."""
scalar JSONtype Project {
name: String
tagline: String
contributors: [JSON]
}
Query
Descreve como a leitura de dados é feita. Além disso, permite realizar a consultar mais de uma entidade por query.
Exemplo:
{
user(id: 1234) {
name
}
project(id: 2) {
id
name
contributors {
name
}
}
}
O resultado dessa querie seria:
{
"data": {
"user": {
"name": "Lala"
},
"project": {
"id": 2,
"name": "Project XPTO",
"contributors": [
"user": {
"name": "Lala"
},
"user": {
"name": "Lele"
}
]
}
}
}
Mutation
Descreve como são feitas as operações de escrita, update e delete.
{
create_user(user: {
id: 1234
name: "Lele"
}) {
name
}
}
O resultado dessa mutation seria:
{
"data": {
"user": {
"name": "Lele",
}
}
}
Subscription
Funciona como uma Query, descrevendo como a leitura de dados é feita, mas permite que clientes da GraphQL se registrem e recebam atualizações de uma query via websocket seguindo um modelo de stream de dados real time (aka: Relay).
Características:
- Define formato de dados
- Hierárquica
- Fortemente tipada
- Introspectiva
- Version free
- Clientes em diversas linguagens https://graphql.org/code/
- Ecossistema forte
- Documentação da API
- Performance do front-end / clientes
- Abstração de serviços
Abaixo temos um modelo de exemplo de uma arquitetura utilizando a GraphQL como camada de transporte:
A neste exemplo conseguimos entender que a GraphQL é uma camada de transporte onde modelamos como os dados devem ser lidos e escritos em diversos sistemas. Essa operação onde buscamos os dados são chamadas de resolver.
O resolver nada mais é do que uma função responsável por carregar e transformar os dados fornecidos nos tipos definidos na schema.
CDP e Schemas dinâmicos
CDP (Customer Data Platform) é um projeto vai levar o RD Station para um novo patamar e possibilitar que novas funcionalidades sejam construídas, assim como novos recursos. Este projeto vem para ser a fonte da verdade sobre o consumidor para todas as áreas da empresa.
Para entender mais sobre a CDP sugerimos a leitura do artigo “O que é CDP e por que essa tecnologia deve transformar o RD Station”.
Agora vamos entender os desafios desse projeto e porque a GraphQL pode ser um caso de uso muito interessante para a CDP.
O Problema:
- Schemas diferentes para cada cliente
- Base de dados relacional, Open Schema/EAV
- Metadados e sistemas de tipos já existentes
- Graphql e Golang são fortemente tipadas
Objetivo:
- Possibilitar uma camada de comunicação padronizada para todos os nossos clientes (externos/internos)
- Backend de APIs automático
- Reuso de ferramentas
- Múltiplos Tenants (Schema único por cliente)
- Facilitar a prototipação
Com isso chegamos ao seguinte arquitetura:
Neste caso construímos uma schema baseado no tenant-id de cada cliente possibilitando alternar entre schemas no mesmo serviço. Hoje a CDP tem toda essa inteligência para prover entidades ricas com base em cada cliente do RDSM. Junto a isso, acabamos nos baseando em uma outra implementação de GraphQL o Prisma para servir uma interface rica de consulta para os nossos clientes.
Para construir essa ferramenta acabamos utilizando o Go como linguagem de programação para este serviço utilizando dois projetos para construir toda a graphql que são eles:
CDP + Graphql para atender um ecommerce simples
Agora iremos descrever um cenário real de caso de uso com um ecommerce simples utilizando a CDP. Para isso vamos ao Objetos, Atributos e Relacionamentos desse ecommerce:
Com isso criamos o schema da Graphql que seria:
Dado que todo nosso shema esta descrito acima, vamos agora executar queries utilizando a interface da GraphQL que irá se conectar ao CDP para realizar as operações de leitura e de escrita dos dados.
Testando…
Realizando uma Mutation
Realizando uma Query
Query de relacionamento + filtros
Query de relacionamento + filtros
Este foi um caso de estudos utilizando a GraphQL para servir os dados da CDP. Para mais continuar estudando sobre este assunto listamos abaixo referências sobre essa tecnologia que nos ajudaram a construir todo esse projeto:
- Building the New facebook.com with React, GraphQL and Relay
- Zero to GraphQL in 30 Minutes — Steven Luscher
- The GitHub GraphQL API
- Prisma
Grande Abraço,
Raffael Tancman