Flutter
GraphQL
Integración de datos relacionales con Flutter y GraphQL
22 min
almacenar datos relacionales usando graphql introducción en los últimos dos tutoriales hemos realizado consultas y mutaciones de graphql en una base de datos de back4app desde nuestro proyecto de flutter estamos usando graphql flutter https //pub dev/packages/graphql flutter/install como nuestro cliente de graphql ya que este es un proyecto muy robusto y ampliamente utilizado para esos tutoriales hemos utilizado un modelo de datos muy simple con los tipos más comunes para nuestras clases back4app es una plataforma flexible que te permite crear, almacenar y consultar datos relacionales en este tutorial vamos a profundizar en esta capacidad mostrándote cómo usar relaciones y punteros al guardar y consultar datos relacionales en el backend de back4app además, vamos a explorar otros tipos de datos que back4app ofrece como geopointer y datetime objetivos al final de este artículo podrás crear/actualizar y eliminar datos relacionales (usando punteros y relaciones) crear/actualizar geopunteros crear/actualizar fecha hora requisitos previos para completar este tutorial, necesitarás asegúrate de haber leído las dos guías anteriores comenzar desde la plantilla y mutación graphql descarga el archivo del proyecto desde github repo que incluye el código anterior así como la nueva gui que necesitarás abre el proyecto descargado en un ide de flutter como vs code o android studio cuenta de back4app que se puede crear aquí conecta tu tutorial a back4app según los tutoriales anteriores comenzar desde la plantilla 1 configurando el back end en nuestro proyecto anterior https //www back4app com/docs/flutter/flutter crud app example nuestro modelo de datos era muy simple con solo una clase lenguaje ahora vamos a hacerlo más complejo añadiendo 2 nuevas clases y relacionándolas con lenguaje fundador con formato nombre de la columna descripción nombre nombre del fundador del idioma nombre de la columna descripción nombre nombre de la empresa propietaria fecha propiedad fecha en que la empresa adquirió la propiedad sede ubicación de la sede de la empresa crearemos una relación uno a uno entre la clase language y la clase founder utilizando parse pointers, que indicará el fundador del idioma específico luego, crearemos una relación uno a muchos entre la clase language y la clase ownership utilizando parse relations que indicará qué organización/empresa poseía el idioma, su sede y la fecha en que adquirieron la propiedad del idioma el modelo de datos se verá así antes de pasar a nuestra aplicación, creemos las clases y los datos en nuestro back end que necesitaremos ve a tu aplicación back4app y luego dirígete al graphql playground usando la mutación a continuación, crea una clase founder donde almacenaremos los nombres de los fundadores de los idiomas 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 } ahora vamos a poblar nuestra clase con algunos nombres de fundadores en los siguientes pasos utilizaremos estos datos para crear nuevos lenguajes apuntando a la clase de fundador usa la mutación a continuación en back4app graphql playground para crear tus fundadores 1 mutation createobject{ 2 createfounder(input {fields {name "james gosling"}}){ 3 founder{ 4 id 5 name 6 } 7 } 8 } aquí hemos ingresado el nombre del fundador del lenguaje de programación java puedes hacer lo mismo para otros también, pero por ahora esto es suficiente para nuestra guía vamos a crear la clase ownership donde almacenaremos la propiedad del lenguaje, la fecha de fundación (fecha hora) y la ubicación de la sede del propietario (geopointer) más tarde crearemos la relación entre la clase de lenguaje y propiedad procede ejecutando el código a continuación para crear la clase 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 } ahora completa la clase propiedad usando las siguientes mutaciones 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 } ahora actualiza la página, ve a propiedad propiedad clase en el navegador de base de datos selecciona el agregar nueva columna desde la esquina superior derecha selecciona geopoint del primer desplegable y nómbralo sede en el segundo campo de texto y deja todo como está y presiona el agregar columna botón luego ve a tu idioma idioma clase en el navegador de base de datos vamos a agregar las relaciones a propiedad propiedad y fundador fundador clases haz clic en agregar nueva columna y luego elige el tipo de dato puntero y la clase objetivo fundador fundador dale a la columna el mismo nombre fundador luego presiona agregar columna ahora repite ese proceso agregando una nueva columna llamada propiedad usando el tipo de dato relación y seleccionando la clase propiedad propiedad ahora tienes tu modelo de datos listo para usar en tu aplicación flutter y para comenzar a guardar y actualizar los datos 2 creando/añadiendo y eliminando punteros ahora necesitas descargar el código base del proyecto desde nuestro repositorio de github https //github com/templates back4app/flutter graphql/tree/complex mutations abierto en tu ide para conectar tu proyecto a back4app, ve al graphql playground y copia las claves y la url de la api como se muestra en la imagen a continuación ahora pégalos en el constants dart constants dart y ejecuta tu proyecto ejecuta la aplicación en tu emulador ve al m botón flotante en la parte inferior eso nos llevará a la página donde realizamos mutaciones simples aquí encontrarás un botón de acción flotante extra cm ese es el botón que vamos a usar para realizar nuestras mutaciones complejas de graphql haz clic en el cm botón, y verás otros cuatro botones, uno para cada operación que vamos a realizar en esta guía ahora abre el databaseutils dart databaseutils dart archivo y desplázate hacia abajo hasta el addpointers() addpointers() método aquí añadiremos la lógica para añadir punteros vamos a señalar a james gosling como un fundador del lenguaje java así que primero necesitarás proceder a tu backend de back4app y copiar ambos objectid objectid actualizando/creando puntero a datos proceda a nuestra aplicación dentro del databaseutils dart databaseutils dart y dentro del addpointers() addpointers() método inicialice un string addpointerquery string addpointerquery donde asignaremos la consulta graphql para agregar pointers de la siguiente manera 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 '''; y inicialice variable final variable final para asignar variables, observe que estamos tomando el rowobjectid rowobjectid y pointersid pointersid como parámetros donde rowobjectid rowobjectid el id del objeto de la fila desde donde apuntaremos pointersid pointersid el id del objeto a la fila que será apuntada así que declare variable variable como 1 final variable={ 2 "userid" rowobjectid, 3 "founderid" { 4 "founder" { 5 "link" pointersid 6 } 7 } 8 }; ahora, como en la última guía, inicializaremos el graphqlclient graphqlclient y enviaremos la consulta con la ayuda de queryoptions() queryoptions() y devolveremos su instancia con 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; así es como debería verse tu addpointers() addpointers() método 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 } reinicia tu aplicación ahora, ve al cm botón en la página de mutación y luego presiona el botón de establecer agregar pointers aquí ingresa el objectid objectid de la fila donde se necesita agregar el puntero en el primer campo de texto y objectid objectid de la fila a la que apuntará en el segundo campo de texto y luego presiona hecho ahora verifica tu panel de control y deberías poder ver una relación bajo la fundador columna podrías hacer clic en él donde te llevaría a la fila que apunta a la fundador clase eliminando el puntero a los datos ahora proceda al método deletepointers() deletepointers() donde escribiremos la lógica para eliminar relaciones para eliminar relaciones, solo tiene que hacer pequeños cambios en la consulta anterior, es decir, en las variables solo cambie el "link" "link" por "remove" "remove" así que después de inicializar la variable final la variable final sería 1 final variable={ 2 "languageid" rowobjectid, 3 "founderid" { 4 "founder" { 5 "remove" pointersid 6 } 7 } 8 }; todo lo demás se verá exactamente igual que el addpointers() addpointers() así que su deletepointers() deletepointers() método se ve así 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 } ahora puedes proceder a tu panel de back4app y ver que la columna de fundador de la fila específica fue eliminada 3 creación/adición y eliminación de datos de fecha hora si recuerdas, hemos creado una clase ownership anteriormente en paso 1 y almacenado algunos datos en ella estos son los nombres de las empresas que poseían el lenguaje de programación java así que primero ingresaremos las fechas en que adquirieron la propiedad procedamos a databaseutils dart databaseutils dart y crear o desplazarnos hacia abajo hasta la función adddatetime() adddatetime() aquí escribiremos la lógica para agregar el tipo de dato de fecha hora a nuestra clase inicializa string adddatetimequery string adddatetimequery y asígnale la consulta para crear datos de fecha 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 '''; y la variable final variable final como 1 final variable={ 2 "rowid" rowobjectid, 3 "dateowned" datetime 4 }; ahora inicializa el graphqlclient graphqlclient y pasa la consulta a través del queryoption() queryoption() así es como se vería tu función 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 } ahora hot restart la aplicación y anota el objectid de la fila que contiene sun microsystems en la columna name presiona el botón add date time ahora ingresa el objectid anotado en el primer campo de texto y “02 24 1982” como mm dd yyyy en el día en que java fue publicado y presiona el botón done procede a tu backend de back4app y verás la fecha en forma de 24 feb 1982 a las 00 00 00 utc lo que significa que ha identificado el tipo de dato como tipo de dato fecha hora de manera similar, podrías agregar “01 27 2010” para el date owned para oracle 4 agregar/actualizar datos de geopointer vamos a agregar datos de geopointer para localizar las sedes de las empresas de la propiedad tabla proceda al database utils dart database utils dart archivo y desplácese hacia abajo hasta la addgeopointers() addgeopointers() función ahora inicialice string addgeopointers string addgeopointers y asigne la 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 '''; y variable final variable final como 1 final variable={ 2 "objectid" rowobjectid, 3 "latitude" double parse(latitude), 4 "longitude" double parse(longitude), 5 }; dado que latitude latitude y longitude longitude son valores dobles, necesitamos convertirlos de string a double antes de enviarlos inicialice el grapqlclient grapqlclient y pase la consulta con queryoption() queryoption() así es como se vería su addgeopointers() addgeopointers() función 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 su aplicación y seleccione el agregar geopointers botón ingrese 37 35 37 35 en el primer cuadro de texto y 121 95 121 95 en el segundo cuadro de texto ingrese el objectid de la fila con sun microsystems como nombre y presione listo ahora proceda a su backend de back4app y verá (37 35, 121 95) que son las coordenadas de la sede y afirma que se identifica como geopointers 5 agregar/actualizar y eliminar relación en los punteros solo podemos apuntar a una fila, pero con la ayuda de relaciones podemos hacer conexiones a múltiples filas así que hagamos la relación de nuestra tabla de lenguaje a estas dos filas para propiedad del lenguaje java agregar/actualizar relación proceda a database utils dart database utils dart archivo y proceda a addrelation() addrelation() función para escribir la lógica inicialice string addrelationquery string addrelationquery y asigne la consulta para la relación de la siguiente manera 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 '''; y la variable final variable final sería 1 final variable= { 2 "objectid" objectid, 3 "relationid" relationid 4 }; así que después de inicializar el graphqlclient graphqlclient y pasar la consulta como antes, así es como se vería su database utils dart database utils dart 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 } éxito ¡tu aplicación finalmente ha almacenado datos relacionales, de fecha y hora y geopointers en back4app! conclusión en esta guía aprendimos cómo almacenar datos relacionales en back4app usando graphql desde un proyecto de aplicación flutter también trabajamos con otras mutaciones de graphql como geopointers y datetime, creando, actualizando y eliminando datos en el próximo tutorial profundizaremos en las consultas para nuestra aplicación flutter esta guía fue escrita por asim junain, de hybrowlabs https //www back4app com/partners/software development company