image

Access unlimited bootcamps and 650+ courses

50
%OFF
Article image
Rubens Reis
Rubens Reis11/05/2022 16:56
Share

GraphQL, a alternativa ao REST!

  • #Facebook
  • #RESTful
  • #REST

Fala galera, tudo bom com vocês? Esse é meu primeiro artigo aqui na Dio, e nele eu vou falar um pouco sobre uma tecnologia muito interessante chamada GraphQL.

GraphQL é uma linguagem de consulta e ambiente de execução em servidores para desenvolvimento de APIs.

Ela foi criada pelo Facebook, em 2012, quando foi necessário mudar a forma que os aplicativos nativos estavam recebendo os dados

Ela surgiu para resolver dois problemas de APIs RESTful: O Over-fetching e o Under-fetching, pra quem não conhece nada sobre REST e RESTful, eu recomendo estudar e aplicá-la antes de se jogar diretamente no Graphql.

Começaremos fazendo uma analogia.

Vamos supor que você entra um restaurante e recebe o cardápio.

A partir daí um procedimento acontece:

  • Você terá que escolher qual prato deseja para o garçom ir até a cozinha e fazer o pedido.
  • O chef vai ser avisado sobre o prato que você quer e vai preparando, quando estiver pronto, o garçom leva o prato até você.

Mas você não tinha notado que o prato vem com brócolis, e desde a sua infância, você tem alergia à brócolis. Mas agora é tarde, você não pode comer aquele brócolis, e vai acabar sendo forçado a deixar ele no prato, que desperdício, não? Aquele brócolis custou dinheiro e suor para ser plantado, transportado, preparado, e delicadamente posto no seu prato.

Numa API RESTful, de forma geral, você não tem como dizer quais partes dos objetos você quer, ou não. Você simplesmente recebe tudo, mesmo se não for utilizar tudo.

Às vezes, você só precisa do nome de usuário para exibir em uma página, e recebe o usuário inteiro como resposta.

Isso é o Over-fetching, quando você recebe mais do que precisa.

Já o Under-fetching é o inverso:

Voltando ao restaurante, além de ter um brócolis, o prato não tem batatas, e você ama batatas, mas você queria muito comer esse prato que acabou de pedir, nesse momento você pensa: será que você vou ter que pedir outro prato diferente, só para comer batatas?

Nesse caso, você recebe menos do que deveria receber, resultando mais de uma requisição para conseguir o resultado final.

O Graphql funciona como um restaurante self-service, você coloca no seu prato apenas aquilo que você quer, e, ao contrário do outro restaurante, você sabe exatamente como o seu prato vai ser, por que é você mesmo que monta.

Enquanto a cozinha, não precisa se preocupar em como os pratos dos clientes vão ser, eles só precisam enviar os ingredientes individualmente prontos para serem consumidos.

Para fazer isso o Graphql trabalha com três pilares básicos:

Schema, Resolvers e Queries.

Schema

O schema é o que faz com que a API seja confiável e previsível, pois além servir como documentação, é baseado no schema, que as validações de requisições e respostas são feitas. Nele, nós definimos quais são os tipos de objetos que fazem parte da API, e também os campos que ele contém.

Veja uma parte de um esquema abaixo, (retirado de um projeto pessoal, se quiser saber mais sobre ele, clique aqui : https://hxshrt.tk/ICTc3W)

type LiteUser{
  _id: ID!
  name: String!
  email: String!
}

type Note{
  _id: ID!
  title: String!
  content: String!
  createdAt: String!
  expiresIn: String
  completed: Boolean!
  owner : ID!
   
    
}

Se o esquema mostra que uma usuário tem determinados campos, ele quer dizer:

Para o cliente: "Escolha quais campos, dentre os disponíveis, você precisa."

Ou seja, não faz sentido pedir um campo senha numa requisição de um usuário, pois não faz parte do schema. E também não é necessário pedir o campo content, quando você quer listar apenas os títulos das anotações.

Para o servidor: "Faça o que tiver de ser feito e me retorne um objeto conforme o declarado e não se preocupe com mais nada."

Basicamente, o servidor só precisa, depois de executar o que for necessário, enviar um objeto conforme a declaração. E pronto. O Graphql faz a mágica. E avisa caso você estiver enviando um objeto não compatível.

Sendo assim, tanto o cliente, quanto o servidor, sabem o que está em jogo em cada requisição, tornando a API previsível, além disso o próprio Graphql também sabe, e vai garantir que as os pedidos e respostas sigam o padrão definido.

Resolvers

Mas como, de fato, é uma requisição graphql? Aqui, vamos dividir a requisição em duas partes: queries e resolvers. Vamos falar dos Resolvers primeiro.

No schema eles são declarados assim:

type Mutation {
  createUser(name: String, email: String, password: String) : String!

  updateUser(name: String = "", email: String = "", password: String = "") : User!

  deleteUser : Boolean!

  createFolder(folderName: String) : UniqueFolder!

  updateFolder(folderId: String, newFolderName: String = "", toMain: Boolean = false) : UniqueFolder!

  createNote(title: String, content: String, createdAt: String, expiresIn: String = "Never" ,folderId: String = ""): Note!

  updateNote(noteId: String, title: String, content: String, expiresIn: String, fromFolder: String, toFolder: String, complete: Boolean, modifiedAt: String): Note!

  deleteTarget(level: Int, targetId: String): [Boolean!]!
      createInvite(noteId: String, to: String): [Int!]!

  responseInvite(inviteId: String, response: Boolean): Boolean!
}
  
type Query {
    loginUser(email: String, password: String) : String!
    getOneNote(noteId: String): Note
    getUser: User!
}

Então, eles se formam assim:

  • nome(parâmentos) : tipo do retorno

Não se preocupe com a sintaxe agora. As palavras Query e Mutation após o type, no topo das declarações, serão explicadas depois.

Cada resolver aponta para uma função, que quando chamada, executa o seu código e deve retornar a resposta conforme o tipo declarado.

Ao invés das rotas da API RESTful, quando você quer um recurso da API Graphql, você faz uma query, e envia para um endpoint, geralmente, só se utiliza apenas um endpoint para toda a API, mas você se pergunta: como a API vai saber o que deve executar?

É aí que entram os resolvers, você indica qual resolver você deseja quando faz a query, e escolhe os campos do retorno que você quer receber.

Queries

As queries são uma mistura de parâmetros de url, corpo da requisição e métodos http. Elas são simples strings, onde você aplica uma sintaxe específica, que vai ser interpretada pelo Graphql. 

Existem 3 tipos:

  • Query: equivale ao método GET.
  • Mutation: equivale aos métodos POST, PUT e DELETE.
  • Subscription: é um tipo especial, onde você recebe atualizações em tempo real. Não vamos falar sobre ela aqui.

Em relação ao métodos http da query e mutation, saiba que

as requisições sempre são feitas usando método POST, sempre no mesmo endpoint. Quando você escreve a query, a ferramenta que você utilizar, vai saber como lidar com a requisição, então você não precisa se preocupar com isso.

A equivalência com os métodos está ao usar a palavra "query'', indica que você quer apenas ler dados, ou ao usar "mutation", indica que você quer modificar dados, o tipo de modificação (criar, editar ou apagar) vai ser definida pelo resolver que você chamar, é uma boa prática descrever a ação no nome do resolver.

/* Essa mutation retorna uma String, por isso não há necessidade de escolher campos.*/
`
mutation($name: String, $email: String, $password:String){
  createUser(name: $name,email: $email, password:$password)
}
`

/*Já aqui, eu escolho quais campos serão retornados(Veja o schema lá em cima.)*/
`
query($noteId: String!){
  getOneNote(noteId: $noteId){
    expiresIn,
    createdAt
  }
}
`

Os nomes marcados com "$", são variáveis, para usar nas queries, mas não vou aprofundar muito nesse assunto.

Essas palavras-chave servem para manter a previsibilidade e documentação tanto das queries, quanto dos resolvers, mesmo que possam não ser seguidas (se você criar uma Mutation que não modifica nada, ou uma Query que modifica, por exemplo), você deve respeitá-las como se fossem leis, ou seja: queries são apenas leitura, e mutations são feitas para modificar dados.

Resumindo os três pilares:

  1. Você faz uma QUERY, que aponta para um RESOLVER.
  2. Escolhendo os campos que você precisa, que devem estar definidos no SCHEMA.
  3. O Graphql analisa sua QUERY, chama o RESOLVER correspondente, que retorna um objeto.
  4. Objeto esse que será validado pelo Graphql com base no SCHEMA.
  5. Depois será filtrado e enviado para você com base nos campos definidos na sua QUERY.

Dúvidas

Mesmo depois dessa breve introdução, ainda podem surgir algumas dúvidas, não é mesmo?

  • O GraphQL é uma alternativa ao REST, ou um implacável substituto?
  • Mesmo com várias vantagens e recursos muito bons, o GraphQL não é um substituto completo ao REST, o REST ainda é mais usado no mercado e ainda que você possa fazer o que o REST faz, você pode utilizá-los em conjunto, mascarando suas requisições REST com o endpoint único do GraphQL (o inverso também é possível.)
  • O GraphQL é seguro?
  • As preocupações com segurança, são as mesmas de uma API feita com REST, como injeção de SQL, ou Ataques DoS. Existem também algumas vulnerabilidades específicas do GraphQL, porém isso não o coloca como menos seguro do que o REST.
  • O que é um cliente GraphQL?
  • Clientes GraphQL, são uma forma otimizada de consumir a API no front-end, eu recomendo fortemente a utilização de uma ferramenta como essa, você pode utilizar requisições comuns para acessar a API, mas um cliente ajuda muito na agilidade e facilidade de acesso, uma das mais utilizadas é o Apollo Client.

Então é isso pessoal, eu estou pensando em escrever mais artigos como esse, com tecnologias que a Dio aborda pouco, ou não aborda, nos cursos. Comentem o que acharam, se curtiram, e caso queiram que eu traga mais conteúdos como esse, podem dar ideias aí nos comentários, tá?

Você pode me encontrar e conversar comigo por aqui:

https://www.linkedin.com/in/rubens-rafael-1455a4213/

Espero vocês lá!

Seria pedir muito #GraphqlNaDio ?

Share
Comments (2)
Igor Santos
Igor Santos - 07/07/2022 10:15

Cara, a analogia com comida foi a melhor que vi até agora, não tem como não lembrar mais as diferenças básicas entre REST x GRAPHQL, rsrs, parabéns!

CR

Christopher Ribeiro - 30/05/2022 01:16

adorei o conteúdo. Me fez entender algo que já perdi horas estudando sem de fato entender, obrigado.

Read below