Flutter
GraphQL
Flutter e GraphQL: Integração com Back4App via Código
28 min
baixe um projeto flutter graphql com código fonte e comece a usar o back4app introdução neste tutorial, vamos construir um aplicativo que irá analisar dados do backend do back4app através do graphql como você pode saber, o graphql é uma linguagem de consulta e manipulação de dados de código aberto para apis, e um tempo de execução para atender consultas com dados existentes o back4app é um backend de baixo código como serviço (baseado na plataforma parse de código aberto) que ajuda os desenvolvedores a construir aplicativos móveis e web extensíveis e escaláveis em um ritmo rápido objetivos o principal objetivo é construir um aplicativo simples que irá mostrar uma lista de linguagens de programação e seu formato de tipo de salvamento no final deste artigo, esperamos que você seja capaz de fazer uma chamada de api no back4app usando graphql; obter os dados da api graphql; buscar dados no seu aplicativo flutter pré requisitos para completar este tutorial, você precisará um ide para escrever código flutter, como android studio ou flutter no entanto, usaremos o android studio para este tutorial uma conta back4app que pode ser criada aqui https //www back4app com/ https //pub dev/packages/graphql flutter 1 clonar projeto do github para o android studio vá para o https //github com/templates back4app/flutter graphql , e baixe o arquivo zip, extraia o e abra o no seu ide flutter para completar esta etapa, arraste a pasta dentro do arquivo zip para a sua área de trabalho, abra o android studio e clique em abrir projeto existente do android studio o diretório do projeto geralmente seria ‘ c \users\username\desktop\back4app graphql starting code ’ mas isso pode ser diferente para diferentes usuários abra o projeto e vá para o lib\main dart lib\main dart arquivo você verá muitos erros lá, não se preocupe, apenas pressione todos os ‘ get dependencies ’ e todos os erros desaparecerão se não desaparecerem, apenas pressione ‘ upgrade dependencies ’ o código no seu main dart main dart deve se parecer com isso 1 import 'package\ flutter/material dart'; 2 import 'package\ graphql flutter/graphql flutter dart'; 3 import 'consonents dart'; 4 5 void main() { 6 runapp(myapp()); 7 } 8 9 class myapp extends statelesswidget { 10 @override 11 widget build(buildcontext context) { 12 return materialapp( 13 home myhomepage(), 14 ), 15 ); 16 } 17 } 18 class myhomepage extends statefulwidget { 19 @override 20 myhomepagestate createstate() => myhomepagestate(); 21 } 22 23 class myhomepagestate extends state\<myhomepage> { 24 25 @override 26 widget build(buildcontext context) { 27 return safearea( 28 child scaffold( 29 appbar appbar( 30 title text('parsing data using graphql', 31 ), 32 ), 33 body container(), 34 ),); 35 } 36 } se você abrir o aplicativo agora, você só verá uma tela vazia em seu emulador/dispositivo com apenas uma appbar intitulada ‘analisando dados usando graphql’ trabalharemos no main dart main dart e nossos valores importantes estão armazenados em consonents dart consonents dart e podemos usá lo diretamente a partir daí precisaremos da dependência graphql flutter graphql flutter para usar graphql em nosso aplicativo o graphql flutter graphql flutter é o cliente graphql mais popular para flutter ele nos ajuda a usar consultas graphql diretamente em nosso código ele nos fornece graphqlclient graphqlclient , graphqlprovider graphqlprovider e muitos outros widgets úteis que nos ajudam a analisar dados de nosso banco de dados diretamente com a ajuda do graphql, sem nem mesmo usar streambuilder streambuilder o pacote nos fornece uma infinidade de recursos, incluindo assinaturas cache em memória sincronização de cache offline resultados otimistas uploads de arquivos graphql você pode importá lo escrevendo o seguinte código no arquivo pubspec yaml pubspec yaml dependências graphql flutter ^ 3 1 0 veja mais sobre graphql flutter graphql flutter em https //pub dev/packages/graphql flutter todas as dependências já estão pré instaladas e você pode prosseguir para a próxima etapa agora 2 criando backend no back4app depois de se inscrever no https //www back4app com/ site, você pode prosseguir para a próxima etapa e criar um novo aplicativo clique em ‘construir novo app’ dê a ele o mesmo nome que o nome do seu projeto, que aqui é ‘back4app graphql’ agora role para baixo até configurações do servidor à sua esquerda e selecione configurações gerenciar cartão do parse server, em seguida, selecione a opção ‘3 10 0 parse server 3 10 0’ da lista agora pressione o botão de salvar abaixo e aguarde até que seja salvo agora volte para núcleo (à esquerda), selecione a console da api , e selecione console graphql a partir dele esta é a janela onde você pode escrever e testar seu código de consultas/mutações graphql vamos prosseguir para o próximo passo 3 criando e obtendo dados através do graphql agora, vamos testar a api graphql no back4app usando o console da api graphql primeiro, cole a seguinte consulta na caixa de código à esquerda 1 mutation createclass { 2 createclass(input { 3 name "language" 4 schemafields { 5 addstrings \[{name "name"}{name "saveformat"}] 6 } 7 }){ 8 class{ 9 schemafields{ 10 name 11 typename 12 } 13 } 14 } 15 } 16 o código acima criará uma classe chamada “linguagem” vamos preencher esta nova classe com algumas linhas 1 mutation createobject{ 2 createlanguage(input {fields {name "python", saveformat " py"}}){ 3 language{ 4 name, 5 saveformat 6 } 7 } 8 } se sua operação for bem sucedida, você verá esta mensagem na caixa de código à direita no graphql playground 1 { 2 "data" { 3 "createlanguage" { 4 "language" { 5 "name" "python", 6 "saveformat" " py" 7 } 8 } 9 } 10 } as mutações são usadas para criar ou fazer alterações em uma classe ao executar a mutação acima, criaremos uma nova classe chamada language com os campos de dados name “python” saveformat “ py” repita o processo e crie mais dois objetos na mesma classe para name “c” e saveformat “ c” name “java” e saveformat “ java” a mutação para isso será assim 1 mutation createobject{ 2 createlanguage(input {fields {name "c", saveformat " c"}}){ 3 language{ 4 name, 5 saveformat 6 } 7 } 8 } java 1 mutation createobject{ 2 createlanguage(input {fields {name "java", saveformat " java"}}){ 3 language{ 4 name, 5 saveformat 6 } 7 } 8 } agora vamos ver todos os dados na nossa classe languages para ler os dados, usamos query então, vá em frente e digite o comando abaixo 1 query findlanguages{ 2 languages{ 3 count, 4 edges{ 5 node{ 6 name, 7 saveformat 8 } 9 } 10 } 11 } em query findlanguage query findlanguage ‘findlanguage’ é apenas um nome para o seu comando de consulta e você poderia até nomeá lo de qualquer outra forma usamos o find(classname "") find(classname "") comando para encontrar todos os elementos da classe específica count count , retorna o número de elementos na classe e todos os elementos são mostrados dentro do result result objeto a consulta acima vai retornar isto 1 { 2 "data" { 3 "languages" { 4 "count" 3, 5 "edges" \[ 6 { 7 "node" { 8 "name" "python", 9 "saveformat" " py" 10 } 11 }, 12 { 13 "node" { 14 "name" "c", 15 "saveformat" " c" 16 } 17 }, 18 { 19 "node" { 20 "name" "java", 21 "saveformat" " java" 22 } 23 } 24 ] 25 } 26 } 27 } você pode ver todas as outras consultas no seguinte link https //blog back4app com/graphql on parse/ agora, vamos prosseguir para o próximo passo 4 configurando o graphql em nosso app vamos começar a codificar nosso app antes disso, você deve fazer algumas coisas no seu lib\consonents dart lib\consonents dart arquivo copie o link graphql que está ao lado do botão de histórico no topo da janela graphql e cole o como um tipo de dado string kurl agora vá para o final da página e copie os códigos dos cabeçalhos http, copie apenas os códigos à direita dos dois pontos( ) e cole os com seus respectivos nomes no lib\consonents dart lib\consonents dart arquivo o arquivo deve ter o seguinte código 1 string kparseapplicationid= "application id copied from headers"; 2 string kparseclientkey = "client key copied from header"; 3 string kurl= "url copied"; 4 // replace "application id copied from headers", "client key copied from header", "url copied" with real keys/ids copied 5 //from http headers tab agora vá para main dart main dart arquivo e vá para o widget stateless myapp e adicione o seguinte código logo acima do return return materialapp() materialapp() 1 final httplink httplink = httplink( 2 uri kurl, 3 headers { 4 'x parse application id' kparseapplicationid, 5 'x parse client key' kparseclientkey, 6 }, 7 ); httplink é do flutter graphql dart e recebe o widget httplink() com dois parâmetros o primeiro é a url da api graphql no back4app o segundo são os cabeçalhos necessários para autenticar na api do back4app após esta seção, você precisa incluir o código do cliente graphql (explique o que é), copie o código abaixo e cole abaixo da seção httplink 1 valuenotifier\<graphqlclient> client = valuenotifier( 2 graphqlclient( 3 cache optimisticcache(dataidfromobject typenamedataidfromobject), 4 link httplink, 5 ), 6 ); agora fornecemos o método de link e cache ao nosso graphqlclient fizemos isso através do nosso valuenotifier e o nomeamos como client vamos envolver o widget myhomepage() que é um filho do materialapp com graphqlprovider e passar myhomepage() como seu cliente adicione um outro parâmetro dentro do graphqlprovider, nomeadamente client, e passe client (nome do nosso valuenotifier) nele é assim que sua classe myapp deve parecer agora 1 class myapp extends statelesswidget { 2 @override 3 widget build(buildcontext context) { 4 final httplink httplink = httplink( 5 uri kurl, 6 headers { 7 'x parse application id' kparseapplicationid, 8 'x parse client key' kparseclientkey, 9 //'x parse rest api key' kparserestapikey, 10 },//getheaders() 11 ); 12 valuenotifier\<graphqlclient> client = valuenotifier( 13 graphqlclient( 14 cache optimisticcache(dataidfromobject typenamedataidfromobject), 15 link httplink, 16 ), 17 ); 18 return materialapp( 19 home graphqlprovider( 20 child myhomepage(), 21 client client, 22 ), 23 ); 24 } 25 } vamos chamar a api e obter os dados 5 fazendo uma chamada de api agora vamos trabalhar no myhomepagestate vamos começar inicializando um tipo de dado string chamado ‘query’ e atribuir/passar a declaração da consulta para encontrar todos os dados da nossa classe language a ele como a consulta é de várias linhas, passaremos a consulta entre três aspas aqui está como ela se parece 1 string query=''' 2 query findlanguages{ 3 languages{ 4 count, 5 edges{ 6 node{ 7 name, 8 saveformat 9 } 10 } 11 } 12 } 13 '''; agora vá para o widget query(), dentro do parâmetro body do scaffold que tem duas propriedades opções construtor e então passe nulo para ambos é assim que seu método de construção ficaria 1 widget build(buildcontext context) { 2 return safearea( 3 child scaffold( 4 appbar appbar( 5 title text('parsing data using graphql', 6 ), 7 ), 8 body query( 9 options null, 10 builder null 11 ), 12 ),); 13 } o query() query() widget nos ajuda a escrever consultas para graphql e nos ajudará a ler e obter dados passaremos a declaração da consulta que tomamos como uma string nas opções e construiremos o widget com o parâmetro builder então passe o widget queryoptions() nas opções da seguinte forma 1 options queryoptions( 2 documentnode gql(query), 3 ), 4 a consulta é passada através do parâmetro documentnode em queryoptions agora vamos construir com a ajuda do parâmetro builder o método builder aceita uma função com três parâmetros, a saber, queryresult result; refetch refetch; fetchmore fetchmore neste momento, só precisamos nos preocupar com o queryresult que nos dá o resultado da nossa consulta e podemos acessar os dados através de result data result data então vamos codificar o seguinte abaixo 1 builder (queryresult result, { refetch refetch,fetchmore fetchmore,}) 2 { 3 if(result data==null){ 4 return center(child text("loading ",style textstyle(fontsize 20 0),)); 5 }else{ 6 return text('success'); 7 } 8 }, no código acima, estamos acessando os dados se não houver dados, retornamos um widget de texto dizendo ‘carregando…’ caso contrário, retornaremos um widget text() dizendo ‘sucesso’ aqui está como sua myhomepage myhomepage classe em main dart main dart deve parecer 1 class myhomepage extends statefulwidget { 2 @override 3 myhomepagestate createstate() => myhomepagestate(); 4 } 5 6 class myhomepagestate extends state\<myhomepage> { 7 string name; 8 string saveformat; 9 string objectid; 10 11 string query = ''' 12 query findlanguages{ 13 languages{ 14 count, 15 edges{ 16 node{ 17 name, 18 saveformat 19 } 20 } 21 } 22 } 23 '''; 24 25 @override 26 widget build(buildcontext context) { 27 return safearea( 28 child scaffold( 29 appbar appbar( 30 title text( 31 'parsing data using graphql', 32 ), 33 ), 34 body query( 35 options queryoptions( 36 documentnode gql(query), 37 ), 38 builder ( 39 queryresult result, { 40 refetch refetch, 41 fetchmore fetchmore, 42 }) { 43 if (result data == null) { 44 return center( 45 child text( 46 "loading ", 47 style textstyle(fontsize 20 0), 48 ), 49 ); 50 } else{ 51 return text('success'); 52 } 53 } 54 ), 55 ), 56 ); 57 } 58 } agora, inicie o app e aguarde alguns segundos após ele reiniciar se você ver ‘sucesso’ na tela, então parabéns! você estabeleceu sua conexão e chamou a api 6 obtendo e mostrando dados da api em vez de retornar o widget text, retornaremos o listview\ builder() widget com os dados originais escreva o seguinte código em vez de return text('sucesso') text('sucesso') 1 return listview\ builder( 2 itembuilder (buildcontext context, int index){ 3 return listtile( 4 title text(result data\["languages"]\["edges"]\[index]\["node"]\['name']), 5 trailing text(result data\["languages"]\["edges"]\[index]\["node"]\['saveformat']), 6 ); 7 }, 8 itemcount result data\["languages"]\["edges"] length, 9 ); agora, se você olhar de volta para a tela de resultado do graphql no console da sua api do back4app onde digitamos nosso método find, os resultados foram os seguintes 1 { 2 "data" { 3 "languages" { 4 "count" 3, 5 "edges" \[ 6 { 7 "node" { 8 "name" "python", 9 "saveformat" " py" 10 } 11 }, 12 { 13 "node" { 14 "name" "c", 15 "saveformat" " c" 16 } 17 }, 18 { 19 "node" { 20 "name" "java", 21 "saveformat" " java" 22 } 23 } 24 ] 25 } 26 } 27 } portanto, a partir do código acima, a localização de “python” foi “dados” > “ idiomas” > “contagem” > “arestas” > “nó” > “nome” também note que o nome está dentro de colchetes ‘\[]’ de arestas, o que simboliza que é o primeiro elemento da lista/array de arestas então precisamos entrar neste local para obter “python” e o mesmo para tudo o mais quando escrevemos resultado dados resultado dados , entramos na “dados” localização então, para dar os outros locais, adicionamos \["nome local"] \["nome local"] a isso assim, a localização de “python” será resultado dados\["idiomas"]\["arestas"]\[0]\["nó"]\["nome"] resultado dados\["idiomas"]\["arestas"]\[0]\["nó"]\["nome"] ao usar listview listview , ele leva dois parâmetros, contagemdeitens contagemdeitens , que informa o número de elementos na chamada da api, construtordeitens construtordeitens , que leva uma função com parâmetros (buildcontext contexto, int índice) (buildcontext contexto, int índice) e retorna uma lista de widgets na qual mostraremos os dados aqui, usaremos uma lista de listtile para mostrar os dados 1 return listview\ builder( 2 itemcount result data\["languages"]\["edges"] length, 3 itembuilder (buildcontext context, int index){ 4 return listtile( 5 title text(result data\["languages"]\["edges"]\[index]\["node"]\['name']), 6 trailing text(result data\["languages"]\["edges"]\[index]\["node"]\['saveformat']), 7 ); 8 }, 9 10 ); quando substituímos text('sucesso') text('sucesso') pelo acima listview\ builder() , primeiro passamos o itemcount onde passamos o número de elementos na lista de resultados e assim não precisamos nos preocupar mais com isso no itembuilder, estamos retornando uma lista de listtiles que terá o "nome" "nome" da "linguagens" "linguagens" classe e em "saveformat" "saveformat" no final note que usamos o índice em vez de qualquer número após o resultado, isso é o que o itemcount cuidou é assim que seu main dart main dart deve parecer agora 1 import 'package\ flutter/material dart'; 2 import 'package\ graphql flutter/graphql flutter dart'; 3 import 'consonents dart'; 4 import 'dart\ ui'; 5 6 void main() { 7 runapp(myapp()); 8 } 9 10 class myapp extends statelesswidget { 11 @override 12 widget build(buildcontext context) { 13 final httplink httplink = httplink( 14 uri 'https //parseapi back4app com/graphql', 15 headers { 16 'x parse application id' kparseapplicationid, 17 'x parse client key' kparseclientkey, 18 }, //getheaders() 19 ); 20 21 valuenotifier\<graphqlclient> client = valuenotifier( 22 graphqlclient( 23 cache optimisticcache(dataidfromobject typenamedataidfromobject), 24 link httplink, 25 ), 26 ); 27 28 return materialapp( 29 home graphqlprovider( 30 child myhomepage(), 31 client client, 32 ), 33 ); 34 } 35 } 36 37 class myhomepage extends statefulwidget { 38 @override 39 myhomepagestate createstate() => myhomepagestate(); 40 } 41 42 class myhomepagestate extends state\<myhomepage> { 43 string name; 44 string saveformat; 45 string objectid; 46 47 string query = ''' 48 query findlanguages{ 49 languages{ 50 count, 51 edges{ 52 node{ 53 name, 54 saveformat 55 } 56 } 57 } 58 } 59 '''; 60 61 @override 62 widget build(buildcontext context) { 63 return safearea( 64 child scaffold( 65 appbar appbar( 66 title text( 67 'parsing data using graphql', 68 ), 69 ), 70 body query( 71 options queryoptions( 72 documentnode gql(query), 73 ), 74 builder ( 75 queryresult result, { 76 refetch refetch, 77 fetchmore fetchmore, 78 }) { 79 if (result data == null) { 80 return center( 81 child text( 82 "loading ", 83 style textstyle(fontsize 20 0), 84 )); 85 } else { 86 return listview\ builder( 87 itembuilder (buildcontext context, int index) { 88 return listtile( 89 title text(result data\["languages"]\["edges"]\[index]\["node"] 90 \['name']), 91 trailing text(result data\["languages"]\["edges"]\[index] 92 \["node"]\['saveformat']), 93 ); 94 }, 95 itemcount result data\["languages"]\["edges"] length, 96 ); 97 } 98 }, 99 ), 100 ), 101 ); 102 } 103 } e nossa tela final do aplicativo conclusão agora você tem um aplicativo flutter conectado a uma api graphql que pode armazenar e recuperar dados no back4app não foi necessário codificar ou decodificar os dados json separadamente, o que torna nosso trabalho mais fácil e rápido usando poucas linhas de código tenha um ótimo dia!