2017年4月15日

ASP.NET CoreとEntityFrameworkで最速でWeb APIを作るには

ASP.NET Core, EntityFrameworkとVisual Studio Codeを使ってデータベースから情報を取得してJSONで返すWeb APIを作ります。

コードファーストは使わず、既存のデータベースが存在するという前提で作ります。
とりあえず Northwind というサンプルのデータベースが存在すると仮定してコーディングしていますが、データベース名、テーブル名やモデルクラスの内容は適宜手元の環境に合わせて読み替えて下さい。

以下ステップ0から8までに分けましたが、おそらく20分もあれば全部出来ると思います。


ステップ0 - .NET Core SDKとVS Codeをインストール
ステップ1 - プロジェクトを作成する
ステップ2 - 依存パッケージを追加する
ステップ3 - モデルクラスを作成する
ステップ4 - DbContextクラスを作成する
ステップ5 - リポジトリクラスを作成する
ステップ6 - 設定ファイルにDB接続文字列を追加する
ステップ7 - Startupクラスに設定を追加する
ステップ8 - Controllerを作成する




ステップ0 - .NET Core SDKとVS Codeをインストール


下のサイトからインストールして下さい。

https://www.microsoft.com/net/core


VS Codeをインストールした後、C#用の拡張機能をインストールしておいて下さい。



ステップ1 - プロジェクトを作成する


dotnet new mvc --auth None --framework netcoreapp1.1 -o MySampleWeb
cd MySampleWeb
dotnet restore
code .

VS Codeでフォルダを開いて、拡張子が.csのファイルを表示すると2〜3秒後にダイアログが表示されるので、「Yes」をクリックします。


プロジェクトフォルダ直下に.vscodeフォルダが作られ、ビルドやデバッグ実行用の設定ファイルが自動的に作成されます。

この時点でShift+Ctrl+B(MacではShift+Cmd+B)を押すとビルドが実行されるのでエラーが無いことを確認しておきます。




ステップ2 - 依存パッケージを追加する


dotnet add package Microsoft.EntityFrameworkCore.SqlServer

上のコマンドを実行すると「MySampleWeb.csproj」ファイルにEntityFrameworkでSqlServerに接続するためのパッケージ参照のエントリが追加されます。



ステップ3 - モデルクラスを作成する


プロジェクト直下にDataというフォルダを作って、そこにCustomer.csファイルを作成します。





ステップ4 - DbContextクラスを作成する




コンストラクタのパラメータでoptionsを受け取るようになっている点に注意して下さい。これを忘れるとデータベースに接続出来ずエラーになります。




ステップ5 - リポジトリクラスを作成する




とりあえずGetAll()とFind()のみ実装しておきます。

CustomerRepositoryクラスのコンストラクタでNorthWindContextのインスタンスを受け取れるようになっている点に注目です。

ASP.NET CoreではDbContextなどのインスタンスはこの様にDependency Injection(DI)で受け取るというのが原則です。





ステップ6 - 設定ファイルにDB接続文字列を追加する




SQLサーバーの指定、ユーザーID、パスワードの指定は適宜変更して下さい。




ステップ7 - StartupクラスにDIの設定を追加する




AddDbContext()

このメソッドでDbContextのDIを設定しています。


AddScoped()

このメソッドでリポジトリクラスのDIを設定しています。「ICustomerRepositoryのインスタンスがどこかで要求されたら、CustomerRepositoryのインスタンスを生成して注入してね」という意味になります。

AddSingleton()やAddTransient()などもありますが、それぞれ注入されるインスタンスが維持される期間が異なります。

Dependency Injection in ASP.NET Core | Microsoft Docs
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection


AddScoped()の場合はひとつのHTTPリクエストについてひとつのインスタンスが生成されます。リポジトリクラスの中で使っているEntityFrameworkはスレッドセーフではないので AddSingleton() はここでは使えません。





ステップ8 - Controllerを作成する


ControllersフォルダにCustomersController.csファイルを新規作成します。



コンストラクタでリポジトリクラスのインスタンスを受け取るようになっています。ここでステップ7で設定したDIが効いてきます。

通常のWebアプリケーションとして動いている場合は、このDIのおかげでASP.NET Coreが自動的にCustomerRepositoryのインスタンスを生成してコントローラに渡してくれます。

でも単体テストでコントローラの動作をテストしたい場合などでは、自前でモックのインスタンスを生成してコントローラに渡すことが出来ます。DIを使うことでクラス同士が疎結合になっているわけですね。

密結合と疎結合の概念やDIについては下のページの説明がとても分かりやすいと思います。

ASP.NET - 依存関係の挿入による ASP.NET Core でのクリーンなコードの作成


これでカスタマーの情報を取得するWeb APIが出来ました。

VS Code上でF5またはCtrl+F5(MacではCmd+F5)を押して実行して見てください。ブラウザが開いてデフォルトのHomeページが表示されるので、下のURLを手入力します。

先頭から3件取得
http://localhost:5000/api/customers?offset=0&limit=3

カスタマーIDを指定して取得
http://localhost:5000/api/customers/ANATR



データベースから取得した情報がJSON形式で表示されれば成功です!


これからは.NETでのWeb開発といえば「ASP.NET Core」という事になって行くと思います。

WindowsでもMacでもLinuxでも全く同じように開発が出来るのがいい感じです。


今回のソースコードはこちらにあります。

https://github.com/mikehibm/AspNetCore-MySampleWeb



参考URL:
ASP.NET Core MVC with Entity Framework Core - Tutorial 1 of 10
チュートリアル: ASP.NET Core MVC で Web API を作成する | Microsoft Docs