ASP.NET Coreシリーズの新しい記事では、To Doリストを操作するための簡単なWeb APIを作成する方法について説明します。
ASP.NET Coreに関する記事の最初のシリーズ
1. Nano Server上のASP.NET Core 。
2. アプリケーションのWebサービスフロントエンドを作成します 。
3. ASP.NET Core MVCおよびVisual Studioを使用した最初のWeb APIの作成 。
4. Visual Studioを使用して、WebアプリケーションをAzure Application Serviceにデプロイします 。
5. Visual Studio Codeを使用した最初のMacアプリケーション 。
はじめに
ASP.NET Core MVCには、Web API作成のサポートが組み込まれています。 2つのプラットフォームを組み合わせることで、ユーザーインターフェイス(HTML)とAPIの両方を含むアプリケーションの作成が簡単になります。この場合、共通のコードとパイプラインがあるためです。
注:既存のWeb APIアプリケーションをASP.NET Coreに移植する場合は、ASP.NET Web APIからアップグレードする方法についてお読みください 。
説明
この記事では、次のAPIを作成します。
API | 説明 | リクエスト本文 | 応答本文 |
Get / API / Todo | すべてのTo Doアイテムを取得する | いや | To Doアイテムの配列 |
GET / api / todo / {id} | IDでアイテムを取得 | いや | To Doアイテム |
POST / API / Todo | 新しいアイテムを追加 | To Doアイテム | To Doアイテム |
PUT / api / todo / {id} | 既存のアイテムを更新 | To Doアイテム | いや |
PATCH / api / todo / {id} | 既存のアイテムを更新 | To Doアイテム | いや |
DELETE / api / todo / {id} | アイテムを削除 | いや | いや |
次の図は、アプリケーションのアーキテクチャを示しています。
- クライアントは、Web API(ブラウザー、モバイルアプリケーションなど)を使用するソフトウェアです。 この記事では、クライアントは作成されません。 Postmanを使用してアプリケーションをテストします。
- モデルは、アプリケーション内のデータを表すオブジェクトです。 この場合、唯一のモデルはTo Doアイテムです。 モデルは単純なC#クラス(POCO)で表されます。
- コントローラーは、HTTP要求を処理し、HTTP応答を作成するオブジェクトです。 このアプリケーションには1つのコントローラーがあります。
- 簡単にするために、この資料ではデータベースを使用してアプリケーションを実行しません。 代わりに、リスト項目は単にメモリに保存されます。 ただし、Web APIとデータレイヤーの分離を示すために、データアクセスレイヤーが含まれます。 データベースを使用するオプションについては、 記事で説明しています 。
プロジェクト作成
Visual Studioを起動します。 「 ファイル」メニューから、 「新規」>「プロジェクト」を選択します。 ASP.NET Core Webアプリケーション(.NET Core)プロジェクトテンプレートを選択します 。 プロジェクトに
TodoApi
名前を付け、クラウド内のホストをオフにして 、[ OK ]をクリックします。
新しいASP.NET Core Webアプリケーション(.NET Core)-TodoApiウィンドウで、 Web APIテンプレートを選択します 。 OKをクリックします。
モデルクラスの追加
モデルは、アプリケーション内のデータを表すオブジェクトです。 この場合、唯一のモデルはTo Doアイテムです。
「Models」というディレクトリを追加します。 ソリューションエクスプローラーで、プロジェクトを右クリックします。 [ 追加]> [新しいフォルダ]を選択します。 Modelsディレクトリの名前を入力します。
注:モデルクラスはプロジェクト内の任意の場所に配置できますが、通常はModelsディレクトリに配置されます。
TodoItem
クラスを追加します。 Modelsディレクトリーを右クリックして、「 追加」>「クラス」を選択します。 クラス名
TodoItem
を
TodoItem
[ 追加 ] をクリックします。
生成されたコードを次のものに置き換えます。
namespace TodoApi.Models { public class TodoItem { public string Key { get; set; } public string Name { get; set; } public bool IsComplete { get; set; } } }
リポジトリクラスの追加
リポジトリは、データレイヤーをカプセル化するオブジェクトであり、データとそのモデルへの方向を抽出するためのロジックが含まれています。 このアプリケーションはデータベースを使用しませんが、リポジトリーをコントローラーに組み込む方法を示すことは理にかなっています。 Modelsディレクトリにリポジトリコードを作成します。
ITodoRepository
というリポジトリインターフェイスを定義することから
ITodoRepository
ます。 クラステンプレート([新しいアイテムの追加]> [クラス])を使用します。
using System.Collections.Generic; namespace TodoApi.Models { public interface ITodoRepository { void Add(TodoItem item); IEnumerable<TodoItem> GetAll(); TodoItem Find(string key); TodoItem Remove(string key); void Update(TodoItem item); } }
このインターフェイスは、CRUDの基本操作を定義します。
次に、
TodoRepository
を実装する
TodoRepository
クラスを追加し
ITodoRepository
。
using System; using System.Collections.Generic; using System.Collections.Concurrent; namespace TodoApi.Models { public class TodoRepository : ITodoRepository { private static ConcurrentDictionary<string, TodoItem> _todos = new ConcurrentDictionary<string, TodoItem>(); public TodoRepository() { Add(new TodoItem { Name = "Item1" }); } public IEnumerable<TodoItem> GetAll() { return _todos.Values; } public void Add(TodoItem item) { item.Key = Guid.NewGuid().ToString(); _todos[item.Key] = item; } public TodoItem Find(string key) { TodoItem item; _todos.TryGetValue(key, out item); return item; } public TodoItem Remove(string key) { TodoItem item; _todos.TryRemove(key, out item); return item; } public void Update(TodoItem item) { _todos[item.Key] = item; } } }
アプリケーションをビルドして、コンパイラーがエラーをスローしないようにします。
リポジトリを登録する
リポジトリインターフェイスを定義するとき、リポジトリクラスを使用するMVCコントローラから分離できます。 コントローラ内に
TodoRepository
を実装する代わりに、ASP.NET Coreに組み込まれた依存性注入のサポートを使用して
TodoRepository
を
TodoRepository
します。
このアプローチにより、コントローラーの単体テストが簡素化されます。 ユニットテストは、
ITodoRepository
「ダミー」または「シミュレーション」バージョンを
ITodoRepository
ます。 この場合、テストはデータアクセスのレベルではなく、コントローラーのロジックを対象としています。
リポジトリをコントローラに実装するには、DIコンテナを使用して登録する必要があります。 Startup.csファイルを開きます。 次のusingディレクティブを追加します。
using TodoApi.Models;
ConfigureServices
メソッドで、強調表示されたコードを追加します。
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddSingleton<ITodoRepository, TodoRepository>(); }
コントローラーの追加
ソリューションエクスプローラーで、 Controllersディレクトリを右クリックします 。 [ 追加]> [新しいアイテム]を選択します。 [ 新しい項目の追加]ウィンドウで、 Web API Controllerクラステンプレートを選択します 。 クラス名
TodoController
入力します。
生成されたコードを次のものに置き換えます。
using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using TodoApi.Models; namespace TodoApi.Controllers { [Route("api/[controller]")] public class TodoController : Controller { public TodoController(ITodoRepository todoItems) { TodoItems = todoItems; } public ITodoRepository TodoItems { get; set; } } }
したがって、空のコントローラーのクラスが決定されます。 以下のセクションでは、APIを実装するためのメソッドの追加について説明します。
To Doアイテムの取得
To Doアイテムを取得するには、次のメソッドを
TodoController
クラスに追加します。
public IEnumerable<TodoItem> GetAll() { return TodoItems.GetAll(); } [HttpGet("{id}", Name = "GetTodo")] public IActionResult GetById(string id) { var item = TodoItems.Find(id); if (item == null) { return NotFound(); } return new ObjectResult(item); }
これらのメソッドは、2つのGETメソッドを実装します。
-
GET /api/todo
-
GET /api/todo/{id}
この場合、
GetAll
メソッドのHTTP応答は次のようになります。
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Server: Microsoft-IIS/10.0 Date: Thu, 18 Jun 2015 20:51:10 GMT Content-Length: 82 [{"Key":"4f67d7c5-a2a9-4aae-b030-16003dd829ae","Name":"Item1","IsComplete":false}]
次に、 Postmanを使用してHTTP応答を表示する方法を示します。
ルーティングとURLパス
HttpGet
属性( HttpGetAttribute )は、HTTP GETメソッドを定義します。 各メソッドのURLパスは次のように構築されます。
- コントローラーのルート属性からテンプレート文字列を
[Route("api/[controller]")]
ます:[Route("api/[controller]")]
- [Controller]を、コントローラークラスの名前を取得し、接尾辞「Controller」を削除して取得するコントローラーの名前に置き換えます。 この例では、コントローラークラス名はTodo Controllerで、ルート名はtodoです。 ASP.NET Core ルーティングは大文字と小文字を区別しません。
-
[HttpGet]
属性にテンプレート文字列がある場合は、パスに追加します。 この例では、テンプレート文字列は使用されていません。
GetById
メソッドで:
[HttpGet("{id}", Name = "GetTodo")] public IActionResult GetById(string id)
"{id}"
は、
todo
要素の識別子に置き換えられる値です。
GetById
が呼び出されると、URLの「{id}」値がメソッドの
id
パラメーターに割り当てられます。
Name = "GetTodo"
は、HTTP応答で参照できる名前付きルートを作成します。 将来的には、これは例によって示されます。
戻り値
GetAll
メソッドは
IEnumerable
返します。 MVCは、オブジェクトをJSONで自動的にシリアル化し、 JSONを応答本文に書き込みます 。 未処理の例外がない場合、このメソッドの応答コードは200です(未処理の例外は5xxエラーに変換されます)。
次に、
GetById
メソッドは、より一般的な
IActionResult
型の値を返します。これは、多数の戻り値型で表されます。
GetById
は、2種類の戻り値があります。
- 要求された識別子に一致するものがない場合、メソッドは404エラーを返しますこれは
NotFound
が戻ったときに発生します。 - それ以外の場合、メソッドは200コードと応答本文をJSON形式で返します。 これは、
ObjectResult
が戻るときに発生します。
アプリケーションの起動
Visual StudioでCtrl + F5を押して、アプリケーションを起動します。 ブラウザが起動し、Webページ
http://localhost:port/api/values
が開きます
http://localhost:port/api/values
はランダムに選択されたポート番号です。 Chrome、Edge、Firefoxを使用している場合、データが表示されます。 IEを使用する場合、 values.jsonファイルを開くか保存するように求められます。
他のCRUD操作の実装
Create
、
Update
および
Delete
メソッドを追加し
Create
。 このプロセスは前に説明したものと似ているため、ここにコードを示し、主な違いを強調します。 コードを追加または変更した後にプロジェクトを作成します。
作成する
[HttpPost] public IActionResult Create([FromBody] TodoItem item) { if (item == null) { return BadRequest(); } TodoItems.Add(item); return CreatedAtRoute("GetTodo", new { id = item.Key }, item); }
これは、 [HttpPost]属性で指定されたHTTO POSTメソッドです。 [FromBody]属性はMVCコマンドを送信して、HTTP要求の本文からTo Doアイテムの値を取得します。
CreatedAtRouteメソッドは201の応答を返します。これは、サーバーに新しいリソースを作成するHTTP POSTメソッドの標準応答です。
CreateAtRoute
は、応答にLocationヘッダーも追加します。 Locationヘッダーは、作成されたTo DoアイテムのURLを示します。 説明: 10.2.2 201 Created 。
Postmanを使用して作成リクエストを送信する
- HTTPメソッドとして
POST
を設定します。 - Bodyスイッチを選択します。
- rawスイッチを選択します。
- JSONタイプを選択します。
- キーと値のペアのエディターで、次のようにTodo要素を指定します:
{"Name":"<your to-do item>"}
。 - 送信をクリックします。
[ヘッダー]タブを選択し、 ロケーションヘッダーをコピーします。
作成したリソースにアクセスするには、LocationヘッダーのURLを使用できます。
GetById
メソッドを
GetById
呼び出して、名前付き
"GetTodo"
ルートを作成します。
[HttpGet("{id}", Name = "GetTodo")] public IActionResult GetById(string id)
更新する
[HttpPut("{id}")] public IActionResult Update(string id, [FromBody] TodoItem item) { if (item == null || item.Key != id) { return BadRequest(); } var todo = TodoItems.Find(id); if (todo == null) { return NotFound(); } TodoItems.Update(item); return new NoContentResult(); }
Update
は
Create
に似てい
Create
、HTTP PUTを使用します。 回答204(コンテンツなし) HTTP仕様によると、PUT要求では、クライアントはデルタだけでなく、更新されたオブジェクトを完全に送信する必要があります。 部分的な更新をサポートするには、HTTP PATCHを使用します。
パッチを使用した更新
Update
に似てい
Update
が、HTTP PATCHを使用します。 回答204(コンテンツなし)
[HttpPatch("{id}")] public IActionResult Update([FromBody] TodoItem item, string id) { if (item == null) { return BadRequest(); } var todo = TodoItems.Find(id); if (todo == null) { return NotFound(); } item.Key = todo.Key; TodoItems.Update(item); return new NoContentResult(); }
削除する
[HttpDelete("{id}")] public IActionResult Delete(string id) { var todo = TodoItems.Find(id); if (todo == null) { return NotFound(); } TodoItems.Remove(id); return new NoContentResult(); }
回答204(コンテンツなし)