Entendendo o que é GraphQL através de exemplos
Tags: graphql, javascript, api, rest
Published: 2019-04-01 20:35:03

---
title: Entendendo o que é GraphQL através de exemplos
published: true
description: Mesmo com a popularidade do GraphQL, dúvidas sobre o que ele é, e o que resolve são comuns. Neste artigo pretendo explicar a partir de exemplos o que é GraphQL e qual o seu objetivo.
tags: GraphQL, JavaScript, API, Rest
canonical_url: https://blog.codecasts.com.br/entendendo-o-que-%C3%A9-graphql-atrav%C3%A9s-de-exemplos-c2fa35e8bf63
cover_image: https://thepracticaldev.s3.amazonaws.com/i/9047u3aivsf7gjz02ecl.png
---

Mesmo com a popularidade do GraphQL, dúvidas sobre o que ele é, e o que resolve são comuns. Neste artigo pretendo explicar a partir de exemplos o que é GraphQL e qual o seu objetivo.

------

# O que não é GraphQL?

Talvez este não seja o tópico que você esperava encontrar, e algumas das coisas aqui pareçam absurdas, mas acredite há pessoas que pensam ou já pensaram isso sobre GraphQL.

> [Publicado originalmente em 10/03/2019](https://blog.codecasts.com.br/entendendo-o-que-%C3%A9-graphql-atrav%C3%A9s-de-exemplos-c2fa35e8bf63)

## GraphQL não é um banco de dados

GraphQL não tem nenhuma relação com o banco de dados, e não é um [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping). Ele nem precisa de um banco de dados para funcionar.
Talvez essa associação exista quando se ouve que ele é uma [Query Language](https://en.wikipedia.org/wiki/Query_language).


## GraphQL não é um _framework_

Não se trata de mais um _framework_, em sua essência GraphQL é uma especificação que possui [implementações em diversas linguagens](https://graphql.org/code/).

## GraphQL não é exclusivo para HTTP/APIs

GraphQL não é simplesmente uma nova forma de se criar APIs com HTTP.  
Na verdade ele nem usa verbos HTTP, ele desconhece completamente esta camada. GraphQL não se limita ao contexto de aplicações HTTP.

------

# O que é GraphQL?

_‘Uma Query Language.’_  
Infelizmente é uma resposta simples e pouco objetiva. Mesmo que GraphQL em si seja algo simples, por vários motivos a explicação do que ele é não é a mais simples.

O objetivo deste artigo não é entrar nas nuances mais técnicas, porém é necessário explicar alguns conceitos chave.

## Tipos e Schema

GraphQL é estaticamente tipado, tudo nele precisa de um tipo associado, e esses tipos formam um _schema_.  
É a partir desse _schema_ que as _queries_ são executadas e consequentemente validadas, tanto entrada quanto saída.

Há alguns tipos base, como  [`String`, `Int`, `Float`, `ID` e `Boolean`](https://graphql.org/learn/schema/#scalar-types). Eles são conhecidos como _Scalar Types_, e é possível criar os seus próprios tipos, escalares e objetos.

Segue o exemplo da criação de dois tipos, **User** e **Address**

![](https://thepracticaldev.s3.amazonaws.com/i/5e6qqhkteavvl78ws294.png)

Os tipos acompanhados de `!` informam que não aceitam `null` como valor.  
O mais interessante deste exemplo é o _field_ **_address_** de **User**, ele aponta para outro tipo, o **Address**. Podemos assumir que há um relacionamento entre **User** e **Address**.

> Como esse relacionamento é feito? Não importa, GraphQL não entrega detalhes de implementação, o _field_ _address_, pode vir de qualquer lugar seja, outro banco, arquivo ou API.

Para que consultas sejam feitas, há um tipo especial no _schema_, ele é a “porta de entrada”

![](https://thepracticaldev.s3.amazonaws.com/i/f0xgw1spj8ud3047xarx.png)

Aqui temos uma idéia mais completa e elaborada. Em _schema_ informamos que o tipo **Query** é responsável pela _“entrada”_ das queries, este tipo também costuma ser conhecido como **RootQuery**.

Em **Query** temos dois _fields_, **_Users_** e **_User_**. Podemos ver também o uso de argumentos em _fields_, significa que para consumir aquele dado, é necessário passar esses argumentos caso eles sejam obrigatórias.

Apenas **_User_** tem **_uuid_** com argumento obrigatório, em **_Users,_** **_pagination_** e **_search_** não são obrigatórios.

![](https://thepracticaldev.s3.amazonaws.com/i/7pqx9cswkisbo7drhltz.png)

Neste exemplo de _query_ o recurso **_User_** é consumido, passando como argumento **_uuid_**. Com base na assinatura do _field_, se um tipo **User** não for retornado, o GraphQL informará erro.

Ainda no exemplo antes desse, em **_Users_**, o argumento **_pagination_** recebe também um tipo como argumento, e como resposta não temos uma lista de **User**, e sim outro tipo **UsersResource**.

![](https://thepracticaldev.s3.amazonaws.com/i/bvajzjg8i4mr2aufjqnc.png)

GraphQL não tem recursos de paginação ou qualquer coisa do gênero, isso deve ser feito através do [design do _schema_](https://github.com/Shopify/graphql-design-tutorial) que está sendo criado. Este é um dos design possíveis para esse tipo de situação.

### Resolvers

> A partir daqui o artigo passa a focar na [implementação em JavaScript](https://github.com/graphql/graphql-js) do GraphQL, mas os conceitos são compartilhados entre as outras implementações.

_Resolvers_ são funções responsáveis por, como o nome sugere, revolver um pedido e devolver o dado solicitado. Abaixo segue o exemplo de um possível resolver para **_Query.User_**.

![](https://thepracticaldev.s3.amazonaws.com/i/uqpn0h8zaw4lxhc2fk2s.png)

É uma função extremamente simples, ela recebe três argumentos: `_root_`, `_args_` e `_context_`.

> Como é um resolver raiz, _root_ não tem valor. Mais sobre ele em seguida.

O segundo parâmetro (_args_) contém um objeto com o que foi passado para o _field_ quando a _query_ foi feita, no exemplo em questão, um objeto com a propriedade **_uuid_**.

O terceiro parâmetro (_context_) é controlado pela nossa instância do GraphQL, todos os _resolvers_ recebem o mesmo _context_. Ele é extremamente útil para compartilhar coisas como usuário atual, serviços e coisas como conexão com o banco de dados.

Neste exemplo o _uuid_ de _args_ é utilizado em conjunto do [_knex_](https://knexjs.org/) de _context_, e com isso um registro é recuperado do banco de dados.

O retorno de um _resolver_ é uma [promessa](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise), o GraphQL espera a resolução dessas promessas para devolver os resultados obtidos. No exemplo acima, se o resultado não for satisfatório o GraphQL informa que houve um erro. Porém, é possível gerar erros mais assertivos.

![](https://thepracticaldev.s3.amazonaws.com/i/fjes71jpwqn0wzj950yp.png)

Agora um erro mais preciso será recebido por quem executou essa _query_.

### Relacionamentos

Como visto anteriormente, é possível estabelecer um relacionamento entre tipos no GraphQL. Foi estabelecido um relacionamento entre **User** e **Address**.

Temos duas formas de chegar até o tipo User, através de `Query.User`ou `Query.Users.records`. O primeiro devolve apenas um **User**, o outro uma lista de User, cada um com seu respectivo _resolver_. Isso só tem importância para se entender que é necessário criar apenas um resolver para o _field_ **address**.

![](https://thepracticaldev.s3.amazonaws.com/i/zevwhlo83toydh7bptco.png)

Este é o resolver `User.address`. Não importa de onde o tipo User foi recuperado, há apenas um resolver para _address_. Isso significa que uma vez que isso seja mapeado, todo o seu _schema_ tira proveito disso.

Em `userAddressResolver` **root** é o **User** em questão, dele é extraído a propriedade **_zipcode_**. Em seguida zipcode é passado como argumento para `zipcodeService` . Os detalhes de implementação dele não importam, porém é possivel imaginar que este serviço se comunique com uma API externa que devolve informações baseadas no _zipcode_.

Vamos acrescentar mais alguns tipos ao nosso _schema_.

![](https://thepracticaldev.s3.amazonaws.com/i/g9o8bn5361drlt0k72a3.png)

Agora há o tipo **Photo** e um novo _field_ em **Query**, o **_featuredPhotos_**.

> Repare no field url, ele devolve o tipo **Url**, este não é um tipo nativo do GraphQL, foi colocado apenas como exemplo que é possível criar tipos como esse.

Uma vez que Photo tenha um relacionamento com User, é possível fazer a seguinte _query_:

![](https://thepracticaldev.s3.amazonaws.com/i/ml8jtsl7y9olm8uw2dur.png)

# Visão geral

Ao adotar GraphQL em sua aplicação, você terá inicialmente uma curva levemente mais lenta no começo, porém rapidamente o valor agregado do GraphQL se destaca, o desenvolvimento do _back-end_ e do _front-end_ se torna mais ágil e dinâmico, menos idas e voltas.

A maior dificuldade do GraphQL não está em sua implementação e uso, e sim no design dele. Ele não tem os problemas de design que uma aplicação [_Rest_](https://becode.com.br/o-que-e-api-rest-e-restful/) possui, porém trás novos desafios.  
Ainda não há um consenso difundido sobre padrões de design com GraphQL, mas há uma grande fonte de exemplos e cases.

Pessoalmente acredito na qualidade e versatilidade do GraphQL frente a soluções Rest. Não me sinto mais confortável em criar uma aplicação que não possua o GraphQL como API.

Entre os muitos usos do GraphQL é utilizado como _front-end_ de outros _back-end_, isso é conhecido como [**Backend-For-Frontend**](https://medium.com/tech-tajawal/backend-for-frontend-using-graphql-under-microservices-5b63bbfcd7d9). Imagine a complexidade de um front-end ter que acessar várias APIs distintas para conseguir uma informação, GraphQL atende muito bem a esses cenários.

# E o Rest?

É possível argumentar que com a ajuda de um ORM + algum padrão mirabolante de _requests_, é possível se obter estes resultados sem o uso do GraphQL

Abaixo alguns destaques que reforçam a adoção do GraphQL

## Existe padrão

Na grande maioria dos casos você ou sua equipe iriam inventar algum padrão/método ou aplicar alguma biblioteca para emular esse comportamento (respostas personalizadas, relacionamentos…)  
Porém há uma equipe grande e séria por trás da especificação do GraphQL, este artigo não cobre metade das possibilidades.

## Auto-documentação

Enquanto seria necessário aplicar ferramentas que geram documentações compatíveis com [swagger](https://swagger.io/) e similares, GraphQL possui documentação automática, além de um ambiente de testes muito produtivo.

- [**graphql/graphiql**](https://github.com/graphql/graphiql)
- [**prisma/graphql-playground**](https://github.com/prisma/graphql-playground)

## Auto-validação

O sistema de tipos do GraphQL já funciona como um processo de validação, tanto de entrada quanto de saída. Também existe a possibilidade de integração com editores de código que validam as _queries_ da aplicação, além de linhas de comando que podem ser integradas em processos de CI/CD

- [**prisma/vscode-graphql**](https://github.com/prisma/vscode-graphql)
- [**cjoudrey/graphql-schema-linter**](https://github.com/cjoudrey/graphql-schema-linter)

## Realtime

A especificação do GraphQL já prevê real-time. Não são todas as implementações que são compatíveis, porém ela existe e não é complexa.  
Isso abre muitas possibilidades antes inexistentes para alguns projetos ou equipes.

[**facebook/graphql**](https://github.com/facebook/graphql/blob/master/rfcs/Subscriptions.md)

# Iniciando com GraphQL

Este artigo não demonstra como começar com GraphQL, por isso, abaixo está uma lista de recursos úteis para se começar com GraphQL.  
Lembrando que GraphQL é implementado em várias linguagens, então escolha a que for mais amigável para você e comece seus experimentos.

- [**GraphQL para iniciantes** _Tudo o que você precisa saber para iniciar com GraphQL_](https://medium.com/trainingcenter/graphql-para-iniciantes-a4cbe6c3da5d)
- [**How to GraphQL - The Fullstack Tutorial for GraphQL** _Fullstack GraphQL Tutorial to go from zero to production covering all basics and advanced concepts.](https://www.howtographql.com/)

{% youtube 8D9XnnjFGMs %}
{% youtube KaxB8wPeTkI %} 
{% youtube -0uxxht4mko %} 
{% youtube m26i1L2D7Yk %} 
{% youtube vWdLM3IK0gw %} 

-----

Interessado em aprender mais sobre GraphQL? Entre no nosso grupo no Telegram [https://t.me/GraphQLBrasil](https://t.me/GraphQLBrasil)

-----

Não deixe de compartilhar e comentar este artigo. Deixe nos comentários sua opinião sobre esse assunto, pontos que você concorda ou discorda. Vamos agregar mais conhecimento!

----

Se quiser saber mais sobre meu trabalho visite [**blog.codecasts.com.br**](https://blog.codecasts.com.br). Assine nosso [canal no YouTube](https://www.youtube.com/channel/UCTluPqMkm90zyw6mCde561A), lá você vai ver vídeos sobre [JavaScript](https://www.youtube.com/watch?v=fBInMy61plk&t=0s&list=PLy5T05I_eQYNQs4Pta85XRSucm3IOHx2M&index=2), [jQuery](https://www.youtube.com/playlist?index=1&list=PLy5T05I_eQYN8T15w4KLLcDcjAmIXDyu-&playnext=1), [Gulp](https://www.youtube.com/watch?v=eukZI7Rcrss&t=0s&index=2&list=PLy5T05I_eQYPl_iF2aJ0T0JBgJMatOLwv), [ES6](https://www.youtube.com/watch?v=yRr8Wo4XfYY&list=PLy5T05I_eQYOoUz2TtAqq35RLCc-xBZCe&index=2&t=0s), [Vue.JS](https://www.youtube.com/watch?v=ck8uNY0B0HI&index=2&t=0s&list=PLy5T05I_eQYOr3uPSI-eTVCLe1GF1qOf5) e muito mais. Também não deixe de entrar em contato pelo nosso grupo no [Telegram](https://t.me/codecasters)

> that’s all folks