asp.net-web-api
ASP.NET Web APIコンテンツネゴシエーション
サーチ…
ASP.NET Web APIコンテンツネゴシエーションの基本情報
コンテンツネゴシエーションは、所定のリソースに対する最良の表現を選択するプロセスとして定義することができる。したがって、コンテンツネゴシエーションとは、クライアントとサーバーがそれらの間でネゴシエートを行い、クライアントが必要な形式に従ってデータを取得できることを意味します。
インターネットが依存する3つのポイントがありますが、
- リソース
- Aリソースへのポインタ(URL)
- リソースの表現
第3のポイントは、他の2つよりも重要です。すべてがリソースをどのように見ることができるかに基づいて動作するからです。リソースは2つの形式で表現できます。
- XML(Extensible Markup Language)形式
- JSON(JavaScript Object Notation)形式
RESTfulなサービスの標準の1つは、クライアントがJSONまたはXMLのいずれかの形式で応答を希望するかどうかを判断する能力があることです。サーバーに送信される要求には、Acceptヘッダーが含まれます。 Acceptヘッダーを使用すると、クライアントは応答の形式を指定できます。
例えば、
Accept: application/xmlは結果をXML形式で返します
Accept: application/jsonは結果をJSON形式で返します
要求のAcceptヘッダー値に応じて、サーバーは応答を送信します。これはコンテンツネゴシエーションと呼ばれます。
特定の形式でデータを要求すると、シーンの後ろにはどうなりますか?
ASP.NET Web APIコントローラは、クライアントに送信するデータを生成し、Web APIパイプラインに渡して、クライアントのAcceptヘッダーを探します。次に、適切なフォーマッタを選択してデータをフォーマットします。
ASP.NET Web APIは非常に拡張性が高いため、要求ヘッダーに複数の値を指定することもできます。
Accept: application/xml,application/json
上記の場合、サーバーは最初のフォーマッターを選択して応答データをフォーマットします。
また、受け入れヘッダに品質係数を指定することもできます。この場合、サーバは、より高い品質係数を有するフォーマットを選択する。
Accept: application/json;q=0.8,application/xml;q=0.5
Acceptヘッダーを指定しない場合は、デフォルトでサーバーがJSONフォーマッターを選択します。
応答が要求された形式でクライアントに送信されるとき、応答のContent-Typeヘッダーが適切な値に設定されていることに注意してください。たとえば、クライアントがapplication/xmlを要求した場合、サーバーはXML形式でデータを送信し、 Content-Type=application/xmlも設定しContent-Type=application/xml 。
フォーマッタは、要求メッセージと応答メッセージの両方のためにサーバによって使用されます。クライアントからサーバーに要求が送信されると、Content-Typeヘッダーに適切な値が設定され、送信するデータの形式がサーバーに通知されます。
たとえば、クライアントがJSONデータを送信している場合、Content-Typeヘッダーはapplication/json設定されapplication/json 。サーバーはJSONデータを扱っているので、JSONフォーマッタを使用してJSONデータを.NETタイプに変換します。同様に、Acceptヘッダー値に応じて、サーバーからクライアントにレスポンスが送信されるときに、適切なフォーマッタを使用して.NETタイプをJSON、XMLなどに変換します。
さまざまなタイプの応答フォーマットの例:
アプリケーション/ json:
{
"Email": "sample string 1",
"HasRegistered": true,
"LoginProvider": "sample string 3"
}
アプリケーション/ xml:
<UserInfoViewModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WebApiDemo.Models">
<Email>sample string 1</Email>
<HasRegistered>true</HasRegistered>
<LoginProvider>sample string 3</LoginProvider>
</UserInfoViewModel>
最新のWebベースのアプリケーションは、さまざまな言語とフォーマットのデータを提供できます。したがって、世界中のグローバルユーザーを対象とするAPIを開発する場合は、コンテンツネゴシエーションが適切です。
Web APIにおけるコンテンツネゴシエーション
概念を理解する
Web APIのコンテンツネゴシエーションを理解するには、「 Resourceという用語を理解することが重要です。
ウェブ上では、アクセスできるすべての情報をHTTP resourceと呼ぶことができます。 HTML文書、画像、ビデオ、オーディオ、実行可能ファイル、スプレッドシートなど、さまざまなコンテンツタイプを持つWeb上では、膨大な量の素材を見ることができます。リソースURIをhttpリクエストすることで、あらゆるリソースを取得できます。要求に対するhttpレスポンスはリソースを返し、コンテンツタイプも指定します。これはalso known as media typeとalso known as media type 。
任意のリソースにアクセスするために、クライアントは特定のリソースuriとhttp動詞を提供することによってhttp要求を行うことができます。しかし、これに加えて、クライアントは、ユーザが探しているコンテンツのフォーマットであるaccept-typeを指定することもできます。 「accept-type」は、http要求ヘッダー内で“accept”ヘッダーとして定義できます。
次に、サーバーは要求から「受け入れる」ヘッダーをチェックし、使用可能な場合は指定された形式で応答を返します。サーバーは、要求された表現が利用可能である場合にのみ応答を返すことができることに注意してください。要求された表現が利用可能でない場合、リソースはデフォルト表現で返されます。これがコンテンツネゴシエーションと呼ばれる理由です。
実例
たとえば、 http://example.com/customer/1にID 1の顧客の情報を取得するようにリクエストしているとします。リクエストに「accept」ヘッダーを指定しない場合、サーバーはこのリソースのデフォルト表現を返します。
サーバーがjson and xml bothで顧客情報を返すことができると仮定します。これで、依頼の「受け入れ」ヘッダーに顧客情報の必要な書式を指定するのがクライアント上にあります。 “accept”ヘッダーの値は、json表現の場合は“application/json” “text/xml” 、xml表現の場合は“text/xml”です。サーバーは要求された形式に従って応答を返します。
要求されたフォーマットが(この例のように)このホストでサポートされていない「text / html」 simply return the resource in the default format 。 httpレスポンスには、リソースのフォーマットについてクライアントに知らせるヘッダ“content-type”含まれています。
リソースの要求された表現が利用可能でない場合でも、リソースのデフォルト表現が依然として返されることに注意してください。
それがコンテンツネゴシエーションと呼ばれる理由です。
クライアントは応答の表現をネゴシエートしますが、利用可能でない場合はデフォルトの応答を取得します。
Web APIでの設定方法
Web APIでは、 WebAPIConfigクラスでコンテンツネゴシエーションを次のように設定できます。
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));
また、IContentNegotiatorインターフェイスとNegotiateメソッドを実装してWeb APIの既定のコンテンツネゴシエーションをオーバーライドし、WebAPI.configファイルのWeb API要求パイプラインで以下のように設定することもできます。
GlobalConfiguration.Configuration.Services.Replace(typeof(IContentNegotiator), new CustomContentNegotiator());
以下に、Negotiateメソッドの実装例を示します。
public class CustomContentNegotiator : DefaultContentNegotiator
{
public override ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
{
var result = new ContentNegotiationResult(new JsonMediaTypeFormatter(), new MediaTypeHeaderValue("application/json"));
return result;
}