API 設計API design

ほとんどの最新の Web アプリケーションでは、クライアントがアプリケーションと対話する際に使用できる API を公開しています。Most modern web applications expose APIs that clients can use to interact with the application. 適切に設計された Web API には、次をサポートする目的があります。A well-designed web API should aim to support:

  • プラットフォームの独立Platform independence. API の内部的な実装方法に関係なく、すべてのクライアントが API を呼び出すことができる必要があります。Any client should be able to call the API, regardless of how the API is implemented internally. そのためには、標準プロトコルを使用し、クライアントと Web サービスが交換するデータの形式に同意できるメカニズムを備えている必要があります。This requires using standard protocols, and having a mechanism whereby the client and the web service can agree on the format of the data to exchange.

  • サービスの進化Service evolution. Web API はクライアント アプリケーションから独立して進化し、機能を追加できる必要があります。The web API should be able to evolve and add functionality independently from client applications. API の進化に伴い、既存のクライアント アプリケーションが変更なしに引き続き機能する必要があります。As the API evolves, existing client applications should continue to function without modification. クライアント アプリケーションが機能を十分に利用できるように、すべての機能が検出可能である必要があります。All functionality should be discoverable, so that client applications can fully utilize it.

このガイダンスでは、Web API の設計時に考慮すべき問題について説明します。This guidance describes issues that you should consider when designing a web API.

REST の概要Introduction to REST

2000 年に、ロイ・フィールディングが、Web サービスを設計するためのアーキテクチャ アプローチとして Representational State Transfer (REST) を提唱しました。In 2000, Roy Fielding proposed Representational State Transfer (REST) as an architectural approach to designing web services. REST はハイパーメディアに基づき分散システムを構築するアーキテクチャ スタイルです。REST is an architectural style for building distributed systems based on hypermedia. REST は基になるプロトコルに依存せず、HTTP に必ずしも関連付けられているわけではありません。REST is independent of any underlying protocol and is not necessarily tied to HTTP. ただし、最も一般的な REST 実装では、アプリケーション プロトコルとして HTTP を使用します。このガイドでは、HTTP の REST API の設計に重点を置きます。However, most common REST implementations use HTTP as the application protocol, and this guide focuses on designing REST APIs for HTTP.

REST over HTTP の主な利点は、オープン スタンダードを使用し、API やクライアント アプリケーションの実装を特定の実装にバインドしないことです。A primary advantage of REST over HTTP is that it uses open standards, and does not bind the implementation of the API or the client applications any specific implementation. たとえば、REST Web サービスが ASP.NET で記述されていても、クライアント アプリケーションは任意の言語やツールセットを使用して、HTTP 要求を生成し、HTTP 応答を解析できます。For example, a REST web service could be written in ASP.NET, and client applications can use any language or toolset that can generate HTTP requests and parse HTTP responses.

HTTP を使用した RESTful API の主な設計原則を次に示します。Here are some of the main design principles of RESTful APIs using HTTP:

  • REST API は "リソース" を中心に設計します。リソースは、クライアントがアクセスできるあらゆる種類のオブジェクト、データ、またはサービスです。REST APIs are designed around resources, which are any kind of object, data, or service that can be accessed by the client.

  • リソースには "識別子" があります。識別子は、そのリソースを一意に識別する URI です。A resource has an identifier, which is a URI that uniquely identifies that resource. たとえば、特定の顧客注文の URI は次のようになります。For example, the URI for a particular customer order might be:

    http://adventure-works.com/orders/1
    
  • クライアントは、リソースの "表現" を交換することでサービスと対話します。Clients interact with a service by exchanging representations of resources. 多くの Web API では、交換形式として JSON を使用します。Many web APIs use JSON as the exchange format. たとえば、上記の URI に対する GET 要求では、次の応答本文が返されます。For example, a GET request to the URI listed above might return this response body:

    {"orderId":1,"orderValue":99.90,"productId":1,"quantity":1}
    
  • REST API では、クライアントとサービスの実装の分離に役立つ統一インターフェイスを使用します。REST APIs use a uniform interface, which helps to decouple the client and service implementations. HTTP を基盤とする REST API の場合、統一インターフェイスで標準の HTTP 動詞を使用して、リソースに対する操作を実行します。For REST APIs built on HTTP, the uniform interface includes using standard HTTP verbs to perform operations on resources. 最も一般的な操作は、GET、POST、PUT、PATCH、DELETE です。The most common operations are GET, POST, PUT, PATCH, and DELETE.

  • REST API では、ステートレスな要求モデルを使用します。REST APIs use a stateless request model. HTTP 要求は独立しており、任意の順序で発生する可能性があるため、要求間の遷移状態の情報を保持することはできません。HTTP requests should be independent and may occur in any order, so keeping transient state information between requests is not feasible. 情報の格納場所はリソース自体のみであり、それぞれの要求はアトミックな操作である必要があります。The only place where information is stored is in the resources themselves, and each request should be an atomic operation. この制約により、非常にスケーラブルな Web サービスが実現します。クライアントと特定のサーバー間のアフィニティを保持する必要がないためです。This constraint enables web services to be highly scalable, because there is no need to retain any affinity between clients and specific servers. どのサーバーも、任意のクライアントからの要求を処理できます。Any server can handle any request from any client. ただし、他の要因によってスケーラビリティが制限される可能性があります。That said, other factors can limit scalability. たとえば、多くの Web サービスは、スケールアウトが難しい可能性のあるバックエンド データ ストアに書き込みを行います (データ ストアのスケールアウト戦略については、「データのパーティション分割」をご覧ください)。For example, many web services write to a backend data store, which may be hard to scale out. (The article Data Partitioning describes strategies to scale out a data store.)

  • REST API は、表現に含まれているハイパーメディア リンクによって動作します。REST APIs are driven by hypermedia links that are contained in the representation. たとえば、次の例は注文の JSON 表現を示しています。For example, the following shows a JSON representation of an order. これには、注文に関連付けられた顧客を取得または更新するためのリンクが含まれています。It contains links to get or update the customer associated with the order.

    {
        "orderID":3,
        "productID":2,
        "quantity":4,
        "orderValue":16.60,
        "links": [
            {"rel":"product","href":"http://adventure-works.com/customers/3", "action":"GET" },
            {"rel":"product","href":"http://adventure-works.com/customers/3", "action":"PUT" } 
        ]
    } 
    

2008 年に、レオナルド・リチャードソンが Web API の次の成熟度モデルを提唱しました。In 2008, Leonard Richardson proposed the following maturity model for web APIs:

  • レベル 0: 1 つの URI を定義し、すべての操作がこの URI に対する POST 要求です。Level 0: Define one URI, and all operations are POST requests to this URI.
  • レベル 1: リソースごとに個別の URI を作成します。Level 1: Create separate URIs for individual resources.
  • レベル 2: HTTP メソッドを使用して、リソースに対する操作を定義します。Level 2: Use HTTP methods to define operations on resources.
  • レベル 3: ハイパーメディアを使用します (後述の HATEOAS)。Level 3: Use hypermedia (HATEOAS, described below).

フィールディングの定義に従うと、レベル 3 が真の RESTful API になります。Level 3 corresponds to a truly RESTful API according to Fielding's definition. 実際には、公開されている多くの Web API がほぼレベル 2 に位置します。In practice, many published web APIs fall somewhere around level 2.

リソースを中心とした API の整理Organize the API around resources

Web API が公開するビジネス エンティティに注目して説明します。Focus on the business entities that the web API exposes. たとえば、電子商取引システムでは、主エンティティは顧客と注文です。For example, in an e-commerce system, the primary entities might be customers and orders. 注文の作成は、注文情報が含まれた HTTP POST 要求を送信することで実現できます。Creating an order can be achieved by sending an HTTP POST request that contains the order information. HTTP 応答では、注文が正常に行われたかどうかを示します。The HTTP response indicates whether the order was placed successfully or not. 可能であれば、リソース URI は動詞 (リソースに対する操作) ではなく、名詞 (リソース) に基づくようにします。When possible, resource URIs should be based on nouns (the resource) and not verbs (the operations on the resource).

http://adventure-works.com/orders // Good

http://adventure-works.com/create-order // Avoid

リソースは、単一の物理データ項目に基づく必要はありません。A resource does not have to be based on a single physical data item. たとえば、注文リソースをリレーショナル データベースの複数のテーブルとして内部的に実装しながら、クライアントには単一のエンティティとして表示することができます。For example, an order resource might be implemented internally as several tables in a relational database, but presented to the client as a single entity. データベースの内部構造を単にミラー化する API は作成しないようにします。Avoid creating APIs that simply mirror the internal structure of a database. REST の目的は、エンティティと、アプリケーションがそれらのエンティティに対して実行できる操作をモデル化することです。The purpose of REST is to model entities and the operations that an application can perform on those entities. クライアントを内部実装に公開しないでください。A client should not be exposed to the internal implementation.

多くの場合、エンティティはコレクション (orders、customers) にグループ化されます。Entities are often grouped together into collections (orders, customers). コレクションはコレクションの項目とは別のリソースであり、独自の URI が必要です。A collection is a separate resource from the item within the collection, and should have its own URI. たとえば、次の URI は注文のコレクションを表しています。For example, the following URI might represent the collection of orders:

http://adventure-works.com/orders

コレクション URI に HTTP GET 要求を送信することで、コレクションの項目の一覧を取得します。Sending an HTTP GET request to the collection URI retrieves a list of items in the collection. コレクションの各項目にも、それぞれ一意の URI があります。Each item in the collection also has its own unique URI. 項目の URI に対する HTTP GET 要求では、その項目の詳細が返されます。An HTTP GET request to the item's URI returns the details of that item.

URI には一貫性のある名前付け規則を使用します。Adopt a consistent naming convention in URIs. 一般に、コレクションを参照する URI には複数形の名詞を使用すると便利です。In general, it helps to use plural nouns for URIs that reference collections. コレクションと項目の URI は、階層構造に整理することをお勧めします。It's a good practice to organize URIs for collections and items into a hierarchy. たとえば、/customers は customers コレクションのパスであり、/customers/5 は ID が 5 の顧客のパスです。For example, /customers is the path to the customers collection, and /customers/5 is the path to the customer with ID equal to 5. この方法は、Web API を直感的に保つのに役立ちます。This approach helps to keep the web API intuitive. また、多くの Web API フレームワークでは、パラメーター化された URI パスに基づいて要求をルーティングできるので、パス /customers/{id} のルートを定義できます。Also, many web API frameworks can route requests based on parameterized URI paths, so you could define a route for the path /customers/{id}.

さまざまな種類のリソース間の関係と、これらの関連付けを公開する方法も検討します。Also consider the relationships between different types of resources and how you might expose these associations. たとえば、/customers/5/orders は顧客 5 のすべての注文を表します。For example, the /customers/5/orders might represent all of the orders for customer 5. 逆方向にし、/orders/99/customer などの URI を使用して、注文から顧客への関連付けを表すこともできます。You could also go in the other direction, and represent the association from an order back to a customer with a URI such as /orders/99/customer. ただし、このモデルを拡張しすぎると、実装が煩雑になる可能性があります。However, extending this model too far can become cumbersome to implement. より優れたソリューションは、HTTP 応答メッセージの本文に、関連するリソースに誘導できるリンクを含めることです。A better solution is to provide navigable links to associated resources in the body of the HTTP response message. このメカニズムについては、関連リソースへのナビゲーションを可能にする HATEOAS アプローチの使用に関するセクションで詳しく説明します。This mechanism is described in more detail in the section Using the HATEOAS Approach to Enable Navigation To Related Resources later.

複雑なシステムでは、クライアント が複数のレベルの関係をナビゲートできるようにする URI (例: /customers/1/orders/99/products) を提供したくなる可能性があります。In more complex systems, it can be tempting to provide URIs that enable a client to navigate through several levels of relationships, such as /customers/1/orders/99/products. ただし、将来的にリソース間のリレーションシップが変わる場合、このレベルの複雑さを維持するのは難しく、柔軟性がありません。However, this level of complexity can be difficult to maintain and is inflexible if the relationships between resources change in the future. 代わりに、URI を比較的単純に保つように努めます。Instead, try to keep URIs relatively simple. アプリケーションがリソースへの参照を取得したら、この参照を使用してそのリソースに関連する項目を検索できるようにします。Once an application has a reference to a resource, it should be possible to use this reference to find items related to that resource. 前述のクエリを URI /customers/1/orders に置き換えると、顧客 1 のすべての注文を検索でき、次に /orders/99/products に置き換えると、この注文の製品を検索できます。The preceding query can be replaced with the URI /customers/1/orders to find all the orders for customer 1, and then /orders/99/products to find the products in this order.

ヒント

"コレクション/項目/コレクション" よりも複雑なリソース URI を要求しないでください。Avoid requiring resource URIs more complex than collection/item/collection.

Web 要求はいずれも Web サーバーに負荷をかけるという点も考慮します。Another factor is that all web requests impose a load on the web server. 要求が増えるほど、負荷も大きくなります。The more requests, the bigger the load. そのため、多数の小さなリソースを公開する "おしゃべりな" Web API にならないようにしてください。Therefore, try to avoid "chatty" web APIs that expose a large number of small resources. このような API では、クライアント アプリケーションが必要なすべてのデータを検索するために、複数の要求を送信することが必要になる場合があります。Such an API may require a client application to send multiple requests to find all of the data that it requires. 代わりに、データを非正規化し、1 つの要求で取得できるより大きなリソースに関連情報をまとめることができます。Instead, you might want to denormalize the data and combine related information into bigger resources that can be retrieved with a single request. ただし、このアプローチでは、クライアントが必要としないデータをフェッチするオーバーヘッドとバランスを取る必要があります。However, you need to balance this approach against the overhead of fetching data that the client doesn't need. ラージ オブジェクトを取得すると、要求の待機時間が増加し、追加の帯域幅コストが発生する可能性があります。Retrieving large objects can increase the latency of a request and incur additional bandwidth costs. これらのパフォーマンスのアンチパターンの詳細については、頻度の高い I/O に関する記事、および余分なフェッチに関する記事をご覧ください。For more information about these performance antipatterns, see Chatty I/O and Extraneous Fetching.

Web API と基になるデータ ソース間に依存関係を導入しないようにします。Avoid introducing dependencies between the web API and the underlying data sources. たとえば、データがリレーショナル データベースに格納されている場合、Web API は各テーブルをリソースのコレクションとして公開する必要はありません。For example, if your data is stored in a relational database, the web API doesn't need to expose each table as a collection of resources. 実際には、これは不適切な設計と考えられます。In fact, that's probably a poor design. 代わりに、Web API をデータベースの抽象化と捉えます。Instead, think of the web API as an abstraction of the database. 必要に応じて、データベースと Web API 間のマッピング レイヤーを導入します。If necessary, introduce a mapping layer between the database and the web API. これにより、クライアント アプリケーションは基になるデータベース スキームの変更から分離されます。That way, client applications are isolated from changes to the underlying database scheme.

最後に、Web API により実装されるすべての操作を特定のリソースにマッピングできない場合があります。Finally, it might not be possible to map every operation implemented by a web API to a specific resource. 機能を呼び出し、HTTP 応答メッセージとして結果を返す HTTP 要求によって、そのような "非リソース" シナリオに対応できます。You can handle such non-resource scenarios through HTTP requests that invoke a function and return the results as an HTTP response message. たとえば、加算や減算などの単純な電卓操作を実装する Web API は、これらの操作を疑似リソースとして公開し、クエリ文字列を使用して必要なパラメーターを指定する URI を提供できます。For example, a web API that implements simple calculator operations such as add and subtract could provide URIs that expose these operations as pseudo resources and use the query string to specify the parameters required. たとえば、URI /add?operand1=99&operand2=1 に対する GET 要求では、本文に値 100 が含まれた応答メッセージが返されます。For example a GET request to the URI /add?operand1=99&operand2=1 would return a response message with the body containing the value 100. ただし、これらの形式の URI は常に慎重に使用してください。However, only use these forms of URIs sparingly.

HTTP メソッドに関する操作の定義Define operations in terms of HTTP methods

HTTP プロトコルにより、要求にセマンティックな意味を割り当てる多くのメソッドが定義されます。The HTTP protocol defines a number of methods that assign semantic meaning to a request. ほとんどの RESTful Web API により使用される一般的な HTTP メソッドは次のとおりです。The common HTTP methods used by most RESTful web APIs are:

  • GET: 指定した URI のリソースの表現を取得します。GET retrieves a representation of the resource at the specified URI. 応答メッセージの本文には、要求されたリソースの詳細が含まれています。The body of the response message contains the details of the requested resource.
  • POST: 指定した URI の新しいリソースを作成します。POST creates a new resource at the specified URI. 応答メッセージの本文には、新しいリソースの詳細が記載されています。The body of the request message provides the details of the new resource. POST は実際にはリソースを作成しない操作をトリガーするのにも使用できます。Note that POST can also be used to trigger operations that don't actually create resources.
  • PUT: 指定した URI のリソースを作成または置換します。PUT either creates or replaces the resource at the specified URI. 要求メッセージの本文で、作成または更新するリソースを指定します。The body of the request message specifies the resource to be created or updated.
  • PATCH: リソースの部分的な更新を実行します。PATCH performs a partial update of a resource. 要求本文でリソースに適用する一連の変更を指定します。The request body specifies the set of changes to apply to the resource.
  • DELETE: 指定した URI のリソースを削除します。DELETE removes the resource at the specified URI.

特定の要求の影響は、リソースがコレクションと個々の項目のどちらであるかによって異なります。The effect of a specific request should depend on whether the resource is a collection or an individual item. 以下の表では、電子商取引の例を使用しながら、ほとんどの RESTful の実装で使用される一般的な規則をまとめています。The following table summarizes the common conventions adopted by most RESTful implementations using the ecommerce example. これらの要求がすべて実装されない場合があります。具体的なシナリオにより異なります。Note that not all of these requests might be implemented; it depends on the specific scenario.

リソースResource POSTPOST GETGET PUTPUT DELETEDELETE
/customers/customers 新しい顧客を作成Create a new customer すべての顧客を取得Retrieve all customers 顧客を一括更新Bulk update of customers すべての顧客を削除Remove all customers
/customers/1/customers/1 エラーError 顧客 1 の詳細を取得Retrieve the details for customer 1 顧客 1 の詳細を更新 (顧客 1 が存在する場合)Update the details of customer 1 if it exists 顧客 1 を削除Remove customer 1
/customers/1/orders/customers/1/orders 顧客 1 の新しい注文を作成Create a new order for customer 1 顧客 1 のすべての注文を取得Retrieve all orders for customer 1 顧客 1 の注文を一括更新Bulk update of orders for customer 1 顧客 1 のすべての注文を削除Remove all orders for customer 1

POST、PUT、PATCH の違いがわかりにくい可能性があります。The differences between POST, PUT, and PATCH can be confusing.

  • POST 要求ではリソースを作成します。A POST request creates a resource. サーバーは新しいリソースの URI を割り当て、その URI をクライアントに返します。The server assigns a URI for the new resource, and returns that URI to the client. REST モデルでは、POST 要求をコレクションに適用することがよくあります。In the REST model, you frequently apply POST requests to collections. 新しいリソースがコレクションに追加されます。The new resource is added to the collection. POST 要求を使用して、新しいリソースを作成せずに、処理するデータを既存のリソースに送信することもできます。A POST request can also be used to submit data for processing to an existing resource, without any new resource being created.

  • PUT 要求では、リソースの作成または既存のリソースの更新を行います。A PUT request creates a resource or updates an existing resource. クライアントがリソースの URI を指定します。The client specifies the URI for the resource. 要求本文には、リソースの完全な表現が含まれます。The request body contains a complete representation of the resource. この URI を使用するリソースが既に存在する場合は、そのリソースが置き換えられます。If a resource with this URI already exists, it is replaced. それ以外の場合は、新しいリソースが作成されます (サーバーが作成をサポートしている場合)。Otherwise a new resource is created, if the server supports doing so. PUT 要求は、コレクションではなく、個々の項目 (特定の顧客など) であるリソースに最も頻繁に適用されます。PUT requests are most frequently applied to resources that are individual items, such as a specific customer, rather than collections. サーバーが PUT を介した更新をサポートしていても、作成はサポートしていないことがあります。A server might support updates but not creation via PUT. PUT を介した作成をサポートするかどうかは、リソースが存在する前に、クライアントが意味のある方法でリソースに URI を割り当てることができるかどうかに左右されます。Whether to support creation via PUT depends on whether the client can meaningfully assign a URI to a resource before it exists. できない場合は、POST を使用してリソースを作成し、PUT または PATCH を使用して更新します。If not, then use POST to create resources and PUT or PATCH to update.

  • PATCH 要求では、既存のリソースに対して "部分的な更新" を実行します。A PATCH request performs a partial update to an existing resource. クライアントがリソースの URI を指定します。The client specifies the URI for the resource. 要求本文で、リソースに適用する一連の "変更" を指定します。The request body specifies a set of changes to apply to the resource. クライアントは、リソースの表現全体ではなく、変更のみを送信するため、PUT を使用するよりも効率的です。This can be more efficient than using PUT, because the client only sends the changes, not the entire representation of the resource. 技術的には、PATCH で ("null" リソースに対する一連の更新を指定することによって) 新しいリソースを作成することもできます (サーバーがこれをサポートしている場合)。Technically PATCH can also create a new resource (by specifying a set of updates to a "null" resource), if the server supports this.

PUT 要求はべき等である必要があります。PUT requests must be idempotent. クライアントが同じ PUT 要求を複数回送信した場合、結果は常に同じになります (同じリソースが同じ値で変更されます)。If a client submits the same PUT request multiple times, the results should always be the same (the same resource will be modified with the same values). POST 要求と PATCH 要求はべき等である保証はありません。POST and PATCH requests are not guaranteed to be idempotent.

HTTP セマンティクスへの準拠Conform to HTTP semantics

このセクションでは、HTTP 仕様に準拠した API の設計に関する一般的な考慮事項について説明します。This section describes some typical considerations for designing an API that conforms to the HTTP specification. ただし、考えられるすべての詳細やシナリオを取り上げているわけではありません。However, it doesn't cover every possible detail or scenario. 不確かな場合は、HTTP 仕様を参照してください。When in doubt, consult the HTTP specifications.

メディアの種類Media types

前述のように、クライアントとサーバーはリソースの表現を交換します。As mentioned earlier, clients and servers exchange representations of resources. たとえば、POST 要求では、要求本文に作成するリソースの表現が含まれます。For example, in a POST request, the request body contains a representation of the resource to create. GET 要求では、応答本文にフェッチされたリソースの表現が含まれます。In a GET request, the response body contains a representation of the fetched resource.

HTTP プロトコルでは、"メディアの種類" (MIME の種類とも呼ばれます) を使用して形式が指定されます。In the HTTP protocol, formats are specified through the use of media types, also called MIME types. 非バイナリ データの場合、ほとんどの Web API が JSON (メディアの種類 = application/json) をサポートしており、場合によっては XML (メディアの種類 = application/xml) もサポートしています。For non-binary data, most web APIs support JSON (media type = application/json) and possibly XML (media type = application/xml).

要求または応答の Content-Type ヘッダーでは、表現の形式を指定します。The Content-Type header in a request or response specifies the format of the representation. JSON データを含む POST 要求の例を次に示します。Here is an example of a POST request that includes JSON data:

POST http://adventure-works.com/orders HTTP/1.1
Content-Type: application/json; charset=utf-8
Content-Length: 57

{"Id":1,"Name":"Gizmo","Category":"Widgets","Price":1.99}

サーバーがこのメディアの種類をサポートしていない場合、HTTP 状態コード 415 (Unsupported Media Type) が返されます。If the server doesn't support the media type, it should return HTTP status code 415 (Unsupported Media Type).

クライアント要求には、クライアントが応答メッセージでサーバーから受け入れるメディアの種類の一覧を含む Accept ヘッダーを含めることができます。A client request can include an Accept header that contains a list of media types the client will accept from the server in the response message. 例: For example:

GET http://adventure-works.com/orders/2 HTTP/1.1
Accept: application/json

サーバーが記載されているメディアの種類のいずれかに対応できない場合、HTTP 状態コード406 (Not Acceptable) が返されます。If the server cannot match any of the media type(s) listed, it should return HTTP status code 406 (Not Acceptable).

GET メソッドGET methods

GET メソッドが成功すると、通常は HTTP 状態コード200 (OK) が返されます。A successful GET method typically returns HTTP status code 200 (OK). リソースが見つからない場合、メソッドは 404 (Not Found) を返します。If the resource cannot be found, the method should return 404 (Not Found).

POST メソッドPOST methods

POST メソッドは、新しいリソースを作成すると、HTTP 状態コード 201 (Created) を返します。If a POST method creates a new resource, it returns HTTP status code 201 (Created). 新しいリソースの URI は、応答の Location ヘッダーに含まれています。The URI of the new resource is included in the Location header of the response. 応答本文には、リソースの表現が含まれています。The response body contains a representation of the resource.

メソッドが新しいリソースの作成以外の処理を実行した場合は、HTTP 状態コード 200 を返し、応答本文に操作の結果を含めることができます。If the method does some processing but does not create a new resource, the method can return HTTP status code 200 and include the result of the operation in the response body. また、返す結果がない場合、メソッドは応答本文なしで HTTP 状態コード 204 (No Content) を返すことができます。Alternatively, if there is no result to return, the method can return HTTP status code 204 (No Content) with no response body.

クライアントが要求に無効なデータを挿入した場合、サーバーは HTTP 状態コード 400 (Bad Request) を返します。If the client puts invalid data into the request, the server should return HTTP status code 400 (Bad Request). 応答本文には、エラーに関する追加情報または詳細を提供する URI へのリンクを含めることができます。The response body can contain additional information about the error or a link to a URI that provides more details.

PUT メソッドPUT methods

POST メソッドと同様に、PUT メソッドは新しいリソースを作成すると、HTTP 状態コード 201 (Created) を返します。If a PUT method creates a new resource, it returns HTTP status code 201 (Created), as with a POST method. 既存のリソースを更新した場合は、200 (OK) または 204 (No Content) を返します。If the method updates an existing resource, it returns either 200 (OK) or 204 (No Content). 既存のリソースを更新できない場合もあります。In some cases, it might not be possible to update an existing resource. その場合は、HTTP 状態コード 409 (Conflict) を返すことを検討してください。In that case, consider returning HTTP status code 409 (Conflict).

コレクションの複数のリソースの更新をバッチ処理できる一括 HTTP PUT 操作の実装を検討してください。Consider implementing bulk HTTP PUT operations that can batch updates to multiple resources in a collection. PUT 要求はコレクションの URI を指定し、要求本文は変更するリソースの詳細を指定する必要があります。The PUT request should specify the URI of the collection, and the request body should specify the details of the resources to be modified. この方法によりおしゃべりを減らし、パフォーマンスを向上させることができます。This approach can help to reduce chattiness and improve performance.

PATCH メソッドPATCH methods

PATCH 要求では、クライアントがパッチ ドキュメントの形で既存のリソースに対する一連の更新を送信します。With a PATCH request, the client sends a set of updates to an existing resource, in the form of a patch document. サーバーはパッチ ドキュメントを処理して更新を実行します。The server processes the patch document to perform the update. パッチ ドキュメントは、リソース全体を記述するのではなく、適用する一連の変更のみを記述します。The patch document doesn't describe the whole resource, only a set of changes to apply. PATCH メソッドの仕様 (RFC 5789) では、パッチ ドキュメントの特定の形式は定義されていません。The specification for the PATCH method (RFC 5789) doesn't define a particular format for patch documents. 形式は、要求内のメディアの種類から推論する必要があります。The format must be inferred from the media type in the request.

JSON が Web API の最も一般的なデータ形式と考えられます。JSON is probably the most common data format for web APIs. 主な JSON ベースのパッチ形式として、JSON パッチJSON マージ パッチの 2 つがあります。There are two main JSON-based patch formats, called JSON patch and JSON merge patch.

JSON マージ パッチの方が若干シンプルです。JSON merge patch is somewhat simpler. パッチ ドキュメントは元の JSON リソースと同じ構造ですが、変更または追加する必要のあるフィールドのサブセットだけが含まれています。The patch document has the same structure as the original JSON resource, but includes just the subset of fields that should be changed or added. また、パッチ ドキュメントのフィールド値に null を指定することによって、そのフィールドを削除できます In addition, a field can be deleted by specifying null for the field value in the patch document. (つまり、元のリソースに明示的な null 値を含めることができる場合、マージ パッチは適していません)。(That means merge patch is not suitable if the original resource can have explicit null values.)

たとえば、元のリソースが次の JSON 表現を持つとします。For example, suppose the original resource has the following JSON representation:

{ 
    "name":"gizmo",
    "category":"widgets",
    "color":"blue",
    "price":10
}

このリソースの使用可能な JSON マージ パッチを次に示します。Here is a possible JSON merge patch for this resource:

{ 
    "price":12,
    "color":null,
    "size":"small"
}

これは、"price" を更新し、"color" を削除し、"size" を追加するようサーバーに指示しています。This tells the server to update "price", delete "color", and add "size". "name" と "category" は変更されません。"Name" and "category" are not modified. JSON マージ パッチの詳細については、RFC 7396 を参照してください。For the exact details of JSON merge patch, see RFC 7396. JSON マージパッチのメディアの種類は "application/merge-patch+json" です。The media type for JSON merge patch is "application/merge-patch+json".

マージ パッチでは、パッチ ドキュメントの null に特別な意味があるため、元のリソースに明示的な null 値を含めることができる場合、マージ パッチは適していません。Merge patch is not suitable if the original resource can contain explicit null values, due to the special meaning of null in the patch document. また、パッチ ドキュメントでは、サーバーが更新を適用する順序は指定されていません。Also, the patch document doesn't specify the order that the server should apply the updates. データとドメインによっては、これが重要な場合とそうでない場合があります。That may or may not matter, depending on the data and the domain. RFC 6902 で定義されている JSON パッチの方が柔軟性に優れています。JSON patch, defined in RFC 6902, is more flexible. 適用する一連の操作として変更を指定します。It specifies the changes as a sequence of operations to apply. 操作には、追加、削除、置換、コピー、テスト (値の検証) があります。Operations include add, remove, replace, copy, and test (to validate values). JSON パッチのメディアの種類は "application/json-patch+json" です。The media type for JSON patch is "application/json-patch+json".

PATCH 要求を処理するときに発生する可能性のある一般的なエラー状態と、該当する HTTP 状態コードを次に示します。Here are some typical error conditions that might be encountered when processing a PATCH request, along with the appropriate HTTP status code.

エラー状態Error condition HTTP 状態コードHTTP status code
パッチ ドキュメントの形式がサポートされていません。The patch document format isn't supported. 415 (Unsupported Media Type)415 (Unsupported Media Type)
無効な形式のパッチ ドキュメントです。Malformed patch document. 400 (Bad Request)400 (Bad Request)
パッチ ドキュメントは有効ですが、現在の状態のリソースに変更を適用することはできません。The patch document is valid, but the changes can't be applied to the resource in its current state. 409 (Conflict)409 (Conflict)

DELETE メソッドDELETE methods

削除操作が成功すると、Web サーバーは HTTP 状態コード 204 で応答します。これは、プロセスは正常に処理されたが、応答本文にそれ以上の情報は含まれていないことを示します。If the delete operation is successful, the web server should respond with HTTP status code 204, indicating that the process has been successfully handled, but that the response body contains no further information. リソースが存在しない場合、Web サーバーは HTTP 404 (Not Found) を返すことができます。If the resource doesn't exist, the web server can return HTTP 404 (Not Found).

非同期操作Asynchronous operations

POST、PUT、PATCH、または DELETE 操作では、完了までに時間のかかる処理が必要な場合があります。Sometimes a POST, PUT, PATCH, or DELETE operation might require processing that takes awhile to complete. 完了を待ってからクライアントに応答を送信すると、許容できない待機時間が発生する可能性があります。If you wait for completion before sending a response to the client, it may cause unacceptable latency. その場合は、操作を非同期にすることを検討してください。If so, consider making the operation asynchronous. HTTP 状態コード 202 (Accepted) を返して、要求が処理のために受理されたが、まだ完了していないことを示します。Return HTTP status code 202 (Accepted) to indicate the request was accepted for processing but is not completed.

クライアントが状態エンドポイントをポーリングして状態を監視できるように、非同期要求の状態を返すエンドポイントを公開する必要があります。You should expose an endpoint that returns the status of an asynchronous request, so the client can monitor the status by polling the status endpoint. 202 応答の Location ヘッダーに、状態エンドポイントの URI を含めます。Include the URI of the status endpoint in the Location header of the 202 response. 例: For example:

HTTP/1.1 202 Accepted
Location: /api/status/12345

クライアントがこのエンドポイントに GET 要求を送信した場合、応答に要求の現在の状態を含める必要があります。If the client sends a GET request to this endpoint, the response should contain the current status of the request. 必要に応じて、完了までの推定時間や操作を取り消すためのリンクを含めることもできます。Optionally, it could also include an estimated time to completion or a link to cancel the operation.

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status":"In progress",
    "link": { "rel":"cancel", "method":"delete", "href":"/api/status/12345" }
}

非同期操作で新しいリソースを作成する場合、状態エンドポイントは、操作の完了後に状態コード 303 (See Other) を返す必要があります。If the asynchronous operation creates a new resource, the status endpoint should return status code 303 (See Other) after the operation completes. 303 応答には、新しいリソースの URI を示す Location ヘッダーを含めます。In the 303 response, include a Location header that gives the URI of the new resource:

HTTP/1.1 303 See Other
Location: /api/orders/12345

詳細については、「Asynchronous operations in REST (REST での非同期操作)」をご覧ください。For more information, see Asynchronous operations in REST.

データのフィルター処理とページング処理Filter and paginate data

単一の URI を使用してリソースのコレクションを公開すると、情報のサブセットだけが必要な場合に、アプリケーションが大量のデータをフェッチする可能性があります。Exposing a collection of resources through a single URI can lead to applications fetching large amounts of data when only a subset of the information is required. たとえば、クライアント アプリケーションが、コストが特定の値を超えるすべての注文を検索する必要があるとします。For example, suppose a client application needs to find all orders with a cost over a specific value. /orders URI からすべての注文を取得し、クライアント側でこれらの注文をフィルター処理します。It might retrieve all orders from the /orders URI and then filter these orders on the client side. このプロセスが非常に非効率的であることは明らかです。Clearly this process is highly inefficient. Web API をホストするサーバーのネットワーク帯域幅と処理能力が無駄になります。It wastes network bandwidth and processing power on the server hosting the web API.

代わりに、API は URI のクエリ文字列でフィルター (例: /orders?minCost=n) を渡すことを許可することができます。Instead, the API can allow passing a filter in the query string of the URI, such as /orders?minCost=n. Web API は、クエリ文字列の minCost パラメーターを解析して処理し、サーバー側でフィルター処理された結果を返す役割を担います。The web API is then responsible for parsing and handling the minCost parameter in the query string and returning the filtered results on the sever side.

コレクション リソースに対する GET 要求では、多数の項目が返される可能性があります。GET requests over collection resources can potentially return a large number of items. 1 つの要求で返されるデータの量を制限するように Web API を設計する必要があります。You should design a web API to limit the amount of data returned by any single request. 取得する項目の最大数とコレクションの開始オフセットを指定するクエリ文字列のサポートを検討します。Consider supporting query strings that specify the maximum number of items to retrieve and a starting offset into the collection. 例: For example:

/orders?limit=25&offset=50

サービス拒否攻撃を防ぐために、返される項目の数に上限を課すことも検討してください。Also consider imposing an upper limit on the number of items returned, to help prevent Denial of Service attacks. クライアント アプリケーションを支援するには、改ページ調整されたデータを返す GET 要求に、コレクションで利用できるリソースの合計を示す何らかの形式のメタデータも含まれるようにします。To assist client applications, GET requests that return paginated data should also include some form of metadata that indicate the total number of resources available in the collection. また、他のインテリジェントなページング方法を検討することもできます。詳細については、「API Design Notes: Smart Paging (API の設計に関する注記: スマート ページング)」を参照してください。You might also consider other intelligent paging strategies; for more information, see API Design Notes: Smart Paging

同様の方法を使用して、フェッチされたデータを並べ替えることができます。/orders?sort=ProductID のように、フィールド名を値として取得する並べ替えパラメーターを指定します。You can use a similar strategy to sort data as it is fetched, by providing a sort parameter that takes a field name as the value, such as /orders?sort=ProductID. ただし、クエリ文字列パラメーターは、キャッシュ データのキーとして多くのキャッシュ実装で使用されるリソース識別子の一部となるため、この方法はキャッシュに悪影響を与える可能性があります。However, this approach can have a negative effect on caching, because query string parameters form part of the resource identifier used by many cache implementations as the key to cached data.

各項目に大量のデータが含まれている場合、返されるフィールドを項目ごとに制限するように、この方法を拡張できます。You can extend this approach to limit the fields returned for each item, if each item contains a large amount of data. たとえば、/orders?fields=ProductID,Quantity など、コンマ区切りのフィールド一覧を受け取るクエリ文字列パラメーターを使用することができます。For example, you could use a query string parameter that accepts a comma-delimited list of fields, such as /orders?fields=ProductID,Quantity.

クエリ文字列内の省略可能なすべてのパラメーターに、意味のある既定値を設定します。Give all optional parameters in query strings meaningful defaults. たとえば、改ページ調整を実装する場合は limit パラメーターを 10、offset パラメーターを 0 に設定し、順序付けを実装する場合はリソースのキーに並べ替えパラメーターを設定し、プロジェクションをサポートする場合はfields パラメーターをリソースのすべてのフィールドに設定します。For example, set the limit parameter to 10 and the offset parameter to 0 if you implement pagination, set the sort parameter to the key of the resource if you implement ordering, and set the fields parameter to all fields in the resource if you support projections.

大きなバイナリ リソースの部分的な応答のサポートSupport partial responses for large binary resources

リソースに大きなバイナリ フィールド (ファイルや画像など) が含まれている場合があります。A resource may contain large binary fields, such as files or images. 信頼性の低い断続的な接続に起因する問題を克服し、応答時間を向上させるには、このようなリソースをチャンクで取得できるようにすることを検討します。To overcome problems caused by unreliable and intermittent connections and to improve response times, consider enabling such resources to be retrieved in chunks. そのためには、Web API が大きなリソースの GET 要求で Accept-Ranges ヘッダーをサポートする必要があります。To do this, the web API should support the Accept-Ranges header for GET requests for large resources. このヘッダーは、GET 操作が部分的な要求をサポートすることを示します。This header indicates that the GET operation supports partial requests. クライアント アプリケーションは、バイト範囲として指定されたリソースのサブセットを返す GET 要求を送信できます。The client application can submit GET requests that return a subset of a resource, specified as a range of bytes.

これらのリソースの HTTP HEAD 要求を実装することも検討してください。Also, consider implementing HTTP HEAD requests for these resources. HEAD 要求は GET 要求に似ていますが、空のメッセージ本文と共に、リソースを示す HTTP ヘッダーだけを返す点が異なります。A HEAD request is similar to a GET request, except that it only returns the HTTP headers that describe the resource, with an empty message body. クライアント アプリケーションは HEAD 要求を発行し、部分的 GET 要求を使用して、リソースを取得するかどうかを判断します。A client application can issue a HEAD request to determine whether to fetch a resource by using partial GET requests. 例: For example:

HEAD http://adventure-works.com/products/10?fields=productImage HTTP/1.1

応答メッセージの例を次に示します。Here is an example response message:

HTTP/1.1 200 OK

Accept-Ranges: bytes
Content-Type: image/jpeg
Content-Length: 4580

Content-Length ヘッダーはリソースの合計サイズを示し、Accept-Ranges ヘッダーは対応する GET 操作が部分的な結果をサポートすることを示します。The Content-Length header gives the total size of the resource, and the Accept-Ranges header indicates that the corresponding GET operation supports partial results. クライアント アプリケーションは、この情報を使用して画像を小さなチャンクで取得できます。The client application can use this information to retrieve the image in smaller chunks. 最初の要求では、Range ヘッダーを使用して最初の 2,500 バイトを取得します。The first request fetches the first 2500 bytes by using the Range header:

GET http://adventure-works.com/products/10?fields=productImage HTTP/1.1
Range: bytes=0-2499

応答メッセージは、HTTP 状態コード 206 を返すことで、これが部分的な応答であることを示します。The response message indicates that this is a partial response by returning HTTP status code 206. Content-Length ヘッダーはメッセージ本文で返される実際のバイト数を指定し (リソースのサイズではない)、Content-Range ヘッダーはこれがどの部分のリソースであるかを示します (4,580 のうち 0 ~ 2499 バイト):The Content-Length header specifies the actual number of bytes returned in the message body (not the size of the resource), and the Content-Range header indicates which part of the resource this is (bytes 0-2499 out of 4580):

HTTP/1.1 206 Partial Content

Accept-Ranges: bytes
Content-Type: image/jpeg
Content-Length: 2500
Content-Range: bytes 0-2499/4580

[...]

クライアント アプリケーションのその後の要求で、リソースの残りの部分を取得できます。A subsequent request from the client application can retrieve the remainder of the resource.

REST の背後にある主な動機の 1 つは、URI スキームの事前知識を必要とせずに、リソースのセット全体を移動できることです。One of the primary motivations behind REST is that it should be possible to navigate the entire set of resources without requiring prior knowledge of the URI scheme. 各 HTTP GET 要求は応答に含まれるハイパーリンクより、要求したオブジェクトに直接関連するリソースを検索するのに必要な情報を返し、これらの各リソースで使用可能な操作を記述する情報も提供されます。Each HTTP GET request should return the information necessary to find the resources related directly to the requested object through hyperlinks included in the response, and it should also be provided with information that describes the operations available on each of these resources. この原則は HATEOAS、つまり アプリケーション状態のエンジンとしてのハイパーテキストとして知られます。This principle is known as HATEOAS, or Hypertext as the Engine of Application State. システムは効率的に Finite State Machine であり、各要求への応答には、ある状態を別の状態に移すのに必要な情報が含まれています。他の情報は必要ありません。The system is effectively a finite state machine, and the response to each request contains the information necessary to move from one state to another; no other information should be necessary.

注意

現在、HATEOAS の原則をモデル化する方法を定義する標準や仕様はありません。Currently there are no standards or specifications that define how to model the HATEOAS principle. このセクションで示されている例は、可能性のある一つのソリューションを示しています。The examples shown in this section illustrate one possible solution.

たとえば、注文と顧客の関係を処理するために、注文の表現にその注文の顧客に対して使用できる操作を示すリンクを含めることができます。For example, to handle the relationship between an order and a customer, the representation of an order could include links that identify the available operations for the customer of the order. 使用可能な表現を次に示します。Here is a possible representation:

{
  "orderID":3,
  "productID":2,
  "quantity":4,
  "orderValue":16.60,
  "links":[
    {
      "rel":"customer",
      "href":"http://adventure-works.com/customers/3", 
      "action":"GET",
      "types":["text/xml","application/json"] 
    },
    {
      "rel":"customer",
      "href":"http://adventure-works.com/customers/3", 
      "action":"PUT",
      "types":["application/x-www-form-urlencoded"]
    },
    {
      "rel":"customer",
      "href":"http://adventure-works.com/customers/3",
      "action":"DELETE",
      "types":[]
    },
    {
      "rel":"self",
      "href":"http://adventure-works.com/orders/3", 
      "action":"GET",
      "types":["text/xml","application/json"]
    },
    {
      "rel":"self",
      "href":"http://adventure-works.com/orders/3", 
      "action":"PUT",
      "types":["application/x-www-form-urlencoded"]
    },
    {
      "rel":"self",
      "href":"http://adventure-works.com/orders/3", 
      "action":"DELETE",
      "types":[]
    }]
}

この例では、links 配列に一連のリンクが含まれています。In this example, the links array has a set of links. 各リンクは、関連エンティティに対する操作を表しています。Each link represents an operation on a related entity. 各リンクのデータには、関係 ("customer")、URI (http://adventure-works.com/customers/3)、HTTP メソッド、サポートされる MIME の種類が含まれています。The data for each link includes the relationship ("customer"), the URI (http://adventure-works.com/customers/3), the HTTP method, and the supported MIME types. クライアント アプリケーションが操作を呼び出すことができるようにするために必要な情報はこれですべてです。This is all the information that a client application needs to be able to invoke the operation.

links 配列には、取得したリソース自体に関する自己参照型の情報も含まれています。The links array also includes self-referencing information about the resource itself that has been retrieved. これらの情報の関係は self です。These have the relationship self.

返されるリンクのセットは、リソースの状態によって変わる可能性があります。The set of links that are returned may change, depending on the state of the resource. "アプリケーション状態のエンジン" であるハイパーリンクとはこのことです。This is what is meant by hypertext being the "engine of application state."

RESTful Web API のバージョン管理Versioning a RESTful web API

Web API が更新されないことはありえません。It is highly unlikely that a web API will remain static. ビジネスの要求は変化するため、新しいリソースのコレクションが加わり、リソース間のリレーションシップが変化し、リソース内のデータ構造が修正される可能性があります。As business requirements change new collections of resources may be added, the relationships between resources might change, and the structure of the data in resources might be amended. 新しいまたは異なる要件を処理するために Web API を更新することは比較的簡単なプロセスですが、そのような変化が Web API を消費するクライアント アプリケーションに対して与える影響を考慮する必要があります。While updating a web API to handle new or differing requirements is a relatively straightforward process, you must consider the effects that such changes will have on client applications consuming the web API. 問題なのは、Web API を設計および実装している開発者はその API を完全に制御できるものの、リモートで操作しているサードパーティの組織により構築されたクライアント アプリケーションを、その開発者が同程度には制御できないことです。The issue is that although the developer designing and implementing a web API has full control over that API, the developer does not have the same degree of control over client applications which may be built by third party organizations operating remotely. まず必要なのは、新しいクライアント アプリケーションが新しい機能やリソースを活用できるようにしながら、既存のアプリケーションに変更なく機能を続行させることです。The primary imperative is to enable existing client applications to continue functioning unchanged while allowing new client applications to take advantage of new features and resources.

バージョン管理により Web API は公開する機能およびリソースを示すことができ、クライアント アプリケーションは特定のバージョンの機能またはリソースへの要求を送信できます。Versioning enables a web API to indicate the features and resources that it exposes, and a client application can submit requests that are directed to a specific version of a feature or resource. 次のセクションではいくつかの方法について説明しますが、それぞれに独自の利点とトレードオフがあります。The following sections describe several different approaches, each of which has its own benefits and trade-offs.

バージョン管理なしNo versioning

これは最も単純な方法で、一部の内部 API で許容されます。This is the simplest approach, and may be acceptable for some internal APIs. 大きな変更は新しいリソースまたは新しいリンクとして示されます。Big changes could be represented as new resources or new links. 既存のリソースにコンテンツを追加しても、このコンテンツの表示を想定していないクライアント アプリケーションはそれを無視するだけであるため、重大な変更はありません。Adding content to existing resources might not present a breaking change as client applications that are not expecting to see this content will simply ignore it.

たとえば、URI http://adventure-works.com/customers/3 への要求により、次のクライアント アプリケーションにより期待される idname、および address フィールドを含む単一の顧客に関する詳細が返されます。For example, a request to the URI http://adventure-works.com/customers/3 should return the details of a single customer containing id, name, and address fields expected by the client application:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"id":3,"name":"Contoso LLC","address":"1 Microsoft Way Redmond WA 98053"}

注意

わかりやすくするために、このセクションで示す応答例には HATEOAS リンクは含まれていません。For simplicity, the example responses shown in this section do not include HATEOAS links.

DateCreated フィールドが顧客リソースのスキーマに追加される場合、応答は次のようになります。If the DateCreated field is added to the schema of the customer resource, then the response would look like this:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"id":3,"name":"Contoso LLC","dateCreated":"2014-09-04T12:11:38.0376089Z","address":"1 Microsoft Way Redmond WA 98053"}

既存のクライアント アプリケーションが認識されていないフィールドを無視できる場合は、正常に機能を続行する場合がありますが、新しいクライアント アプリケーションではこの新しいフィールドを処理するように設計できます。Existing client applications might continue functioning correctly if they are capable of ignoring unrecognized fields, while new client applications can be designed to handle this new field. とはいえ、リソースのスキーマにさらに重大な変更があるか (フィールドの削除や名前の変更など)、リソース間のリレーションシップが変更される場合、これらは既存のクライアント アプリケーションが正常に機能できなくなる重大な変更となる可能性があります。However, if more radical changes to the schema of resources occur (such as removing or renaming fields) or the relationships between resources change then these may constitute breaking changes that prevent existing client applications from functioning correctly. このような状況では、次の方法のいずれかを検討してください。In these situations you should consider one of the following approaches.

URI のバージョン管理URI versioning

Web API を変更するか、リソースのスキーマを変更するたびに、バージョン番号を各リソースの URI に追加します。Each time you modify the web API or change the schema of resources, you add a version number to the URI for each resource. 既存の URI はこれまでと同様に動作を続け、元のスキーマに準拠するリソースを返します。The previously existing URIs should continue to operate as before, returning resources that conform to their original schema.

前の例を拡張し、address フィールドをアドレスの各構成部分 (streetAddresscitystatezipCode など) を含むサブフィールドに再構築する場合、このバージョンのリソースはバージョン番号を含む http://adventure-works.com/v2/customers/3: などの URI より公開できますExtending the previous example, if the address field is restructured into sub-fields containing each constituent part of the address (such as streetAddress, city, state, and zipCode), this version of the resource could be exposed through a URI containing a version number, such as http://adventure-works.com/v2/customers/3:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"id":3,"name":"Contoso LLC","dateCreated":"2014-09-04T12:11:38.0376089Z","address":{"streetAddress":"1 Microsoft Way","city":"Redmond","state":"WA","zipCode":98053}}

このバージョン管理メカニズムは非常に単純ですが、適切なエンドポイントに要求をルーティングするサーバーにより変わります。This versioning mechanism is very simple but depends on the server routing the request to the appropriate endpoint. とはいえ、Web API は何度も繰り返すことで成熟し、サーバーは多くの異なるバージョンをサポートする必要があるため、扱いにくくなる可能性があります。However, it can become unwieldy as the web API matures through several iterations and the server has to support a number of different versions. また、純正主義者の観点からすると、すべての場合でクライアント アプリケーションは同じデータを取得しているため (顧客 3)、URI はバージョンによってそれほど異なるべきではありません。Also, from a purist’s point of view, in all cases the client applications are fetching the same data (customer 3), so the URI should not really be different depending on the version. すべてのリンクで URI にバージョン番号が含まれる必要があるため、このスキームによっても HATEOAS の実装が複雑になります。This scheme also complicates implementation of HATEOAS as all links will need to include the version number in their URIs.

クエリ文字列のバージョン管理Query string versioning

複数の URI を提供するのではなく、http://adventure-works.com/customers/3?version=2 など、HTTP 要求に追加されたクエリ文字列内のパラメーターを使用してリソースのバージョンを指定できます。Rather than providing multiple URIs, you can specify the version of the resource by using a parameter within the query string appended to the HTTP request, such as http://adventure-works.com/customers/3?version=2. バージョン パラメーターがより古いクライアント アプリケーションで省略される場合、1 などの有効な値を既定にします。The version parameter should default to a meaningful value such as 1 if it is omitted by older client applications.

この方法には同じリソースからは常に同じ URI が取得されるというセマンティックな利点がありますが、クエリ文字列を解析し、適切な HTTP 応答を返送する要求を処理するコードにより異なります。This approach has the semantic advantage that the same resource is always retrieved from the same URI, but it depends on the code that handles the request to parse the query string and send back the appropriate HTTP response. この方法は、URI のバージョン管理メカニズムとして HATEOAS を実装する同様の複雑さによっても影響されます。This approach also suffers from the same complications for implementing HATEOAS as the URI versioning mechanism.

注意

一部の古い Web ブラウザーや Web プロキシは、URI にクエリ文字列を含む要求の応答をキャッシュしません。Some older web browsers and web proxies will not cache responses for requests that include a query string in the URI. これは、Web API を使用し、そのような Web ブラウザー内から実行する Web アプリケーションのパフォーマンスに悪影響を与える可能性があります。This can have an adverse impact on performance for web applications that use a web API and that run from within such a web browser.

ヘッダーのバージョン管理Header versioning

バージョン番号をクエリ文字列パラメーターとして追加するのではなく、リソースのバージョンを示すカスタム ヘッダーを実装できます。Rather than appending the version number as a query string parameter, you could implement a custom header that indicates the version of the resource. この方法ではクライアント アプリケーションにより任意の要求に適切なヘッダーを追加する必要がありますが、バージョン ヘッダーが省略されている場合、クライアントの要求を処理するコードは既定値 (バージョン 1) を使用できます。This approach requires that the client application adds the appropriate header to any requests, although the code handling the client request could use a default value (version 1) if the version header is omitted. 次の例では、Custom-Header という名前のカスタム ヘッダーを使用します。The following examples utilize a custom header named Custom-Header. このヘッダーの値は、Web API のバージョンを示します。The value of this header indicates the version of web API.

バージョン 1: Version 1:

GET http://adventure-works.com/customers/3 HTTP/1.1
Custom-Header: api-version=1
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"id":3,"name":"Contoso LLC","address":"1 Microsoft Way Redmond WA 98053"}

バージョン 2: Version 2:

GET http://adventure-works.com/customers/3 HTTP/1.1
Custom-Header: api-version=2
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"id":3,"name":"Contoso LLC","dateCreated":"2014-09-04T12:11:38.0376089Z","address":{"streetAddress":"1 Microsoft Way","city":"Redmond","state":"WA","zipCode":98053}}

前の 2 つの方法と同様、HATEOAS の実装では任意のリンクに適切なカスタム ヘッダーを追加することが必要です。Note that as with the previous two approaches, implementing HATEOAS requires including the appropriate custom header in any links.

メディアの種類のバージョン管理Media type versioning

クライアント アプリケーションが Web サーバーに HTTP GET 要求を送信する場合、このガイダンスで既に説明したように、Accept ヘッダーを使用して処理できるコンテンツの書式を指定する必要があります。When a client application sends an HTTP GET request to a web server it should stipulate the format of the content that it can handle by using an Accept header, as described earlier in this guidance. 多くの場合、Accept ヘッダーの目的は、応答の本文が XML、JSON、またはクライアントが解析可能な他の一般的な形式であるかどうかをクライアント アプリケーションが指定できるようにすることです。Frequently the purpose of the Accept header is to allow the client application to specify whether the body of the response should be XML, JSON, or some other common format that the client can parse. とはいえ、想定しているリソースのバージョンをクライアント アプリケーションが示すことができるようにする情報を含むカスタム メディアの種類を定義できます。However, it is possible to define custom media types that include information enabling the client application to indicate which version of a resource it is expecting. 次の例は、application/vnd.adventure-works.v1+json の値を含む Accept ヘッダーを指定する要求を示します。The following example shows a request that specifies an Accept header with the value application/vnd.adventure-works.v1+json. vnd.adventure-works.v1 要素は Web サーバーに対し、バージョン 1 のリソースを返すように指示しますが、json 要素は応答本文の形式が JSON であるように指定します。The vnd.adventure-works.v1 element indicates to the web server that it should return version 1 of the resource, while the json element specifies that the format of the response body should be JSON:

GET http://adventure-works.com/customers/3 HTTP/1.1
Accept: application/vnd.adventure-works.v1+json

要求を処理しているコードは、Accept ヘッダーを処理し、可能な限りそれを使用します (クライアント アプリケーションは複数の形式を Accept ヘッダーで指定する場合があり、その場合 Web サーバーは最も適切な形式を応答本文に選択できます)。The code handling the request is responsible for processing the Accept header and honoring it as far as possible (the client application may specify multiple formats in the Accept header, in which case the web server can choose the most appropriate format for the response body). Web サーバーは次のように Content-Type ヘッダーを使用することで、応答本文のデータの形式を確認します。The web server confirms the format of the data in the response body by using the Content-Type header:

HTTP/1.1 200 OK
Content-Type: application/vnd.adventure-works.v1+json; charset=utf-8

{"id":3,"name":"Contoso LLC","address":"1 Microsoft Way Redmond WA 98053"}

Accept ヘッダーにより既知のメディアの種類が指定されない場合、Web サーバーは HTTP 406 (Not Acceptable) 応答メッセージを生成するか、既定のメディアの種類でメッセージを返すことができます。If the Accept header does not specify any known media types, the web server could generate an HTTP 406 (Not Acceptable) response message or return a message with a default media type.

この方法が最も純粋と思われるバージョン管理メカニズムで、当然ながら HATEOAS で役立ち、リソース リンクの関連データの MIME の種類を含めることができます。This approach is arguably the purest of the versioning mechanisms and lends itself naturally to HATEOAS, which can include the MIME type of related data in resource links.

注意

バージョン管理の方法を選択すると、パフォーマンスに対する影響、特に Web サーバーでのキャッシュについて検討する必要もあります。When you select a versioning strategy, you should also consider the implications on performance, especially caching on the web server. 同じ URI/クエリ文字列の組み合わせは同じデータを毎回参照するため、URI バージョン管理および Query String バージョン管理スキームはキャッシュに適しています。The URI versioning and Query String versioning schemes are cache-friendly inasmuch as the same URI/query string combination refers to the same data each time.

通常、Header バージョン管理および Media Type バージョン管理メカニズムでは、カスタム ヘッダーまたは Accept ヘッダーの値を確認するのに追加のロジックが必要です。The Header versioning and Media Type versioning mechanisms typically require additional logic to examine the values in the custom header or the Accept header. 大規模な環境では、多くのクライアントで異なるバージョンの Web API が使用されているため、サーバー側のキャッシュの重複データ量が著しく増加します。In a large-scale environment, many clients using different versions of a web API can result in a significant amount of duplicated data in a server-side cache. この問題が深刻になるのは、クライアント アプリケーションがキャッシュを実装するプロキシを経由して Web サーバーと通信する場合です。また、キャッシュに要求されたデータのコピーが現在保持されていない場合は Web サーバーに要求の転送のみ行います。This issue can become acute if a client application communicates with a web server through a proxy that implements caching, and that only forwards a request to the web server if it does not currently hold a copy of the requested data in its cache.

Open API イニシアチブOpen API Initiative

Open API イニシアチブは、ベンダー間の REST API の記述を標準化するために業界コンソーシアムによって作成されました。The Open API Initiative was created by an industry consortium to standardize REST API descriptions across vendors. このイニシアチブの一環として、Swagger 2.0 仕様という名前が OpenAPI 仕様 (OAS) に変更され、Open API イニシアチブの下に配置されました。As part of this initiative, the Swagger 2.0 specification was renamed the OpenAPI Specification (OAS) and brought under the Open API Initiative.

Web API に OpenAPI を採用することもできます。You may want to adopt OpenAPI for your web APIs. 考慮すべき点:Some points to consider:

  • OpenAPI 仕様には、REST API の設計方法に関する一連の厳密なガイドラインが付属しています。The OpenAPI Specification comes with a set of opinionated guidelines on how a REST API should be designed. 相互運用性の利点はありますが、API を設計するときは、仕様に準拠するようにさらに注意が必要です。That has advantages for interoperability, but requires more care when designing your API to conform to the specification.
  • OpenAPI では、実装優先のアプローチではなく、コントラクト優先のアプローチが推進されます。OpenAPI promotes a contract-first approach, rather than an implementation-first approach. コントラクト優先とは、API コントラクト (インターフェイス) を最初に設計してから、コントラクトを実装するコードを記述することを意味します。Contract-first means you design the API contract (the interface) first and then write code that implements the contract.
  • Swagger などのツールにより、API コントラクトからクライアント ライブラリまたはドキュメントを生成できます。Tools like Swagger can generate client libraries or documentation from API contracts. 例については、Swagger を使用する ASP.NET Web API のヘルプ ページに関する記事をご覧ください。For example, see ASP.NET Web API Help Pages using Swagger.

詳細情報More information