REST ベースの Web サービスを実行する
Representational State Transfer (REST) は、Web サービスをビルドするためのアーキテクチャ スタイルです。 REST 要求は、Web ブラウザーが Web ページの取得やサーバーへのデータの送信に使用するのと同じ HTTP 動詞を使用して HTTPS 経由で実行されます。 次の動詞があります。
- GET – この操作は、Web サービスからデータを取得するために使用されます。
- POST – この操作は、Web サービスに新しいデータ項目を作成するために使用されます。
- PUT – この操作は、Web サービスのデータ項目を更新するために使用されます。
- PATCH – この操作は、項目の変更方法に関する一連の命令を記述することにより、Web サービスのデータ項目を更新するために使用されます。
- DELETE – この操作は、Web サービスのデータ項目を削除するために使用されます。
REST に準拠する Web サービス API は次のものを使用して定義されます。
- ベース URI。
- GET、POST、PUT、PATCH、DELETE などの HTTP メソッド。
- JavaScript Object Notation (JSON) などの、データのメディアの種類。
REST ベースの Web サービスは、通常、JSON メッセージを使用してクライアントにデータを返します。 JSON は、データの送受信時に帯域幅要件を減らせる、コンパクトなペイロードを生成するテキスト ベースのデータ交換形式です。 REST のシンプルさが、モバイル アプリで Web サービスにアクセスするための主要な方法となっています。
Note
Web サービスにアクセスするには、多くの場合、非同期プログラミングが必要です。 非同期プログラミングの詳細については、「Asynchronous programming with async and await」をご覧ください。
Web サービスの操作
REST サービスの例は、ASP.NET Core を使用して記述され、次の操作を提供します。
操作 | HTTP メソッド | 相対 URI | パラメーター |
---|---|---|---|
ToDo 項目のリストを取得する | GET | /api/todoitems/ | |
ToDo 項目を作成する | 投稿 | /api/todoitems/ | JSON 形式の ToDo 項目 |
ToDo 項目を更新する | PUT | /api/todoitems/ | JSON 形式の ToDo 項目 |
ToDo 項目を削除する | DELETE | /api/todoitems/{id} |
.NET MAUI アプリと Web サービスは、TodoItem
クラスを使用して、表示され、ストレージ用の Web サービスに送信されるデータをモデル化します。
public class TodoItem
{
public string ID { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public bool Done { get; set; }
}
この ID
プロパティは、各 TodoItem
オブジェクトを一意に識別するために使用され、Web サービスで更新または削除するデータを識別するために使用されます。 たとえば、ID が 6bb8a868-dba1-4f1a-93b7-24ebce87e243
である TodoItem
を削除するには、.NET MAUI アプリから DELETE 要求が https://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243
に送信されます。
Web API フレームワークは、要求を受信すると、要求をアクションにルーティングします。 これらのアクションは、TodoItemsController
クラスのパブリック メソッドです。 Web API フレームワークは、ルーティング ミドルウェアを使って、受信した要求の URL を照合し、アクションにマップします。 REST API では、属性ルーティングを使用して、HTTP 動詞で操作を表現するリソースのセットとしてアプリの機能をモデル化する必要があります。 属性ルーティングでは、属性のセットを使ってアクションをルート テンプレートに直接マップします。 属性ルーティングの詳細については、「Attribute routing for REST APIs」をご覧ください。 ASP.NET Core を使用した REST サービスの構築の詳細については、「ネイティブ モバイル アプリのバックエンド サービスを作成する」をご覧ください。
HTTPClient オブジェクトを作成する
.NET Multi-platform App UI (.NET MAUI) アプリは、HttpClient
クラスを使用して Web サービスに要求を送信することで、REST ベースの Web サービスを使用できます。 このクラスでは、HTTP 要求を送信し、URI で識別されたリソースから HTTP 応答を受信するための機能が提供されます。 これらの各要求は、非同期操作として送信されます。
アプリが HTTP 要求を行う必要がある限り、HttpClient
オブジェクトはクラス レベルで宣言する必要があります。
public class RestService
{
HttpClient _client;
JsonSerializerOptions _serializerOptions;
public List<TodoItem> Items { get; private set; }
public RestService()
{
_client = new HttpClient();
_serializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
}
...
}
この JsonSerializerOptions
オブジェクトは、Web サービスとの間で送受信される JSON ペイロードの書式設定を構成するために使用されます。 詳細については、「System.Text.Json で JsonSerializerOptions インスタンスをインスタンス化する方法」をご覧ください。
データを取得する
この HttpClient.GetAsync
メソッドは、URI で指定された Web サービスに GET 要求を送信し、Web サービスから応答を受信するために使用されます。
public async Task<List<TodoItem>> RefreshDataAsync()
{
Items = new List<TodoItem>();
Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
try
{
HttpResponseMessage response = await _client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
Items = JsonSerializer.Deserialize<List<TodoItem>>(content, _serializerOptions);
}
}
catch (Exception ex)
{
Debug.WriteLine(@"\tERROR {0}", ex.Message);
}
return Items;
}
データは、Web サービスから HttpResponseMessage
オブジェクトとして受信されます。 これには、状態コード、ヘッダー、本文など、応答に関する情報が含まれます。 REST サービスは、HTTP 要求が成功したか失敗したかを示すために、HttpResponseMessage.IsSuccessStatusCode
プロパティから取得できる HTTP 状態コードを応答で送信します。 この操作では、REST サービスは応答に HTTP 状態コード 200 (OK) を送信します。これは、要求が成功し、要求された情報が応答にあることを示します。
HTTP 操作が成功した場合、応答の内容が読み取られます。 HttpResponseMessage.Content
プロパティは、応答のコンテンツを表す HttpContent
型のものです。 HttpContent
クラスは、HTTP 本文とコンテンツ ヘッダー (Content-Type
や Content-Encoding
など) を表します。 その後、HttpContent.ReadAsStringAsync
メソッドを使用してコンテンツが string
に読み込まれます。 その後、string
は JSON から TodoItem
オブジェクトの List
に逆シリアル化されます。
警告
ReadAsStringAsync
メソッドを使用して大きな応答を取得すると、パフォーマンスに悪影響を及ぼす可能性があります。 このような状況では、応答を完全にバッファー処理しないように、応答を直接逆シリアル化する必要があります。
データの作成
この HttpClient.PostAsync
メソッドは、URI で指定された Web サービスに POST 要求を送信し、Web サービスから応答を受信するために使用されます。
public async Task SaveTodoItemAsync(TodoItem item, bool isNewItem = false)
{
Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
try
{
string json = JsonSerializer.Serialize<TodoItem>(item, _serializerOptions);
StringContent content = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = null;
if (isNewItem)
response = await _client.PostAsync(uri, content);
else
response = await _client.PutAsync(uri, content);
if (response.IsSuccessStatusCode)
Debug.WriteLine(@"\tTodoItem successfully saved.");
}
catch (Exception ex)
{
Debug.WriteLine(@"\tERROR {0}", ex.Message);
}
}
この例では、TodoItem
インスタンスは Web サービスに送信するために JSON ペイロードにシリアル化されます。 このペイロードは、PostAsync
メソッドで要求が行われる前に Web サービスに送信される HTTP コンテンツの本文に埋め込まれます。
REST サービスは、HTTP 要求が成功したか失敗したかを示すために、HttpResponseMessage.IsSuccessStatusCode
プロパティから取得できる HTTP 状態コードを応答で送信します。 この操作の一般的な応答は次のとおりです。
- 201 (CREATED): 応答が送信される前に、要求によって新しいリソースが作成されたことを示します。
- 400 (BAD REQUEST): 要求はサーバーによって認識されません。
- 409 (CONFLICT): サーバー上の競合のために要求を実行できないことを示します。
データの更新
この HttpClient.PutAsync
メソッドは、URI で指定された Web サービスに PUT 要求を送信し、Web サービスから応答を受信するために使用されます。
public async Task SaveTodoItemAsync(TodoItem item, bool isNewItem = false)
{
...
response = await _client.PutAsync(uri, content);
...
}
PutAsync
メソッドの操作は、Web サービスでデータを作成するために使用される PostAsync
メソッドと同じです。 ただし、Web サービスから送信される可能性のある応答は異なります。
REST サービスは、HTTP 要求が成功したか失敗したかを示すために、HttpResponseMessage.IsSuccessStatusCode
プロパティから取得できる HTTP 状態コードを応答で送信します。 この操作の一般的な応答は次のとおりです。
- 204 (NO CONTENT): 要求が正常に処理され、応答が意図的に空白になっていることを示します。
- 400 (BAD REQUEST): 要求はサーバーによって認識されません。
- 404 (NOT FOUND): 要求されたリソースはサーバーに存在しないことを示します。
データの削除
この HttpClient.DeleteAsync
メソッドは、URI で指定された Web サービスに DELETE 要求を送信し、Web サービスから応答を受信するために使用されます。
public async Task DeleteTodoItemAsync(string id)
{
Uri uri = new Uri(string.Format(Constants.RestUrl, id));
try
{
HttpResponseMessage response = await _client.DeleteAsync(uri);
if (response.IsSuccessStatusCode)
Debug.WriteLine(@"\tTodoItem successfully deleted.");
}
catch (Exception ex)
{
Debug.WriteLine(@"\tERROR {0}", ex.Message);
}
}
REST サービスは、HTTP 要求が成功したか失敗したかを示すために、HttpResponseMessage.IsSuccessStatusCode
プロパティから取得できる HTTP 状態コードを応答で送信します。 この操作の一般的な応答は次のとおりです。
- 204 (NO CONTENT): 要求が正常に処理され、応答が意図的に空白になっていることを示します。
- 400 (BAD REQUEST): 要求はサーバーによって認識されません。
- 404 (NOT FOUND): 要求されたリソースはサーバーに存在しないことを示します。
ローカル開発
ASP.NET Core Web API などのフレームワークを使用して REST Web サービスをローカルで開発している場合は、Web サービスと .NET MAUI アプリを同時にデバッグできます。 このシナリオでは、Android エミュレーターと iOS シミュレーターから HTTP 経由で Web サービスを使用するには、.NET MAUI アプリでクリア テキストの HTTP トラフィックを有効にする必要があります。 詳細については、「Connect to local web services from Android emulators and iOS simulators」をご覧ください。
.NET MAUI