第2回 RESTfulなAPIの設計を学ぼう連載:ASP.NET Web API 入門(1/2 ページ)

Web APIといっても、どのようなURLの、どのようなAPIを定義すればよいのか? RESTfulなHTTPサービスを実装するためのAPIの定義方法の基礎を説明する。

» 2013年10月23日 13時34分 公開
連載:ASP.NET Web API 入門
Insider.NET

 

「連載:ASP.NET Web API 入門」のインデックス

連載目次

 本連載は、ASP.NET Web APIを基礎から解説している。前回は、簡単なHello, Worldコードを確認しただけであったが、今回から本格的な実装の解説に入る。

 ASP.NET Web APIにおいて、最低限必要になる実装は、「ルーティングの設定」と「APIコントローラの実装」である。今回〜次回は、そのうちの「APIコントローラの実装」について解説を行う*1

 開発環境はMicrosoft Visual Studio Express 2012 for Web(Update3)、言語はC#、対象とするASP.NET Web APIのバージョンは1とする*2

*1 ルーティングの設定については、第4回目で紹介する予定だ。

*2 開発環境は、本稿執筆時点でリリースされているMicrosoft Visual Studio Express 2013 for Webでも構わない。ただし、プロジェクト・テンプレートに含まれるASP.NET Web APIのバージョンは2なので注意。 以降の解説にて、バージョン2との違いがある場合は随時補足する。


はじめに

 本稿(今回〜次回)の目次は、以下のとおりとなる。

【今回】
  1. RESTfulなAPIの設計を学ぼう
   1-1. REST とは
   1-2. HTTPメソッドは、リソースをどのように操作したいかを表す
   1-3. URLはリソースの名前を表す
   1-4. APIの処理の結果は、ステータス・コードで表す

【次回】
  2. APIコントローラの実装
   2-1. APIコントローラの役割とは
   2-2. APIコントローラの用意
   2-3. HTTPリクエストを取得する
   2-4. HTTPレスポンスの内容を指定する

 今回〜次回は、より実践的なAPIコントローラの実装方法を学ぶため、以下の2つの要素を取り入れて解説する。

  • RESTfulなAPIの設計
  • データの基本処理であるCRUD(追加/取得/更新/削除)を想定したAPIの実装方法

 実装に入る前にはまず、どのようなAPIを定義するかを決定する必要がある。ASP.NET Web APIは、RESTfulなHTTPサービスを提供することに特化したフレームワークであるため、初めにRESTfulなAPIを定義する方法について紹介する。

 また、APIの振る舞いは、データの基本処理であるCRUDを想定し、サーバとクライアントの間でどのようなHTTPリクエスト、HTTPレスポンスのやりとりが行われるか、例を挙げながら解説する。APIコントローラを実装する際は、ぜひ本稿を参考にしていただきたい。

今回〜次回で使用するAPIコントローラのサンプル・コード

 本稿で扱う要素 ―― RESTfulなAPIとCRUDを備える、APIコントローラ ―― のサンプル・コードは、Visual Studio 2012(または、Visual Studio Express 2012 for Web)のスキャフォールディング機能*3により自動生成されるAPIコントローラ・クラスのコードだ。ASP.NET Web APIのスキャフォールディング機能は、コードの記述を簡略化するだけでなく、ASP.NET Web APIの基本パターンを実装しているという側面も併せ持つ。

 スキャフォールディングにより自動生成されるAPIコントローラ・クラスのコード(リスト1)と、定義されるAPIを図で表したもの(図1)を掲載する。CRUDの対象となるデータは、例として顧客データ(今回のサンプルのために定義したCustomerクラス)とした。以降、このAPIコントローラ・クラスで定義されるAPI(顧客APIと呼称する)を引用しながら解説を行うので、今は簡単に眺め、必要なときに参照してほしい。

*3 スキャフォールディング機能とは、開発者が定義するモデルから、APIコントローラ・クラスのコードを自動生成する機能だ。この機能は、ASP.NET MVCにおいても有効だ(参考:「ASP.NET MVC入門:第2回 スキャフォールディング機能で軽々DB連携アプリケーション」)。
  ASP.NET Web APIのスキャフォールディング機能を利用する手順については、「Windows Azure ドキュメント: ASP.NET Web API と SQL データベースを使用したモバイル対応の REST サービス」を参考のこと。


図1 顧客APIコントローラ・クラスが定義するAPI 図1 顧客APIコントローラ・クラスが定義するAPI
スキャフォールディング機能より生成されるAPIコントローラ・クラスが定義するAPIを図で表したもの。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using MyApiProject.Models;

namespace MyApiProject.Controllers
{
  public class CustomersController : ApiController
  {
    // (1)
    private MyApiProjectContext db = new MyApiProjectContext();

    //  GET ~/api/Customers
    public IEnumerable<Customer> GetCustomers()
    {
      // Customersテーブルの全てのデータを取得し、
      // IEnumerable<Customer>型に変換して返す。
      return db.Customers.AsEnumerable();
    }

    //  GET ~/api/Customers/5
    public Customer GetCustomer(int id)
    {
      // Customersテーブルから、idが一致するデータを取得
      Customer customer = db.Customers.Find(id);
      if (customer == null)
      {
        // 一致するデータ存在しない場合は、ステータス・コード404を返す。
        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
      }
      // Customerデータを返す。
      return customer;
    }

    //  PUT ~/api/Customers/5
    public HttpResponseMessage PutCustomer(int id, Customer customer)
    {
      if (!ModelState.IsValid)
      {
        // モデルに検証エラーが存在する場合は、ステータス・コード400とエラー内容を返す。
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
      }

      if (id != customer.Id)
      {
        // URLで指定したidと、HTTPリクエストのボディで指定したidが一致しない場合は、
        // ステータス・コード400を返す。
        return Request.CreateResponse(HttpStatusCode.BadRequest);
      }
        // Customerデータを更新する。
        db.Entry(customer).State = EntityState.Modified;

      try
      {
        // データベースに変更をコミットする。
        db.SaveChanges();
      }
      catch (DbUpdateConcurrencyException ex)
      {
        // データベースの変更中に例外が発生した場合は、
        // ステータス・コード404と例外のメッセージを返す。
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
      }
      // データの変更処理が正常に終了した場合、ステータス・コード200を返す。
      return Request.CreateResponse(HttpStatusCode.OK);
    }

    //  POST ~/api/Customers
    public HttpResponseMessage PostCustomer(Customer customer)
    {
      if (ModelState.IsValid)
      {
        // Customersテーブルに新しいデータを追加する。
        db.Customers.Add(customer);
        db.SaveChanges();

        // ステータス・コード201と、追加したCustomerデータ、
        // 追加したCustomerデータを取得するためのURLを返す。
        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, customer);
        response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = customer.Id }));
        return response;
      }
      else
      {
        // モデルに検証エラーが存在する場合は、ステータス・コード400とエラー内容を返す。
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
      }
    }

    //  DELETE ~/api/Customers/5
    public HttpResponseMessage DeleteCustomer(int id)
    {
      // Customersテーブルから、idが一致するデータを取得
      Customer customer = db.Customers.Find(id);
      if (customer == null)
      {
        // 一致するデータ存在しない場合は、ステータス・コード404を返す。
        return Request.CreateResponse(HttpStatusCode.NotFound);
      }
      // Customersテーブルからデータを削除する
      db.Customers.Remove(customer);

      try
      {
        // データベースに変更をコミットする。
        db.SaveChanges();
      }
      catch (DbUpdateConcurrencyException ex)
      {
        // データベースの変更中に例外が発生した場合は、
        // ステータス・コード404と例外のメッセージを返す。
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
      }
      // 削除処理が正常に終了した場合、ステータス・コード200と、
      // 削除したCustomerデータを返す。
      return Request.CreateResponse(HttpStatusCode.OK, customer);
    }

    protected override void Dispose(bool disposing)
    {
      db.Dispose();
      base.Dispose(disposing);
    }
  }
}

リスト1 顧客APIコントローラ・クラス
各メソッド内で、顧客データをデータベースへの登録/取得/更新/削除が行われている。
データベースへのアクセスには、Entity Framework*4を採用している。プライベート・フィールド変数「db」……(1)に対して操作を行っている箇所がデータベースへアクセスする部分である。
このコードは、Visual Studio 2012(または、Visual Studio Express 2012 for Web)のスキャフォールディング機能で生成したコードである。Microsoft Visual Studio 2013のスキャフォールディング機能で生成されるコードとは、一部が違うので注意。

*4 Entity Frameworkについては「ADO.NET Entity Framework入門」、Entity Frameworkのコード・ファーストについては『第1回 EF 4.1の目玉機能「コード・ファースト」を理解しよう』を参考のこと。


       1|2 次のページへ

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。