Hands ON: API GraphQL+ REST com Hasura em minutos – Parte 2
No post anterior, Hands ON: API GraphQL+ REST com Hasura em minutos – Parte 1, estruturamos nossa API com a modelagem do banco de dados e provisionamento do Hasura. Agora vamos aproveitar essa estrutura e aprender como inserir e recuperar dados utilizando a nossa API.
Populando a base de dados
Em um ambiente real seu banco será alimentado com dados vindo de inserções ou mutações (no caso do GraphQL). Nós podemos fazer isso de várias formas, com o psql via terminal, com um seed SQL, mas vamos fazer isso já utilizando GraphQL para que você veja a mágica acontecendo.
Fonte: Giphy
Clique em API, a janela irá carregar o GraphQL Explorer trazendo algumas orientações.
No canto inferior esquerdo você pode observar que já existem algumas queries pra você usar, baseadas na nossa modelagem.
Fonte: produzida pelo autor
Utilizando operações out-of-the-box
O GraphQL trabalha com operações, são elas as queries, mutations e subscriptions. Ao fazer a tradução do banco de dados para o GraphQL o Hasura já cria pra gente como base algumas operações.
O explorer do GraphQL possui uma funcionalidade muito interessante que é o autocomplete, ao digitar o atalho ctrl + espaço. No exemplo abaixo podemos ver que já temos diversas operações disponíveis, como expliquei anteriormente.
Fonte: produzida pelo autor
Então vamos inserir nosso primeiro artista, utilizando a mutation insert_artist.
Ao escrever mutation no
mutation{ insert_artist(objects: { name: "Iron Maiden" }){ affected_rows } }
Fonte: produzida pelo autor
Vamos com calma, o que estamos fazendo aqui?
Na linha 1 – descreve a operação (mutation).
Linha 2 – chama a mutation insert_artist e passa como parâmetro um item chamado objects, que pode ser um array ou apenas um objeto.
Linha 3 – descreve o field name do objeto a ser inserido (que é o único campo que precisamos passar para nosso artist).
Linha 4 – fechamos o objeto e os parâmetros da função e abrimos o retorno que vamos pedir do GraphQl.
Linha 5 – solicitamos affected_rows que nada mais é do que a quantidade de linhas afetadas no banco.
E nas linhas subsequentes fechamos as chaves que faltam.
Já temos uma forma de inserir dados, agora vamos ver se conseguimos buscar esse dado do banco?
Vamos descobrir como podemos explorar nossa API usando a hierarquia do explorer, sem precisar manjar muito sobre a sintaxe do GraphQL ainda…
No explorer, clique na entidade que quer buscar, no nosso caso artist, depois em where para filtrar pelo name, quando ele for _eq (equals) a “Iron Maiden”
Fonte: produzida pelo autor
Perceba que ao apertar o botão para fazer a query, a ferramenta já adicionou o campo id como retorno da minha busca, pois eu não havia inserido nada. Como dá pra perceber, existe uma certa inteligência embutida na ferramenta que ajuda com esses casos.
De qualquer forma, aqui está a query e você pode brincar com ela:
query MyQuery { artist(where: {name: {_eq: "Iron Maiden"}}) { id } }
Se você for verificar lá na aba DATA perceberá que nosso banco já está com o dado persistindo.
Fonte: produzida pelo autor
Vamos remover esse dado para testar outra mutation:
Fonte: produzida pelo autor
mutation{ delete_artist(where: {name: { _eq:"Iron Maiden"}}){ returning{ name } } }
Essa mutation, também já criada automaticamente para nós, irá deletar o artista e como retorno, dessa vez solicitamos para o Hasura trazer nosso field name, você pode observar o retorno da query no lado direito da primeira imagem.
GraphQL a sério
Que maravilha, e agora?
Agora vamos popular esse banco pra valer e de lambuja mostrar o verdadeiro poder de uma engine GraphQL!
Fonte: Giphy
Lembra da nossa mutation que aceitava um array de objects, mas que só passamos um?
Vamos reescrever ela e vamos inserir mais dados… Muito mais dados mwahahaha!
Fonte: Giphy
Veja essa mutation:
mutation { insert_artist( objects: [ { name: "Iron Maiden" albums: { data: [ { title: "Powerslave" year: 1984 songs: { data: [ { title: "Aces High" } { title: "2 Minutes to Midnight" } { title: "Losfer Words" } { title: "Flash of the Blade" } { title: "The Duellists" } { title: "Back in the Villager" } { title: "Powerslave" } { title: "Rime of the Ancient Mariner" } ] } } ] } } { name: "Metallica" albums: { data: { title: "Kill'Em All" year: 1983 songs: { data: [ { title: "Hit the Lights" } { title: "The Four Horseman" } { title: "Motorbreath" } { title: "Jump in the Fire" } { title: "(Anesthesia) - Pulling Teeth" } { title: "Whiplash" } { title: "Phantom Lord" } { title: "No Remorse" } { title: "Seek & Destroy" } { title: "Metal Militia" } ] } } } } ] ) { affected_rows } }
Aí você pode me perguntar: “Como assim? Você está inserindo objetos em album e song a partir do artist?” Sim!
Fonte: produzida pelo autor
Ao rodar ela, nós alteramos 22 linhas, incluindo relacionamentos entre objetos aninhados.
Podemos utilizar esse pensamento para fazer queries também:
query albumAndSongs { album(where: {artist: {name: {_eq: "Metallica"}}}) { title year songs{ title } } }
Fonte: produzida pelo autor
API REST
Então, você chegou até aqui, viu todo o poder do GraphQL mas por algum motivo talvez você precise integrar com um time que não vai adotar GraphQL, talvez seu time não esteja interessado em trabalhar com GraphQL hoje… Ou talvez você simplesmente esteja interessado em ter uma API REST e não é da minha conta, ok, já entendi.
Isso não é um problema, o Hasura disponibiliza também uma API REST para você, basta configurar seus endpoints.
Configurando API REST
Para fazer isso é muito simples na verdade, então vamos lá. Aproveitando essa última query que escrevemos, vamos primeiro expor os parâmetros dela em variáveis da seguinte maneira:
query albumAndSongs($artist: String) { album(where: {artist: {name: {_eq: $artist}}}) { title year songs{ title } } }
Fonte: produzida pelo autor
Agora, clique em REST e crie seu endpoint:
Fonte: produzida pelo autor
Agora basta fazer o request para sua url (embaixo de location) e passar o artist como parâmetro.
Fonte: produzida pelo autor
Fonte: produzida pelo autor
x-hasura-admin-secret
Dependendo de como você instanciou o Hasura, para fazer a requisição para sua API será necessário passar o x-hasura-admin-secret no header da requisição. Você pode obter esse secret nas env vars lá no Hasura Cloud.
Fonte: produzida pelo autor
A url da sua API também pode ser encontrada na aba General.
The End?
Foi uma jornada interessante e pudemos descobrir diversas funcionalidades interessantes do Hasura. Porém, não para por aí! Além das mutations e queries que vem por padrão, você pode definir as suas próprias, bem como seus próprios tipos intermediários.
Entre outras coisas, o Hasura oferece ainda diversas funcionalidades:
– Possibilidade de configurar triggers e actions;
– Websockets;
– Fazer integrações com serviços externos praticamente sem código;
– Agregar schemas GraphQL remotos;
– Monitoramento e controles de segurança nativos;
– Exportação de código para aplicações que irão consumir a API.
O que vimos nesse tutorial foi apenas uma pequena parte do que compõe o Hasura.
Pensando bem, parece que o Hasura abstrai bastante trabalho para gente, não é? Ainda garante segurança, escalabilidade e performance de uma aplicação serverless.
A ferramenta é open source, gratuita e possui opções de hosting com preços competitivos.
Se eu fosse você iria lá nas docs e dava uma olhadinha, pois essa pode ser a ferramenta que vai agregar valor no seu próximo projeto.
Por hora é isso, até mais caro leitor!