Guia essencial do GraphQL para pessoas que desenvolvem frontend
Se você quer aprender o que é GraphQL e pra que ele serve, esse artigo é pra você! Ou, se você tem alguns problemas conhecidos com suas APIs REST e quer saber como resolver problemas de over e under fetching e excesso de roundtrips… esse artigo também é pra você!
Vamos juntos entender quais são os conceitos importantes relacionados a essa tecnologia e como podemos utilizá-la com os principais frameworks do mercado: React, Angular e Vue!
Imagine um cenário onde você é um Almirante da Frota Estelar e quer pedir um relatório contendo os detalhes de uma Nave da frota.
Você tem vários enpdoints REST pra te ajudar nessa missão. Porém o time de backend da frota utiliza microserviços. Então você tem um endpoint para cada recurso:
- naves
- tripulacao
- tripulantes
- cargos
Para cada nave, você precisa realizar uma chamada adicional para enriquecer os dados do seu relatório, para garantir que nenhum clandestino a bordo!
Nesse cenário, o número de requisições HTTP vai ser muito grande! Um pra nave, outro para a tripulação, pra cada tripulante alocado teremos mais duas requisições (uma para cargo e outra para o nome) e, por fim, mais uma requisição para pegar o nome do capitão. Nossa, fico cansado só de pensar.
Será que a gente consegue analisar o que nós temos e buscar uma solução alternativa? Vem comigo analisar o cenário.
Mão na massa
Vamos explorar um exemplo de como esse problema é na prática? Vem comigo analisar uma API que retorna dados sobre naves, tripulantes, tripulação e cargos da Star Trek (é um nerd que está conversando com você, não tem como fugir :]).
Só que repara bem nos endpoints que temos:
- http://localhost:3000/naves
- http://localhost:3000/tripulacao
- http://localhost:3000/tripulantes
- http://localhost:3000/cargos
Quando pedimos uma nave de id 1, recebemos:
{
"id": 1,
"nome": "Enterprise",
"classe": "Constitution",
"capitao_id": 1,
"missao": "Exploração"
}
E aí podemos pedir os dados do capitão:
http://localhost:3000/tripulantes/1
{
id: 1,
nome: "James T. Kirk",
idade: 35
}
E se quisermos a tripulação?
http://localhost:3000/tripulacao?naves_id=1
[
{
id: 1,
tripulante_id: 1,
cargo_id: 1,
naves_id: 1
},
{
id: 2,
tripulante_id: 2,
cargo_id: 2,
naves_id: 1
}
]
E agora podemos pedir o cargo:
http://localhost:3000/cargos/2
{
"id": 2,
"nome": "Oficial Científico"
}
E os detalhes:
http://localhost:3000/tripulantes/42
{
"id": 42,
"nome": "Coramila",
"idade": 28
}
Repara bem o número de requisições! E olha que ainda nem pegamos todos os dados de todos os tripulantes. Num ambiente onde consumimos micro serviços é comum termos cenários desse tipo, e aí temos que lidar com isso do lado do front end.
E é exatamente nisso que o GraphQL nos ajuda! Ao invés de lidarmos com vários pedidos desse tipo, podemos simplesmente fazer uma consulta que traga os dados que queremos.
O GraphQL é uma linguagem de consulta que foi criada pelo Facebook (atual Meta). O seu objetivo principal era otimizar e resolver problemas relacionados à obtenção de dados necessários em aplicações front end, tomando o cuidado para não trazer nem coisas demais (over fetching) e nem coisas de menos (under fetching). Isso tudo tentando otimizar a quantidade de chamadas para obter os dados necessários para abastecer toda uma tela.
Queries e mutations
As consultas (lembra que o GraphQL é uma linguagem de consulta?) se dividem em dois tipos: queries e mutations.
Quando queremos obter dados, utilizamos queries. E quando queremos enviar dados são as consultas que entram em ação.
Imaginando o cenário dos dados das naves da série Star Trek, poderíamos ter uma query que retornaria os dados de uma nave específica, assim:
query {
nave (id: 1) {
id
nome
classe
missao
}
}
E se quiséssemos trazer somente o nome do capitão?
query {
nave (id: 1) {
id
nome
classe
missao
capitao {
nome
}
}
}
E agora queremos o nome e o cargo de cada tripulante:
query {
nave (id: 1) {
id
nome
classe
missao
capitao {
nome
}
tripulacao {
nome
cargo {
nome
}
}
}
}
Isso resolve todo aquele problema do excesso de round trips, não é?
Eu sei que isso pode ser um pouco abstrato demais, e pensando em te ajudar a entender eu criei um backend que disponibiliza esse endpoint GraphQL e disponibilizei especialmente pra você aqui.
Você vai ter toda a descrição de como fazer tudo funcionar lá no github, tá bem?
React
Quer conectar sua aplicação React a uma API GraphQL? Bom, o Apollo Cliente pode te ajudar nisso.
A documentação é bem completinha. mas resumidamente você vai precisar configurar o seu Client:
const client = new ApolloClient({
uri: 'https://flyby-router-demo.herokuapp.com/',
cache: new InMemoryCache(),
});
Depois, pode colocar o provedor no nível mais alto da sua aplicação (ou apenas envolvendo os componentes que de fato vão precisar realizar queries, o que vc achar melhor):
function App() {
return (
<ApolloProvider client={client}>
{/* Componentes aqui */}
</ApolloProvider>
);
}
Agora podemos usar o useQuery
para obter os dados que queremos:
function Nave() {
const { loading, error, data } = useQuery(gql`
query {
nave (id: 1) {
nome
classe
missao
}
}`);
if (loading) return (<p>Carregando...</p>);
if (error) return (<p>Erro ao carregar a nave.</p>);
const { nome, classe, missao } = data.nave;
return (
<ul>
<li>{ nome } </li>
<li>{ classe } </li>
<li>{ missao } </li>
</ul>
);
}
Bacana né?
Angular
Não é porque você não tem me visto nos cursos de Angular que eu vou te deixar na mão! Se o que você precisa é plugar sua aplicação Angular numa api GraphQL, você vai precisar do apollo-angular.
Lá no seu app.module.ts
você configura sua conexão com o servidor:
import { APOLLO_OPTIONS, ApolloModule } from 'apollo-angular';
import { HttpLink } from 'apollo-angular/http';
import { HttpClientModule } from '@angular/common/http';
import { InMemoryCache } from '@apollo/client/core';
@NgModule({
imports: [BrowserModule, ApolloModule, HttpClientModule],
providers: [
{
provide: APOLLO_OPTIONS,
useFactory(httpLink: HttpLink) {
return {
cache: new InMemoryCache(),
link: httpLink.create({
uri: 'https://48p1r2roz4.sse.codesandbox.io',
}),
};
},
deps: [HttpLink],
},
],
})
export class AppModule {}
E no componente, basta executar a query no ngOnInit
:
export class Nave implements OnInit {
constructor(private apollo: Apollo) {}
ngOnInit() {
this.apollo
.watchQuery({
query: gql`
{
nave (id: 1) {
nome
classe
missao
}
}
`,
})
.valueChanges.subscribe((result: any) => {
console.log(result.data?.nave);
console.log(result.loading);
console.log(result.error);
});
}
}
Vue
Agora é hora da galera do Vue configurar o Apollo, vamos nessa?
Primeiro, vamos instanciar o ApolloClient:
const httpLink = createHttpLink({
uri: 'http://localhost:3020/graphql',
})
const cache = new InMemoryCache()
const apolloClient = new ApolloClient({
link: httpLink,
cache,
})
E graças a Composition API, podemos realizar queries assim:
<script>
import { useQuery } from '@vue/apollo-composable'
import gql from 'graphql-tag'
export default {
setup () {
const { result } = useQuery(gql`
query {
nave (id: 1) {
nome
classe
missao
}
}
`)
},
}
</script>
E prontinho, já temos acesso aos dados. A documentação pro pacote do Vue fica aqui.
Conclusão
Neste artigo, tivemos uma visão geral e mergulhamos no maravilhoso mundo do GraphQL. Aprender essa ferramenta é uma ótima opção para conectar suas aplicações web e obter dados.
Se quiser conhecer um estudo de caso de uma empresa que utiliza GraphQL, dá uma olhada no Case Farfetch: Front-End – Hipsters Ponto Tech #311.
01) Compartilhando o que você aprendeu
E vamos lançar um desafio! Se você gostou desse artigo, compartilhe nas redes sociais o que você aprendeu com ele com a hashtag #AprendinoBlogdaAlura.
02) Cursos de React da Alura
Se quiser conhecer mais sobre React, pode acessar todo o conteúdo de React da Alura, em que você poderá entender os fundamentos e primeiros passos do framework, desenvolver um portfólio de projetos e, é claro, técnicas e habilidades intermediárias e avançadas com essa tecnologia.
Primeiro, a formação React com JavaScript que vai te dar a bagagem inicial necessária para construir aplicações e componentes React;
Depois, você pode fazer a formação React com TypeScript. Onde você vai mergulhar mais fundo no universo do React, mas dessa vez utilizando todo o poder do TypeScript.
E além disso, você pode acompanhar uma formação bem bacana onde eu falo sobre como lidar com cenários mais complexos do GraphQL em aplicações React:
Espero que tenha gostado desse conteúdo que eu escrevi pra ti! Vida longa e próspera.