Flutter
GraphQL
Descarga y Configuración de un Proyecto Flutter con GraphQL
28 min
descarga un proyecto de flutter graphql con código fuente y comienza a usar back4app introducción en este tutorial, vamos a construir una aplicación que analizará datos del backend de back4app a través de graphql como sabrás, graphql es un lenguaje de consulta y manipulación de datos de código abierto para apis, y un entorno de ejecución para cumplir consultas con datos existentes back4app es un backend de bajo código como servicio (basado en la plataforma open source parse) que ayuda a los desarrolladores a construir aplicaciones móviles y web extensibles y escalables a un ritmo rápido objetivos el objetivo principal es construir una aplicación simple que mostrará una lista de lenguajes de programación y su formato de tipo de guardado al final de este artículo, esperamos que puedas hacer una llamada a la api en back4app usando graphql; obtener los datos de la api de graphql; recuperar datos en tu aplicación flutter requisitos previos para completar este tutorial, necesitarás un ide para escribir código flutter como android studio o flutter sin embargo, utilizaremos android studio para este tutorial una cuenta de back4app que se puede crear aquí back4app graphql flutter https //pub dev/packages/graphql flutter 1 clonar el proyecto de github a android studio ve al repositorio de github https //github com/templates back4app/flutter graphql , y descarga el archivo zip, extráelo y ábrelo en tu ide de flutter para completar este paso, arrastra la carpeta dentro del archivo zip a tu escritorio, abre android studio y luego haz clic en abrir proyecto existente de android studio el directorio del proyecto sería generalmente ‘ c \users\username\desktop\back4app graphql starting code ’ pero esto puede ser diferente para diferentes usuarios abre el proyecto y ve al lib\main dart lib\main dart archivo verás muchos errores allí, no te preocupes, solo presiona ‘ obtener dependencias ’ y todos los errores desaparecerán si no lo hacen, entonces solo presiona ‘ actualizar dependencias ’ el código en tu main dart main dart debería verse así 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 } si abres la aplicación ahora, solo verías una pantalla vacía en tu emulador/dispositivo con solo una appbar titulada ‘parsing data using graphql’ trabajaremos en el archivo main dart main dart y nuestros valores importantes están almacenados en consonents dart consonents dart y podemos usarlo directamente desde allí requeriremos la dependencia graphql flutter graphql flutter para usar graphql en nuestra aplicación el graphql flutter graphql flutter es el cliente graphql más popular para flutter nos ayuda a usar graphql consultas directamente en nuestro código nos proporciona graphqlclient graphqlclient , graphqlprovider graphqlprovider y muchos otros widgets útiles que nos ayudan a analizar datos de nuestra base de datos directamente con la ayuda de graphql sin siquiera usar streambuilder streambuilder el paquete nos proporciona muchas características, incluyendo suscripciones caché en memoria sincronización de caché offline resultados optimistas subidas de archivos graphql puedes importarlo escribiendo el siguiente código en el archivo pubspec yaml pubspec yaml vea más sobre graphql flutter graphql flutter en documentación de graphql flutter todas las dependencias ya están preinstaladas y puedes proceder al siguiente paso ahora 2 creando backend en back4app después de haberte registrado en back4app https //www back4app com/ sitio web, puedes proceder al siguiente paso y crear una nueva aplicación haz clic en ‘construir nueva app’ dale el mismo nombre que el de tu proyecto, que aquí es ‘back4app graphql’ ahora desplázate hacia abajo hasta configuración del servidor a la izquierda y selecciona configuraciones administrar la tarjeta del servidor parse, luego selecciona la opción ‘3 10 0 parse server 3 10 0’ de la lista ahora presiona el botón de guardar abajo y espera hasta que se guarde ahora regresa a núcleo (a la izquierda), selecciona la consola api , y selecciona consola graphql de ella esta es la ventana donde puedes escribir y probar tu código de consultas/mutaciones de graphql procedamos al siguiente paso 3 creando y obteniendo datos a través de graphql ahora, probemos la api de graphql en back4app usando la consola de api de graphql primero, pega la siguiente consulta en el cuadro de código de la izquierda 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 el código anterior creará una clase llamada “language” vamos a poblar esta nueva clase con algunas filas 1 mutation createobject{ 2 createlanguage(input {fields {name "python", saveformat " py"}}){ 3 language{ 4 name, 5 saveformat 6 } 7 } 8 } si tu operación es exitosa, verás este mensaje en el cuadro de código a la derecha en graphql playground 1 { 2 "data" { 3 "createlanguage" { 4 "language" { 5 "name" "python", 6 "saveformat" " py" 7 } 8 } 9 } 10 } las mutaciones se utilizan para crear o hacer cambios en una clase al ejecutar la mutación anterior, crearemos una nueva clase llamada language con los campos de datos nombre “python” formatodeguardado “ py” repite el proceso y crea dos objetos más en la misma clase para nombre “c” y formatodeguardado “ c” nombre “java” y formatodeguardado “ java” la mutación para esto será así 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 } ahora veamos todos los datos en nuestra clase languages para leer datos usamos query así que adelante y escribe el siguiente comando 1 query findlanguages{ 2 languages{ 3 count, 4 edges{ 5 node{ 6 name, 7 saveformat 8 } 9 } 10 } 11 } en query findlanguage query findlanguage ‘findlanguage’ es solo un nombre para tu comando de consulta y podrías incluso nombrarlo de cualquier otra manera usamos el find(classname "") find(classname "") comando para encontrar todos los elementos de la clase específica count count , devuelve el número de elementos en la clase y todos los elementos se muestran dentro del result result objeto la consulta anterior va a devolver esto 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 } puedes ver todas las otras consultas en el siguiente enlace consultas graphql back4app https //blog back4app com/graphql on parse/ ahora, procedamos al siguiente paso 4 configurando graphql en nuestra app comencemos a codificar nuestra app antes de esto, debes hacer algunas cosas en tu lib\consonents dart lib\consonents dart archivo copia el enlace graphql que está al lado del botón de historial en la parte superior de la ventana de graphql, y pégalo como un tipo de dato string kurl ahora desplázate hacia la parte inferior de la página y copia los códigos de los encabezados http, copia solo los códigos a la derecha de los dos puntos( ) y pégalos con sus respectivos nombres en el lib\consonents dart lib\consonents dart archivo el archivo debe tener el siguiente 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 ahora muévete al main dart main dart archivo y dirígete al widget stateless myapp y agrega el siguiente código justo encima del 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 es de flutter graphql dart y toma el widget httplink() con dos parámetros el primero es la url de la api graphql en back4app el segundo son los encabezados necesarios para autenticar en la api de back4app después de esta sección, necesitas incluir el código del cliente graphql (explicar qué es), copia el código a continuación y luego pégalo debajo de la sección httplink 1 valuenotifier\<graphqlclient> client = valuenotifier( 2 graphqlclient( 3 cache optimisticcache(dataidfromobject typenamedataidfromobject), 4 link httplink, 5 ), 6 ); ahora hemos proporcionado el método de enlace y caché a nuestro graphqlclient hemos hecho esto a través de nuestro valuenotifier y lo hemos nombrado como client vamos a envolver el widget myhomepage() que es un hijo de materialapp con graphqlprovider y pasar myhomepage() como su cliente agrega otro parámetro dentro de graphqlprovider llamado client y pasa client (nombre de nuestro valuenotifier) en él así es como debería verse ahora tu clase myapp 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 } llamemos a la api y obtengamos los datos 5 haciendo una llamada a la api ahora trabajaremos en el myhomepagestate vamos a comenzar inicializando un tipo de dato string llamado ‘query’ y asignar/pasar la declaración de consulta para encontrar todos los datos de nuestra clase language a él dado que la consulta es de varias líneas, pasaremos la consulta entre comillas triples así es como se ve 1 string query=''' 2 query findlanguages{ 3 languages{ 4 count, 5 edges{ 6 node{ 7 name, 8 saveformat 9 } 10 } 11 } 12 } 13 '''; ahora ve al widget query(), dentro del parámetro body del scaffold que tiene dos propiedades opciones constructor y luego pasa null para ambos así es como se vería tu método de construcción 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 } el query() query() widget nos ayuda a escribir consultas para graphql y nos ayudará a leer y obtener datos pasaremos la declaración de consulta que hemos tomado como una cadena en las opciones y construiremos el widget con el parámetro builder así que pasa el widget queryoptions() en opciones de la siguiente manera 1 options queryoptions( 2 documentnode gql(query), 3 ), 4 la consulta se pasa a través del parámetro documentnode en queryoptions ahora construyamos con la ayuda del parámetro builder el método builder acepta una función con tres parámetros, a saber, queryresult result; refetch refetch; fetchmore fetchmore en este momento, solo necesitamos preocuparnos por el queryresult que nos da el resultado de nuestra consulta y podemos acceder a los datos a través de result data result data así que codifiquemos lo siguiente a continuación 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 }, en el código anterior estamos accediendo a los datos si no hay datos, devolvemos un widget de texto que dice ‘cargando…’ de lo contrario, devolveremos un widget text() que dice ‘éxito’ así es como debería verse tu myhomepage myhomepage clase en main dart main dart 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 } ahora, inicia la aplicación y espera unos segundos después de que se reinicie si ves ‘éxito’ en la pantalla, entonces ¡felicidades! has establecido tu conexión y llamado a la api 6 obteniendo y mostrando datos de la api en lugar de devolver el widget text, devolveremos el listview\ builder() widget con los datos originales escribe el siguiente código en lugar de return text('éxito') text('éxito') 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 ); ahora, si miras de nuevo a tu pantalla de resultados de graphql en la consola de api de back4app donde escribimos nuestro método find, los resultados fueron los siguientes 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 } así que, a partir del código anterior, la ubicación de “python” fue “data” > “ languages” > “count” > “edges” > “node” > “name” también nota que el nombre está dentro de corchetes cuadrados ‘\[]’ de edges, lo que simboliza que es el primer elemento de la lista/array de edges así que necesitamos entrar en esta ubicación para obtener “python” y lo mismo para todo lo demás cuando escribimos result data result data , entramos en la “data” ubicación así que para dar las otras ubicaciones añadimos \["location name"] \["location name"] a ello así que la ubicación de “python” será result data\["languages"]\["edges"]\[0]\["node"]\["name"] result data\["languages"]\["edges"]\[0]\["node"]\["name"] al usar listview listview , toma dos parámetros, itemcount itemcount , que indica el número de elementos en la llamada a la api, itembuilder itembuilder , que toma una función con parámetros (buildcontext context, int index) (buildcontext context, int index) y devuelve una lista de widgets en la que mostraremos los datos aquí, usaremos una lista de listtile para mostrar los datos 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 ); cuando reemplazamos text('success') text('success') con el anterior listview\ builder() widget, primero pasamos el itemcount donde pasamos el número de elementos en la lista de resultados y así no necesitamos preocuparnos más por eso en itembuilder estamos devolviendo una lista de listtiles que tendrá el "name" "name" de la "languages" "languages" clase y en "saveformat" "saveformat" en el trailing nota que usamos el índice en lugar de cualquier número después de resultado, esto es lo que el itemcount se encargó así es como tu main dart main dart debería verse ahora 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 } y nuestra pantalla final de la aplicación conclusión ahora tienes una aplicación flutter conectada a una api graphql que puede almacenar y recuperar datos en back4app no fue necesario codificar o decodificar los datos json por separado, lo que hace que nuestro trabajo sea más fácil y rápido utilizando pocas líneas de código ¡que tengas un gran día!