はじめに
Flutterを網羅的に学習するにあたってRoadmapを使って学習を進めることにしました。
この記事では、Flutter初学者やこれからFlutterを学習し始める方に向けて、APIの操作についてまとめています。
RoadmapはFlutterだけでなく、他の言語やスキルのロードマップも提供されており、何から学習して良いか分からないと悩んでいる方にとって有用なサイトになっています。
ぜひRoadmapを利用して学習してみてください。
Roadmapとは
簡潔に言えば、Roadmap.shは学習者にとってのガイドブックであり、学習の方向性を提供する学習ロードマップサイトです。
初心者から上級者まで、ステップバイステップでスキルを習得するための情報が提供されています。
学習の進め方が分かりやすく示されているだけでなく、個々の項目に参考資料やリソースへのリンクも提供されているので、学習者は目標を設定し、自分自身のペースで学習を進めることができます。
Working with APIs
FlutterロードマップWorking with APIsでは以下の4つのサイトが紹介されています。興味のある方はぜひお読みください。
- Using Google APIs: https://dart.dev/guides/google-apis
- How to work with APIs in Flutter?: https://www.youtube.com/watch?v=uVo7HDWDUEQ
- JSON and serialization: https://docs.flutter.dev/data-and-backend/serialization/json
- Using JSON: https://dart.dev/guides/json
APIとは
APIとは「Application Programming Interface」の略称です。
インターフェースとは、異なる2つのモノをつなぐという意味を持ちます。例えば、USBも「パソコン」と「周辺機器」をつなぐものですので、インターフェースの一つです。
つまり、APIとは、「アプリケーション、ソフトウェア」と「プログラム」をつなぐもの、という意味になります。
APIの使用用途
APIを使用することによって、ソフトウェアやアプリケーションなどの一部を外部に向けて公開することができるようになります。
例えば、異なるサービス間で認証機能を共有したり、片方のサービスからデータを取り込んで、取り込んだデータをもう片方のサービスで利用するなど使い方は多岐に渡ります。
では、APIを公開するとは、どういうことでしょうか?
簡単に言うと、ソフトウェアに外部とやりとりするための窓口を作り、外部との連携ができる状態にするということです。
何をして欲しいのかをAPIに要求(リクエスト)して、ルールに基づいて要求が書かれていれば、APIを提供するサービスやソフトウェアが処理をして、その結果を返して(レスポンス)くれます。
当たり前ですが、APIは決められた仕様以外のことはできません、APIの提供者が公開する段階でサービスの利用範囲を決めているので、決められたこと以外はできないようになっています。
もっと詳しく学びたい方は、わかりやすい記事があったので、以下のリンクからぜひ読んでみてください。
JSONとは
JSON(JavaScript Object Notation)は、軽量なデータ交換フォーマットで、人間にも機械にも読みやすい形式の記述方法のことです。JSONは属性-値ペアの集合で表現し、多くのプログラミング言語で扱えるため、データのやり取りに広く使われています。
JSON形式は以下のようにキー
と値
からデータが表現されます。
{
"A さん": {
"国語": "84 点",
"数学": "79 点",
},
"B さん": {
"国語": "89 点",
"数学": "83 点",
}
}
JSONは次のデータ型に対応しています。
-
文字列: 文字列はダブルクォーテーション(
“
)、バックスラッシュ(\
)以外の文字であればなんでも使用できます。 - 数値: 数値はダブルクォーテーションで囲みません。ダブルクォーテーションで囲むと文字列扱いになるので注意が必要です。
- null: nullは全て小文字で指定します。
- bool値: bool値(true or false)の指定も可能です。
-
オブジェクト: オブジェクトを使いたい場合は
{}
を使います。オブジェクトの中にオブジェクトを入れることもできます。これを「ネストする」と言います。 -
配列: 配列を使いたい場合は
[]
を使います。配列内の要素はカンマで区切ることで複数入力できます。
HTTPメソッド
GETメソッド
GETメソッドはサーバーからデータを取得するために使用されます。読み取り専用のメソッドなので、このメソッドを呼ぶことで、データが変更される恐れはありません。
POSTメソッド
POSTメソッドは新しいデータを作成するのに使用されます。POSTメソッドを実行することによって、データをサーバーに送信し、新しいリソースを作成することができます。新しく作成されるとID(新しいリソースのURI1)が割り当てられて、自動的に既存のAPIに関連付けられます。
PUTメソッド
PUTメソッドは、既存のリソースを更新するために使用されます。特定のリソースを更新する場合、更新しようとしている新しいリソースを含むリクエストを該当のURIに送信して、更新をかけます。
つまり、PUTではリソース全体を送信します。例えば、元あるデータが以下だとします。
{
"title": "sample title",
"content": "foobarbaz hoge fuga",
"author": "sample tarou"
}
上記のリソースがサーバーにあったとして、以下のデータをPUTメソッドで送信すると
{
"title": "new title"
}
以下のようにcontent
とauthor
は削除されます。リソース全体を送信して、全体が更新されるということです。
{
"title": "new title"
}
PATCHメソッド
PATCHメソッドは、既存のリソースを更新するために使用されます。PUTメソッドは全体を更新するのに対し、PATCHメソッドは部分更新をします。例えば、記事のタイトルだけを更新したり、記事の本文だけを更新したりなどです。
DELETEメソッド
DELETEメソッドは、URIで指定された特定のリソースを削除するために使用されます。
Flutter API実装
アプリケーション開発でAPI通信は避けては通れない分野になっています。ここではFlutterでAPIを通信を行う際、どういった手順で導入していくのかを解説していきます。
まずFlutterでAPI通信を行うには、http
パッケージという外部パッケージを活用します。
API通信をサポートするパッケージは他にもたくさんあるので、興味のある方はぜひ調べてみてください。
パッケージの導入
- パッケージを追加します。
flutter pub add http
2. 使用するファイル内でimport
します。
import 'package:http/http.dart' as http;
JSONPlaceholder
JSONPlaceholderは、テスト用途のAPIサービスで、開発者がAPIの動作をテストし、APIリクエストを練習するためのサイトとなっています。今回は投稿リソースを利用したいと思います。
サンプルコード
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<dynamic> _posts = [];
@override
void initState() {
super.initState();
fetchPosts();
}
Future<void> fetchPosts() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
if (response.statusCode == 200) {
final List<dynamic> data = jsonDecode(response.body);
setState(() {
_posts = data;
});
} else {
throw Exception('Failed to load data');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('API Example'),
),
body: ListView.builder(
itemCount: _posts.length,
itemBuilder: (context, index) {
final post = _posts[index];
return ListTile(
title: Text(post['title']),
subtitle: Text(post['body']),
);
},
),
),
);
}
}
サンプルコード解説
Future<void> fetchPosts() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
if (response.statusCode == 200) {
final List<dynamic> data = jsonDecode(response.body);
setState(() {
_posts = data;
});
} else {
throw Exception('Failed to load data');
}
}
- 非同期関数で、外部のAPIからデータを取得します。 ここでは
http.get
メソッドを使用して指定したURLからデータを取得します。 - HTTP応答ステータスコードが200(成功)であるかを確認し、成功した場合はデータをデコード2して
_posts
リストに設定します。エラーが発生した場合は例外をスローします。
body: ListView.builder(
itemCount: _posts.length,
itemBuilder: (context, index) {
final post = _posts[index];
return ListTile(
title: Text(post['title']),
subtitle: Text(post['body']),
);
},
),
リストビューのitemCount
プロパティでは、表示するリストアイテムの数を_posts
リストの数に設定します。
itemBuilder
プロパティは、リストアイテムを動的に構築するために使用されます。_posts
リスト内の各要素にアクセスし、ListTile
ウィジェットとして返します。
ListTile
ウィジェットプロパティは、リスト内の各項目を表示します。title
プロパティにはtitle
フィールドのデータが、subtitle
プロパティにはbody
フィールドのデータが表示されます。
参考資料