Roadmap.shで学ぶFlutter - Working with APIs -

# 導入
[roadmap.shのFlutter](https://roadmap.sh/flutter)の`Working with APIs`を進めていきます。

Flutterアプリを作る際、サーバーとのデータのやり取りは重要な要素の一つです。今回は、FlutterでAPIを扱うための基本的な方法と、HTTPリクエスト、JSONデータの処理、WebSocket、GraphQL、RESTful APIなどの具体的な技術について紹介します。

# Working with APIs
FlutterでAPIを扱うには、サーバーへのHTTPリクエストを行い、レスポンスを処理する必要があります。Flutterでは、HTTPリクエストを行うためのライブラリがいくつか提供されていますが、その中には`dart:io`や`http`があります。

`http`ライブラリは、FlutterでHTTPリクエストを行う際に一般的に使用される選択肢であり、使いやすく、GET、POST、PUT、DELETEなどのHTTPメソッドをサポートしています。

## JSON
JSON（JavaScript Object Notation）は、人間にとって読み書きが容易で、機械にとって解析や生成が容易な軽量のデータ交換形式です。Flutterでは、通常HTTP接続を介してクライアントとサーバー間でデータを送信するためにJSONが使用されます。

Flutterには、JSONデータを扱うためのライブラリがいくつか提供されており、その中には`dart:convert`ライブラリがあります。このライブラリは、JSONデータのエンコードとデコードをサポートしています。

DartオブジェクトをJSON文字列にエンコードするには、`dart:convert`ライブラリのjsonEncode関数を使用できます。JSON文字列をDartオブジェクトにデコードするには、jsonDecode関数を使用します。

## WebSockets
通常のHTTPリクエストに加えて、WebSocketを使ってサーバーに接続することができます。WebSocketは、クライアント（例えばウェブブラウザ）とサーバー間で双方向の通信を可能にする、単一で長時間接続を維持する仕組みです。リアルタイムデータの提供においてHTTPの代わりとしてより効率的な方法であり、クライアントが更新情報を求めてサーバーに繰り返しリクエストを送る必要がなく、サーバー側からデータが利用可能になった時点で即座にクライアントに送信できる点が特徴です。

FlutterからWebSocketサーバーに接続するには、`web_socket_channel`パッケージを利用します。

- 接続
```dart
final channel = WebSocketChannel.connect(
  Uri.parse('wss://{WebSocketサーバーのドメイン}'),
);
```

- サーバーからのメッセージ受信

```dart
StreamBuilder(
  stream: channel.stream, // ここで上記でWebSocketに接続したchannelを設定しておく
  builder: (context, snapshot) {
    return Text(snapshot.hasData ? '${snapshot.data}' : '');
  },
)
```
- メッセージ送信

```dart
const message = 'メッセージ';
channel.sink.add(message);
```

### 参考
https://docs.flutter.dev/cookbook/networking/web-sockets

## GraphQL

GraphQLはAPIのためのクエリ言語で、クライアントが必要なデータだけをリクエストできるようにします。
Facebookによって開発され、2015年にオープンソースとして公開されました。

GraphQLの大きな利点の一つは、クライアントが特定のフィールドを必要に応じてリクエストできる点です。
これにより、サーバーが固定のレスポンス形式でデータを送信するのではなく、**クライアントが必要なデータだけを取得**できます。ネットワークトラフィックが削減され、APIの効率が向上します。

## RESTful APIs
REST（Representational State Transfer）は、ウェブ上のコンピュータシステム間で標準を提供するためのアーキテクチャスタイルです。プロトコルや標準ではなく、API開発者は様々な方法でRESTを実装できます。
これにより、システム間の通信が容易になります。

### RESTful APIの特徴

1. **リソースの状態表現の転送**
   RESTful APIを使用してクライアントがリクエストを送信すると、リソースの状態の表現が返されます。この情報は、HTTPを通じてJSON（Javascript Object Notation）、HTML、XML、プレーンテキストなどの形式で提供されます。JSONは言語に依存せず、人間と機械の両方にとって読みやすいため、広く使われています。

2. **ヘッダーとパラメータ**
   RESTful APIリクエストでは、ヘッダーとパラメータが重要です。これらは認証情報、URI、キャッシング情報、クッキーなどのメタデータを含んでいます。リクエストヘッダーとレスポンスヘッダーにより、HTTP接続の詳細やステータスコードが伝えられます。

### RESTful APIの基準

RESTful APIは以下の基準に従う必要があります。

1. **クライアント-サーバーアーキテクチャ**
   クライアントとサーバーが明確に分離され、HTTPを通じてリクエストとレスポンスがやり取りされます。

2. **ステートレスなクライアント-サーバー通信**
   各リクエストは独立しており、サーバーはリクエスト間でクライアントの状態を保存しません。

3. **キャッシュ可能なデータ**
   サーバーからクライアントに送信されたデータはキャッシュ可能で、これにより通信が効率化されます。

4. **統一されたインターフェース**
   統一された方法でリソースを操作できることを保証します。具体的には、以下の要件を満たします。
   - リソースの識別: リソースは一意のURIによって特定されます
   - 操作の明示: クライアントが受け取るリソース表現には、リソースに対する操作に必要な情報が含まれています
   - セルフディスクリプティブメッセージ: メッセージには、クライアントがどのようにそれを処理するかの情報が含まれています
   - ハイパーメディア制御: クライアントはリソース表現内のハイパーリンクを使用して、利用可能な次の操作を発見できます

5. **レイヤードシステム**
   システムは階層構造を持ち、クライアントは中間サーバーの存在を意識しません。これにより、負荷分散やセキュリティが向上します。

6. **コードオンデマンド（オプション）**
   サーバーはクライアントに実行可能なコードを提供し、クライアントの機能を拡張できます。

これらの基準を満たす必要がありますが、REST APIはSOAP（Simple Object Access Protocol）などのプロトコルと比較して、使用が容易で軽量です。SOAPはXMLメッセージング、セキュリティ、トランザクションの遵守などの特定の要件があり、処理が遅く重くなりがちです。

一方、RESTは必要に応じて実装できるガイドラインのセットであり、REST APIは高速かつ軽量でスケーラビリティが向上します。これは、特にIoTやモバイルアプリ開発に適しています。したがってFlutter開発にも適していると言えます。

# 終わりに
今回は、FlutterでのAPI連携に焦点を当て、HTTPリクエストからWebSocket、GraphQL、RESTful APIまで、様々な技術について解説しました。これらの知識を活用して、よりインタラクティブでリアルタイムな機能を持つアプリを開発していきたいと思いました。