Flutter: Grafos de Relacionamento no Back4App
22 min
armazenar dados relacionais usando graphql introdução nos últimos dois tutoriais, realizamos consultas e mutações graphql em um banco de dados back4app a partir do nosso projeto de aplicativo flutter estamos usando graphql flutter https //pub dev/packages/graphql flutter/install como nosso cliente graphql, uma vez que este é um projeto muito robusto e amplamente utilizado para esses tutoriais, usamos um modelo de dados muito simples com os tipos mais comuns para nossas classes back4app é uma plataforma flexível que permite criar, armazenar e consultar dados relacionais neste tutorial, vamos nos aprofundar nessa capacidade, mostrando como usar relações e ponteiros ao salvar e consultar dados relacionais no backend do back4app além disso, vamos explorar outros tipos de dados que o back4app oferece, como geopointer e datetime objetivos no final deste artigo, você será capaz de criar/atualizar e excluir dados relacionais (usando pointers e relations) criar/atualizar geopointers criar/atualizar data hora pré requisitos para completar este tutorial, você precisará certifique se de que leu os dois guias anteriores começar a partir do template https //www back4app com/docs/flutter/graphql/flutter graphql project with source code download e mutação graphql https //www back4app com/docs/flutter/graphql/flutter crud app example baixe o arquivo do projeto de repositório do github https //github com/templates back4app/flutter graphql/tree/complex mutations que inclui o código anterior, bem como a nova interface gráfica que você precisará abra o projeto baixado em um ide flutter como vs code ou android studio conta back4app que pode ser criada aqui https //www back4app com/ conecte seu tutorial ao back4app conforme os tutoriais anteriores começar a partir do template https //www back4app com/docs/flutter/graphql/flutter graphql project with source code download 1 configurando o back end em nosso projeto anterior https //www back4app com/docs/flutter/flutter crud app example nosso modelo de dados era muito simples, com apenas uma única classe language agora vamos torná lo mais complexo, adicionando 2 novas classes e relacionando as com language fundador com formato nome da coluna descrição nome nome do fundador da língua nome da coluna descrição nome nome da empresa proprietária data propriedade data em que a propriedade foi adquirida pela empresa sede localização da sede da empresa vamos criar uma relação um para um entre a classe language e a classe founder usando parse pointers, que indicará o fundador da linguagem específica em seguida, criaremos uma relação um para muitos entre a classe language e a classe ownership usando parse relations que indicará qual organização/empresa possuía a linguagem, sua sede e a data em que adquiriu a propriedade da linguagem o modelo de dados ficará assim antes de irmos para nosso aplicativo, vamos criar as classes e os dados em nosso back end que precisaremos vá para seu aplicativo back4app e depois vá para o graphql playground usando a mutação abaixo, crie uma classe founder onde armazenaremos os nomes dos fundadores da linguagem 1 mutation createclass { 2 createclass(input { 3 name "founder" 4 schemafields { 5 addstrings \[{name "name"}] 6 } 7 }){ 8 class{ 9 schemafields{ 10 name 11 typename 12 } 13 } 14 } 15 } agora vamos preencher nossa classe com alguns nomes de fundadores nos passos seguintes, usaremos esses dados para criar novas linguagens apontando para a classe de fundador use a mutação abaixo no back4app graphql playground para criar seus fundadores 1 mutation createobject{ 2 createfounder(input {fields {name "james gosling"}}){ 3 founder{ 4 id 5 name 6 } 7 } 8 } aqui inserimos o nome do fundador da linguagem de programação java você pode fazer o mesmo para outros também, mas agora isso é suficiente para nosso guia vamos criar a ownership classe onde armazenaremos a propriedade da linguagem, a data de fundação (data hora) e a localização da sede do proprietário (geopointer) mais tarde, criaremos a relação entre a classe de linguagem e propriedade prossiga executando o código abaixo para criar a classe 1 mutation createclass { 2 createclass(input { 3 name "ownership" 4 schemafields { 5 addstrings \[{name "name"}] 6 adddates \[{name "date owned"}] 7 } 8 }){ 9 class{ 10 schemafields{ 11 name 12 typename 13 } 14 } 15 } 16 } agora preencha a propriedade classe usando as seguintes mutações 1 mutation createobject{ 2 createownership(input {fields {name "sun microsystems"}}){ 3 ownership{ 4 id 5 name 6 } 7 } 8 }1 mutation createobject{ 2 createownership(input {fields {name "oracle"}}){ 3 ownership{ 4 id 5 name 6 } 7 } 8 } agora atualize a página, vá para propriedade propriedade classe no navegador de banco de dados selecione o adicionar nova coluna no canto superior direito selecione geopoint no primeiro menu suspenso e nomeie como sede no segundo campo de texto e deixe tudo como está e pressione o adicionar coluna botão então vá para sua língua língua classe no navegador de banco de dados vamos adicionar as relações a propriedade propriedade e fundador fundador classes clique em adicionar nova coluna e então escolha o tipo de dado ponteiro e a classe alvo fundador fundador dê à coluna o mesmo nome fundador então pressione adicionar coluna agora repita esse processo adicionando uma nova coluna chamada propriedade usando o tipo de dado relação e selecionando a classe propriedade propriedade agora você tem seu modelo de dados pronto para usar em seu aplicativo flutter e para começar a salvar e atualizar os dados 2 criando/adicionando e deletando ponteiros agora você precisa baixar o código base do projeto do nosso repositório do github https //github com/templates back4app/flutter graphql/tree/complex mutations aberto no seu ide para conectar seu projeto ao back4app, vá para o graphql playground e copie as chaves e a url da api conforme mostrado na imagem abaixo agora cole as no constants dart constants dart e execute seu projeto execute o aplicativo no seu emulador vá até o m botão flutuante na parte inferior isso nos levará à página onde realizamos mutações simples aqui você encontrará um botão de ação flutuante extra cm esse é o botão que vamos usar para realizar nossas mutações graphql complexas clique no botão cm e você verá mais quatro botões, um para cada operação que vamos realizar neste guia agora abra o databaseutils dart databaseutils dart arquivo e role para baixo até o addpointers() addpointers() método aqui vamos adicionar a lógica para adicionar ponteiros vamos apontar james gosling como um fundador da linguagem java então, primeiro você precisará acessar seu backend do back4app e copiar o objectid objectid atualizando/criando ponteiro para dados prossiga para nosso aplicativo dentro do databaseutils dart databaseutils dart e dentro do addpointers() addpointers() método inicialize um string addpointerquery string addpointerquery onde iremos atribuir a consulta graphql para adicionar pointers da seguinte forma 1 string addpointerquery= 2 ''' 3 mutation addpointer(\\$languageid id!, \\$founderid updatelanguagefieldsinput! ){ 4 updatelanguage(input {id \\$languageid, fields \\$founderid}) 5 { 6 language{ 7 objectid 8 } 9 } 10 } 11 '''; e inicialize variável final variável final para atribuir variáveis, note que estamos pegando o rowobjectid rowobjectid e pointersid pointersid como parâmetros onde rowobjectid rowobjectid o id do objeto da linha de onde iremos apontar pointersid pointersid o id do objeto para a linha a ser apontada então declare variável variável como 1 final variable={ 2 "userid" rowobjectid, 3 "founderid" { 4 "founder" { 5 "link" pointersid 6 } 7 } 8 }; agora, como no último guia, vamos inicializar o graphqlclient graphqlclient e enviar a consulta com a ajuda de queryoptions() queryoptions() e retornar sua instância com queryresults() queryresults() 1 graphqlconfiguration configuration = graphqlconfiguration(); 2 graphqlclient client = configuration clienttoquery(); 3 4 queryresult queryresult = await client query( 5 queryoptions(documentnode gql(addpointerquery), variables variable), 6 ); 7 return queryresult; é assim que seu addpointers() addpointers() método deve parecer 1 future\<queryresult> addpointers(string rowobjectid, string pointersid) async{ 2 print('addpointers'); 3 //code for add/update pointers 4 string addpointerquery= 5 ''' 6 mutation addpointer(\\$languageid id!, \\$founderid updatelanguagefieldsinput! ){ 7 updatelanguage(input {id \\$languageid, fields \\$founderid}) 8 { 9 language{ 10 objectid 11 } 12 } 13 } 14 '''; 15 final variable={ 16 "userid" rowobjectid, 17 "founderid" { 18 "founder" { 19 "link" pointersid 20 } 21 } 22 }; 23 graphqlconfiguration configuration = graphqlconfiguration(); 24 graphqlclient client = configuration clienttoquery(); 25 26 queryresult queryresult = await client query( 27 queryoptions(documentnode gql(addpointerquery), variables variable), 28 ); 29 return queryresult; 30 } reinicie seu aplicativo agora, vá para o cm botão na página de mutação e então pressione o botão adicionar pointers aqui insira o objectid objectid da linha onde o ponteiro precisa ser adicionado no primeiro campo de texto e objectid objectid da linha onde ele apontaria no segundo campo de texto e então pressione concluído agora verifique seu painel e você deve ser capaz de ver uma relação sob a fundador coluna você pode clicar nela onde ela o levará à linha apontando para a classe fundador excluindo ponteiro para dados agora prossiga para o método deletepointers() deletepointers() onde escreveremos a lógica para excluir relações para excluir relações, você só precisa fazer pequenas alterações na consulta acima, ou seja, nas variáveis, basta trocar o "link" "link" por "remove" "remove" então, após inicializar variável final variável final ela ficaria assim 1 final variable={ 2 "languageid" rowobjectid, 3 "founderid" { 4 "founder" { 5 "remove" pointersid 6 } 7 } 8 }; todo o resto parecerá exatamente igual ao addpointers() addpointers() então seu deletepointers() deletepointers() método ficará assim 1 future\<queryresult> deletepointers(string rowobjectid, string pointersid) async{ 2 print('deletepointers'); 3 //code for delete pointers 4 string removepointersquery= 5 ''' 6 mutation addpointer(\\$languageid id!, \\$founderid updatelanguagefieldsinput! ){ 7 updatelanguage(input {id \\$languageid, fields \\$founderid}) 8 { 9 language{ 10 objectid 11 } 12 } 13 } 14 '''; 15 final variable={ 16 "languageid" rowobjectid, 17 "founderid" { 18 "founder" { 19 "remove" pointersid 20 } 21 } 22 }; 23 graphqlconfiguration configuration = graphqlconfiguration(); 24 graphqlclient client = configuration clienttoquery(); 25 26 queryresult queryresult = await client query( 27 queryoptions(documentnode gql(removepointersquery), variables variable), 28 ); 29 return queryresult; 30 31 } agora você pode prosseguir para o seu painel do back4app e ver que a coluna do fundador da linha específica foi deletada 3 criando/adicionando e deletando dados de data hora se você se lembra, criamos uma classe ownership anteriormente em passo 1 e armazenamos alguns dados nela estes são os nomes das empresas que possuíam a linguagem de programação java então, primeiro vamos inserir as datas em que adquiriram a propriedade vamos prosseguir para databaseutils dart databaseutils dart e criar ou rolar para baixo até a função adddatetime() adddatetime() aqui escreveremos a lógica para adicionar o tipo de dado data hora à nossa classe inicialize string adddatetimequery string adddatetimequery e atribua a consulta para criar dados de data hora 1 string adddatetimequery= 2 ''' 3 mutation addtime(\\$rowid id!,\\$dateowned date!){ 4 updateownership(input {id \\$rowid, fields {date owned \\$dateowned}}) 5 { 6 ownership{ 7 objectid 8 } 9 } 10 } 11 '''; e a variável final variável final como 1 final variable={ 2 "rowid" rowobjectid, 3 "dateowned" datetime 4 }; agora inicialize o graphqlclient graphqlclient e passe a consulta através do queryoption() queryoption() é assim que sua função ficaria 1 future\<queryresult> adddatetime(string rowobjectid, string datetime) async{ 2 print('adddatetime'); 3 //code for add/update date time 4 string adddatetimequery= 5 ''' 6 mutation addtime(\\$rowid id!,\\$dateowned date!){ 7 updateownership(input {id \\$rowid, fields {date owned \\$dateowned}}) 8 { 9 ownership{ 10 objectid 11 } 12 } 13 } 14 '''; 15 final variable={ 16 "rowid" rowobjectid, 17 "dateowned" datetime 18 }; 19 graphqlconfiguration configuration = graphqlconfiguration(); 20 graphqlclient client = configuration clienttoquery(); 21 queryresult queryresult = await client query( 22 queryoptions(documentnode gql(adddatetimequery), variables variable), 23 ); 24 return queryresult; 25 } agora hot restart o aplicativo e anote o objectid da linha contendo sun microsystems na coluna name pressione o botão add date time agora insira o objectid anotado no primeiro campo de texto e “02 24 1982” como mm dd yyyy no dia em que o java foi publicado e pressione o botão done prossiga para o seu backend do back4app e você veria a data na forma de 24 fev 1982 às 00 00 00 utc o que significa que ele identificou o tipo de dado como tipo de dado data hora da mesma forma, você poderia adicionar “01 27 2010” para o date owned para oracle 4 adicionando/atualizando dados do geopointer vamos adicionar dados do geopointer para localizar as sedes das empresas da tabela de propriedade prossiga para database utils dart database utils dart e role para baixo até a addgeopointers() addgeopointers() função agora inicialize string addgeopointers string addgeopointers e atribua a consulta respectiva 1 string addgeopointers= 2 ''' 3 mutation addgeopointer(\\$objectid id!,\\$latitude float!,\\$longitude float!){ 4 updateownership(input {id \\$objectid, fields { headquarters {latitude \\$latitude, longitude \\$longitude}}}) 5 { 6 ownership{ 7 objectid 8 } 9 } 10 } 11 '''; e variável final variável final como 1 final variable={ 2 "objectid" rowobjectid, 3 "latitude" double parse(latitude), 4 "longitude" double parse(longitude), 5 }; como latitude latitude e longitude longitude são valores duplos, precisamos convertê los de string para double antes de enviá los inicialize o grapqlclient grapqlclient e passe a consulta com queryoption() queryoption() é assim que sua addgeopointers() addgeopointers() função deve se parecer 1 future\<queryresult> addgeopointers(string rowobjectid, string latitude, string longitude) async{ 2 print('add geopointers'); 3 //code for add/update geopointers 4 string addgeopointers= 5 ''' 6 mutation addgeopointer(\\$objectid id!,\\$latitude float!,\\$longitude float!){ 7 updateownership(input {id \\$objectid, fields { headquarters {latitude \\$latitude, longitude \\$longitude}}}) 8 { 9 ownership{ 10 objectid 11 } 12 } 13 } 14 '''; 15 final variable={ 16 "objectid" rowobjectid, 17 "latitude" double parse(latitude), 18 "longitude" double parse(longitude), 19 }; 20 graphqlconfiguration configuration = graphqlconfiguration(); 21 graphqlclient client = configuration clienttoquery(); 22 queryresult queryresult = await client query( 23 queryoptions(documentnode gql(addgeopointers), variables variable), 24 ); 25 return queryresult; 26 } reinicie seu aplicativo e selecione o adicionar geopointers botão insira 37 35 37 35 na primeira caixa de texto e 121 95 121 95 na segunda caixa de texto insira o objectid da linha com sun microsystems como nome e pressione concluído agora prossiga para seu back4app backend e você verá (37 35, 121 95) que são as coordenadas da sede e afirma que identifica como geopointers 5 adicionando/atualizando e deletando relação nos pointers, podemos apontar apenas para uma linha, mas com a ajuda de relações podemos fazer conexão com várias linhas então vamos fazer a relação da nossa tabela de linguagem com essas duas linhas para propriedade da linguagem java adicionando/atualizando relação prossiga para database utils dart database utils dart arquivo e prossiga para addrelation() addrelation() função para escrever a lógica inicialize string addrelationquery string addrelationquery e atribua a consulta para a relação da seguinte forma 1 string addrelationquery= 2 ''' 3 mutation addrelation(\\$objectid id!, \\$relationid ownershiprelationinput){ 4 updatelanguage(input {id \\$objectid, fields {ownership \\$relationid}}) 5 { 6 language{ 7 objectid 8 } 9 } 10 } 11 '''; e a variável final variável final seria 1 final variable= { 2 "objectid" objectid, 3 "relationid" relationid 4 }; então, após inicializar o graphqlclient graphqlclient e passar a consulta como antes, é assim que seu database utils dart database utils dart ficaria 1 future\<queryresult> addrelation(string rowobjectid, string relationid) async{ 2 //code for add/update relation 3 print('addrelation'); 4 string addrelationquery= 5 ''' 6 mutation addrelation(\\$objectid id!, \\$relationid ownershiprelationinput){ 7 updatelanguage(input {id \\$objectid, fields {ownership \\$relationid}}) 8 { 9 language{ 10 objectid 11 } 12 } 13 } 14 '''; 15 final variable= { 16 "objectid" rowobjectid, 17 "relationid" { 18 "add" relationid 19 } 20 }; 21 graphqlconfiguration configuration = graphqlconfiguration(); 22 graphqlclient client = configuration clienttoquery(); 23 queryresult queryresult = await client query( 24 queryoptions(documentnode gql(addrelationquery), variables variable), 25 ); 26 print(queryresult); 27 return queryresult; 28 } sucesso seu aplicativo finalmente armazenou dados relacionais, de data/hora e geopointers no back4app! conclusão neste guia, aprendemos como armazenar dados relacionais no back4app usando graphql a partir de um projeto de aplicativo flutter também trabalhamos com outras mutações graphql como geopointers e data/hora, criando, atualizando e excluindo dados no próximo tutorial, vamos nos aprofundar em consultas para nosso aplicativo flutter este guia foi escrito por asim junain, da hybrowlabs https //www back4app com/partners/software development company