ASP.NET Web API
によるREST API開発API
: Application Programming InterfaceプログラムからのHTTPリクエストに対し、XML
や JSON
などのデータを返すWebアプリケーションを Web API と呼びます。
ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework.
ASP.NET Web APIは、それが簡単にブラウザやモバイル機器などのクライアントの広い範囲を、到達するHTTPサービスを構築することを可能にするフレームワークです。 ASP.NET Web APIは、.NET Framework上で RESTful なアプリケーションを構築するための理想的なプラットフォームです。 (Google翻訳)
REST
とは?RESTful
なシステム、 といわれます。
セッションやクッキーによるセッション状態の管理を行わず、 一度のリクエスト/レスポンスで問い合わせが完了する。
URI (Uniform Resource Identifier)
でリソースを一意に識別するhttp://{webapi}/user/1/task/5
のような URL にリクエストを投げると
userId
が1
のユーザーが持っているtaskId
が5
のタスク情報を返すようなイメージ。
HTTPメソッド | リソースの操作 |
---|---|
GET | リソースの取得 (Read) |
POST | リソースの追加 (Create) |
PUT | リソースの更新 (Update) |
DELETE | リソースの削除 (Delete) |
ステータスコード | 意味 |
---|---|
200 | OK |
201 | Created |
400 | Bad Request |
401 | Unauthorized |
403 | Forbidden |
404 | Not Found |
500 | Internal Server Error |
今回はクライアント側のプログラムは作成しないので、Web APIに問い合わせを行う クライアントアプリケーションを用意します。
HTTPが喋れるツールであれば何でも良いのですが、今回は cURL
を使用します。
cURL(カール)は、さまざまなプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供するプロジェクトである。
自分でcURL
のバイナリを探してきてダウンロード・インストールするのは面倒臭いので、
パッケージ管理ツールを使用します。
Chocolatey は Linuxでいう yum
や apt-get
のようなパッケージ管理ツールです。
コマンドプロンプトを 管理者として実行
し、以下のコマンドをコピー&ペーストします。
(Chocolateyのサイトにコマンドが記載されているので、それをコピーしてください。)
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin
Chocolatey
を使用して、cURL
をインストールします。
choco install curl
www.example.com
のhtmlを取得してみます。
>curl http://www.example.com
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
:
きちんとhtmlが返ってくれば、準備完了です。
操作 | URL | Method | 説明 |
---|---|---|---|
Create | /api/Todoes/ | post | 1件作成 |
Read | /api/Todoes/{id} | get | 指定したTodoを取得 |
ReadAll | /api/Todoes/ | get | 全てのTodoを取得 |
Update | /api/Todoes/{id} | put | 指定したTodoを更新 |
Delete | /api/Todoes/{id} | delete | 指定したTodoを削除 |
Todoは以下のプロパティを持つものとします。
done: 完了フラグ。真偽値。
第2回で作成した MVC の Todo管理アプリケーションと同じ内容です。
それでは、実際に開発を進めていきます。
こちら に実際にVisual Studio 2013で作成したプロジェクトがあります。
TodoApi
とします。Empty
を選択し、Web API
にチェックを入れます。今回は EntityFramework 6 を使用します。
Models
を右クリック→「追加」→「クラス」を選択します。Todo.cs
として「追加」します。Todo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TodoApi.Models
{
public class Todo
{
public int id { get; set; }
[Required]
public string summary { get; set; }
public string detail { get; set; }
public DateTime limit { get; set; }
public bool done { get; set; }
}
}
TodoesContext.cs
を追加します。TodoesContext.cs
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace TodoApi.Models
{
public class TodoesContext : DbContext
{
public DbSet<Todo> Todoes { get; set; }
}
}
ここまで作成したら、一旦ソリューション全体をビルドしてください。
Entity Framework を使用したアクションがある Web API 2 コントローラー
を選択して「追加」をクリックTodo
、データ コンテキスト クラスに TodoesContext
を選択して「追加」をクリックTodoesController
となるはず生成されたソースコードについて解説していきます。
Web APIとして公開されるメソッドは Public
になっています。
また、それぞれの命名規則は HTTPメソッド名 + Model名
となっています。
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Description;
using TodoApi.Models;
namespace TodoApi.Controllers
{
public class TodoesController : ApiController
{
Web APIのコントローラーは ApiController
クラスを継承します。ApiController
は MVCの Controller
クラスを継承していますので、
MVCの場合と非常によく似た内容になります。
private TodoesContext db = new TodoesContext();
// GET: api/Todoes
public IQueryable<Todo> GetTodoes()
{
return db.Todoes;
}
GetTodoes
は GETメソッドで api/Todoes
にアクセスされた場合に実行されるアクションメソッドです。
すべてのTodoをリストで返します。
StatusCodeの指定がない場合は、常に 200 (Ok) を返します。
// GET: api/Todoes/5
[ResponseType(typeof(Todo))]
public IHttpActionResult GetTodo(int id)
{
Todo todo = db.Todoes.Find(id);
if (todo == null)
{
return NotFound();
}
return Ok(todo);
}
IDを指定された場合は、IDが一致するTodoを返します。
Todoが見つかった場合はそのデータを返します。Ok
メソッドはStatusCode 200 を返します。
Todoが見つからない場合、 StatusCode 404 (Not Found) を返します。
// PUT: api/Todoes/5
[ResponseType(typeof(void))]
public IHttpActionResult PutTodo(int id, Todo todo)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != todo.id)
{
return BadRequest();
}
db.Entry(todo).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!TodoExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
PUT で該当IDの項目を更新 (Update) します。
入力内容に問題がある場合は 400 (BadRequest) が返されます。
例外がthrowされた場合は 500 (Internal Server Error) が返されます。
また、該当IDの項目が無ければ 404 (Not Found) が返されます。
更新完了後は特に返却するものは無いので、StatusCode 204 (No Content) を返します。
// POST: api/Todoes
[ResponseType(typeof(Todo))]
public IHttpActionResult PostTodo(Todo todo)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Todoes.Add(todo);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = todo.id }, todo);
}
POST で新しいTodoを作成 (Create) します。
postされた内容が todo
にセットされます。
ModelState.IsValid
で内容を検査し、問題があれば 400 (BadRequest) を返します。
問題なければ、DBを更新し、 201 (Created) を返します。
// DELETE: api/Todoes/5
[ResponseType(typeof(Todo))]
public IHttpActionResult DeleteTodo(int id)
{
Todo todo = db.Todoes.Find(id);
if (todo == null)
{
return NotFound();
}
db.Todoes.Remove(todo);
db.SaveChanges();
return Ok(todo);
}
DELETE で該当のTodoを削除 (Delete) します。
該当IDの項目が無ければ 404 (Not Found) が返されます。
削除後は削除されたTodoをそのまま返しています。 (個人的には StatusCode 204 (No Content) を返しても良いと思います)
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool TodoExists(int id)
{
return db.Todoes.Count(e => e.id == id) > 0;
}
}
}
Visual Studioで F5キーを押下 (あるいは |>
ボタンをクリック) してデバッグ実行します。
ブラウザが起動しますが、Webページは用意していないのでエラー画面が表示されると思います。 Web API は正常に稼働しているはずです。 (動作確認を完了するまでブラウザは終了せず、そのままにしておいてください。)
# get all items
curl http://localhost:49192/api/Todoes/
# create item
curl -v -H "Content-Type: application/json" -H "Accept:application/json" -X POST -d "{\"summary\":\"test\",\"detail\":\"hogehoge\",\"limit\":\"2015-02-01\",\"done\":\"false\"}" http://localhost:49192/api/Todoes/
# get item
curl http://localhost:49192/api/Todoes/1
# update item
curl -v -H "Content-Type: application/json" -H "Accept:application/json" -X PUT -d "{\"id\":5,\"summary\":\"test2\",\"detail\":\"hogehoge\",\"limit\":\"2015-02-01\",\"done\":\"false\"}" http://localhost:49192/api/Todoes/5
現状、http://localhost:49192/api/Todoes/
にリクエストを投げると全件返ってきます。
URLにパラメータ (QueryString
といいます) を付与することで、Todoを絞り込めるように機能を追加してみます。
GetTodoes
を拡張し、引数にパラメータを取得するように指定します。
// GET: api/Todoes
public IQueryable<Todo> GetTodoes([FromUri] Todo param)
{
var todoes = db.Todoes.OrderBy(item => item.id).Select(item => item);
if (!string.IsNullOrEmpty(param.summary))
{
// summary検索
todoes = todoes.Where(item => item.summary.Contains(param.summary));
}
if (param.done)
{
// 完了フラグ
todoes = todoes.Where(item => true.Equals(item.done));
}
return todoes;
}
[FromUri]
は QueryString
の内容を引数にセットする指定です。
http://localhost:49192/api/Todoes/?summary=test&done=false
といったようにURLパラメータに絞り込み条件を付与すると、条件に一致した項目のみ返ってきます。
これまでの処理で登録されたデータは、SQL Server LocalDB
に保存されています。
以下の手順で、登録されたデータを確認することができます。
Web.config
に登録されている LocalDB のインスタンス名を確認します。 :
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
mssqllocaldb
がインスタンス名です。表示
> SQL Server オブジェクト エクスプローラー
を選択します。SQL Serverの追加
をクリックします。(localdb)\mssqllocaldb
と入力し、接続します。TodoApi.Models.TodoesContext
というデータベースが存在します。テーブル > dbo.Todoes
を右クリックし、「データの表示」を選択します。正常に接続できない場合は、以下の手順でインスタンス名を確認します。
>sqllocaldb i
と入力します。SQL Server オブジェクト エクスプローラー
で各インスタンスの中身を確認してください。
ASP.NET Web APIの開発手順について解説しました。
ASP.NET Web API
と EntityFramework
により、以下のようなメリットがあることを実感いただけたのではないでしょうか。
次回は 今回作成したAPIを操作する WebアプリケーションのView部分を作成します。