Flutter
GraphQL
FlutterでGraphQLを使ったプロジェクト構築ガイド【ソースコード付き】
24 分
ソースコード付きのflutter graphqlプロジェクトをダウンロードしてback4appを使用し始める イントロダクション このチュートリアルでは、graphqlを通じてback4appバックエンドからデータを解析するアプリケーションを構築します。ご存知のように、graphqlはapiのためのオープンソースのデータクエリおよび操作言語であり、既存のデータでクエリを満たすためのランタイムです。back4appは、開発者が迅速に拡張可能でスケーラブルなモバイルおよびwebアプリケーションを構築するのを支援する低コードのバックエンドサービス(オープンソースのparseプラットフォームに基づいています)です。 目標 主な目標は、プログラミング言語のリストとその保存形式を表示するシンプルなアプリを構築することです。 この記事の最後には、あなたができるようになることを期待しています graphqlを使用してback4appでapiコールを行う; graphql apiからデータを取得する; flutterアプリでデータを取得する。 前提条件 このチュートリアルを完了するには、次のものが必要です android studioやflutterのようなflutterコードを書くためのide。ただし、このチュートリアルではandroid studioを使用します。 ここで作成できるback4appアカウント back4app graphql flutter https //pub dev/packages/graphql flutter 1 githubからandroid studioにプロジェクトをクローンする 次に行く githubリポジトリ https //github com/templates back4app/flutter graphql , zipファイルをダウンロードし、解凍して、flutter ideで開きます。 このステップを完了するには、zipファイル内のフォルダーをデスクトップにドラッグし、android studioを開いて「既存のandroid studioプロジェクトを開く」をクリックします。プロジェクトディレクトリは通常「 c \users\username\desktop\back4app graphql starting code 」です。 しかし、これはユーザーによって異なる場合があります。 プロジェクトを開いて、「 lib\main dart lib\main dart 」ファイルに移動します。そこには多くのエラーが表示されますが、心配しないでください。「 依存関係を取得 」をすべて押すと、すべてのエラーが消えます。消えない場合は、「 依存関係をアップグレード 」を押してください。 あなたの main dart main dart のコードはこのように見えるはずです。 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 } アプリを今すぐ実行すると、エミュレーター/デバイスに「 ‘データをgraphqlで解析する’ 」というタイトルの空の画面だけが表示されます。 私たちは main dart main dart ファイルに取り組み、重要な値は consonents dart consonents dart に保存されており、そこから直接使用できます。アプリでgraphqlを使用するために、 graphql flutter graphql flutter 依存関係が必要です。 「 graphql flutter graphql flutter 」はflutter用の最も人気のあるgraphqlクライアントです。これにより、私たちはコード内で直接 graphql クエリを使用できます。私たちに提供されるのは graphqlclient graphqlclient , graphqlprovider graphqlprovider などの多くの便利なウィジェットで、graphqlの助けを借りてデータベースから直接データを解析するのに役立ちます。 streambuilder streambuilder を使用することさえありません。このパッケージは、以下を含む多くの機能を提供します サブスクリプション メモリキャッシュ オフラインキャッシュの同期 楽観的結果 graphqlファイルのアップロード 次のコードを pubspec yaml pubspec yaml ファイルに書くことでインポートできます 詳細については graphql flutter graphql flutter を参照してください graphql flutter ドキュメント すべての依存関係はすでにプリインストールされており、次のステップに進む準備が整いました。 2 back4appでのバックエンドの作成 back4appのウェブサイトでサインアップした後、次のステップに進んで新しいアプリを作成できます。「 ‘新しいアプリを作成’ 」をクリックします。プロジェクト名と同じ名前を付けます。ここでは「 ‘back4app graphql’ 」です。 左側の「 サーバー設定 」までスクロールし、「 設定 」の「parse serverカードを管理」を選択し、リストから「 ‘3 10 0 parse server 3 10 0’ 」のオプションを選択します。下の保存ボタンを押して、保存されるまで待ちます。 今度は左側の「 コア 」に戻り、「 apiコンソール 」を選択し、「 graphqlコンソール 」を選択します。 これは、graphqlクエリ/ミューテーションコードを書いてテストできるウィンドウです。次のステップに進みましょう。 3 graphqlを通じてデータを作成および取得する さて、graphql apiコンソールを使用してback4appでgraphql apiをテストしてみましょう。まず、左側のコードボックスに次のクエリを貼り付けてください 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 上記のコードは、「language」という名前のクラスを作成します。この新しいクラスにいくつかの行を追加しましょう 1 mutation createobject{ 2 createlanguage(input {fields {name "python", saveformat " py"}}){ 3 language{ 4 name, 5 saveformat 6 } 7 } 8 } 操作が成功すると、graphql playgroundの右側のコードボックスにこのメッセージが表示されます 1 { 2 "data" { 3 "createlanguage" { 4 "language" { 5 "name" "python", 6 "saveformat" " py" 7 } 8 } 9 } 10 } ミューテーションは、クラスを作成したり変更を加えたりするために使用されます。上記のミューテーションを実行することで、データフィールドを持つlanguageという新しいクラスを作成します name “python” saveformat “ py” プロセスを繰り返し、同じクラスに2つのオブジェクトを作成します name “c” と saveformat “ c” name “java” と saveformat “ java”。 これに対するミューテーションは次のようになります 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 } さて、私たちのクラス languages のすべてのデータを見てみましょう。データを読み取るために、私たちは query を使用します。さあ、以下のコマンドを入力してください。 1 query findlanguages{ 2 languages{ 3 count, 4 edges{ 5 node{ 6 name, 7 saveformat 8 } 9 } 10 } 11 } 「 query findlanguage query findlanguage 」はあなたのクエリコマンドの名前に過ぎず、他の名前を付けることもできます。私たちは find(classname "") find(classname "") コマンドを使用して、特定のクラスのすべての要素を見つけます。 count count はクラス内の要素の数を返し、すべての要素は result result オブジェクト内に表示されます。 上記のクエリはこれを返します 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 } 他のすべてのクエリは以下のリンクで見ることができます graphqlクエリ back4app https //blog back4app com/graphql on parse/ では、次のステップに進みましょう。 4 アプリにgraphqlを設定する アプリのコーディングを始めましょう。その前に、あなたの lib\consonents dart lib\consonents dart ファイルでいくつかのことを行う必要があります graphqlウィンドウの上部にある履歴ボタンの隣にあるgraphqlリンクをコピーし、kurl文字列データ型として貼り付けます。 ページの下部に移動し、httpヘッダーからコードをコピーします。コロン( )の右側のコードのみをコピーし、それぞれの名前とともに lib\consonents dart lib\consonents dart ファイルに貼り付けます ファイルには次のコードが含まれている必要があります 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 次に、 main dart main dart ファイルに移動し、myapp stateless widgetに進んで、次のコードを 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 は flutter graphql dart からのもので、2つのパラメータを持つhttplink()ウィジェットを取ります。最初はback4appのgraphql api urlです。2つ目はback4app apiで認証するために必要なヘッダーです。このセクションの後にgraphqlクライアントコードを含める必要があります(何であるかを説明し)、以下のコードをコピーしてhttplinkセクションの下に貼り付けます 1 valuenotifier\<graphqlclient> client = valuenotifier( 2 graphqlclient( 3 cache optimisticcache(dataidfromobject typenamedataidfromobject), 4 link httplink, 5 ), 6 ); 今、私たちはgraphqlclientにリンクとキャッシュメソッドを提供しました。これはvaluenotifierを通じて行い、clientと名付けました。materialappの子であるmyhomepage()ウィジェットをgraphqlproviderでラップし、myhomepage()をそのclientとして渡しましょう。graphqlproviderの中にclientという別のパラメータを追加し、client(valuenotifierの名前)を渡します。これがあなたの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 } apiを呼び出してデータを取得しましょう 5 api呼び出しの作成 今、私たちはmyhomepagestateに取り組みます。まず、‘query’という名前のstringデータ型を初期化し、languageクラスからすべてのデータを見つけるためのクエリ文をそれに割り当て/渡します。クエリは複数行のため、トリプルクオートでクエリを渡します。以下のようになります 1 string query=''' 2 query findlanguages{ 3 languages{ 4 count, 5 edges{ 6 node{ 7 name, 8 saveformat 9 } 10 } 11 } 12 } 13 '''; 次に、scaffoldのbodyパラメータ内のquery()ウィジェットに移動します。そこには2つのプロパティがあります オプション ビルダー そして、両方にnullを渡します。これがあなたのビルドメソッドの見た目になります 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 } この query() query() ウィジェットは、graphqlのクエリを書くのに役立ち、データを読み取って取得するのに役立ちます。オプションに文字列として取得したクエリ文を渡し、ビルダーパラメータでウィジェットを構築します。 したがって、次のようにオプションにqueryoptions()ウィジェットを渡します 1 options queryoptions( 2 documentnode gql(query), 3 ), 4 クエリはqueryoptionsのdocumentnodeパラメータを通じて渡されます。では、builderパラメータの助けを借りて構築してみましょう。builderメソッドは、次の3つのパラメータを持つ関数を受け入れます。 queryresult result; refetch refetch; fetchmore fetchmore 今のところ、私たちが心配する必要があるのはqueryresultだけで、これはクエリの結果を提供し、私たちは次のようにデータにアクセスできます。 result data result data それでは、以下のコードを書いてみましょう 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 }, 上記のコードではデータにアクセスしています。データがない場合は、「 ‘loading…’ 」と表示されるテキストウィジェットを返します。そうでなければ、「 ‘success’ 」と表示されるtext()ウィジェットを返します。 あなたの myhomepage myhomepage クラスは 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 } 今、アプリを起動し、再起動後に数秒待ってください。画面に ‘success’ が表示されたら、 おめでとうございます!接続が確立され、apiが呼び出されました。 6 apiからデータを取得して表示する textウィジェットを返す代わりに、元のデータを持つ listview\ builder() ウィジェットを返します。次のコードを返すのではなく書いてください text('success') text('success') 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 ); 今、back4appのapiコンソールでfindメソッドを入力したgraphql結果画面に戻ると、結果は次のようになります 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 } したがって、上記のコードから「python」の位置は “data” > “ languages” > “count” > “edges” > “node” > “name” また、nameはedgesの角括弧‘\[]’の中にあり、これはedgesリスト/配列の最初の要素であることを示しています。 したがって、私たちはこの場所に入って“python”を取得する必要があります。他のすべてについても同様です。私たちが result data result data , と書くと、私たちは “data” の場所に入ります。したがって、他の場所を指定するために \["location name"] \["location name"] を追加します。したがって、“python”の場所は result data\["languages"]\["edges"]\[0]\["node"]\["name"] result data\["languages"]\["edges"]\[0]\["node"]\["name"] になります。 使用する場合 listview listview , 2つのパラメータを取ります。 itemcount itemcount , これはapi呼び出しの要素の数を示し、 itembuilder itembuilder , これは (buildcontext context, int index) (buildcontext context, int index) というパラメータを持つ関数を取ります。そして、データを表示するためのウィジェットのリストを返します。ここでは、listtileのリストを使用してデータを表示します 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 ); 置き換えるとき text('success') text('success') 上記の listview\ builder() ウィジェットでは、最初にitemcountを渡し、結果のリスト内の要素の数を渡しますので、もうそれについて心配する必要はありません。itembuilderでは、 "name" "name" のリストを返します。 "languages" "languages" クラスの "saveformat" "saveformat" をトレーリングに入れます。結果の後に任意の数の代わりにインデックスを使用したことに注意してください。これがitemcountが処理したことです。 これがあなたの main dart main dart の見た目になるはずです 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 } そして私たちの最終アプリ画面 結論 これで、back4app上でデータを保存および取得できるgraphql apiに接続されたflutterアプリが完成しました。 jsonデータを別々にエンコードまたはデコードする必要がなかったため、少ない行数のコードで作業が簡単かつ迅速に行えました。 素晴らしい一日を!