こんにちは、こだかです。
今回は、ADO.NET Data Serviceのリンク(接続性)について書きたいと思います。
RESTの実装としてのWebと言う話は以前したと思いますが、そのWebの便利な特徴としてハイパーリンクがあります。通常Webサーフィンをする場合、ハイパーリンクをたどって行くことで、様々な情報を入手することができるようになっています。当たり前と言えば当たり前ですが、この特徴は非常に重要です。もしリンクがなければ、常にアドレスを入力しなければいけませんよね。つまり、使いやすいリソース設計の条件に「リソース間のリンクを考える事」が必要になると言えます。そして、リソースの表現を受け取ったクライアントは、その中に含まれているリンクから、次のアクションを決定することができると言うわけです。(平たく言うと、Webアプリケーションの中で、「ブラウザの戻るボタンを押してください」とか、ブックマークにある別のアドレスに行く必要がある設計はイマイチってことですね)では、今回はSOAP形式のWebServiceを反例にして上記の優位点を確認しましょう。SOAP形式のWebServiceは、エンドポイントであるアドレスが一つだけあります。そして、そこに対して、Serviceのリクエストを出す形になります。このとき「そのServiceにはどのようなメソッドがあるのか?」は、まぁWSDLを見てくださいとなり、個々は独立していると言えます。例えば、SearchCategoryメソッドがあったとして、それでCategoryが取得できても、その関連であるProductの取得には、例えばSearchProductを行う必要があるかもしれません。そもそも、SearchCategory→SearchProductなんていう実装や順番は、このServiceのみのローカルルールであり、別のServiceを使用したい場合は、別のルールを理解する必要があるはずです・・・
前置きが長くなりました。ADO.NET Data Serviceでは、AtomPubをリソースの表現として返すことができます。AtomPubは、主にブログなどの情報をやり取りすることが多いと思いますが、その中の要素として「link」があり、ここには、関連のあるWebリソースに対するリンクが入るようになっています。そして、ADO.NET Data Serviceも、そのルール通り、linkに対して関連する情報が入ります。関連する情報とは、ADO.NET Data Serviceの場合、公開されるのは論理層であるEDMなどですから、このEDMで定義したAssosiation(つまりリレーション)です。
実際にpubsデータベースのemployeeに対して、GETのリクエスト(http://localhost/Test2/pubs.svc/employee('PMA42628M'))をしてみました。
HTTP/1.1 200 OKCache-Control: no-cacheContent-Type: application/atom+xmlServer: Microsoft-IIS/7.0X-AspNet-Version: 2.0.50727X-Powered-By: ASP.NETDate: Fri, 21 Mar 2008 11:52:06 GMTContent-Length: 1096
?<?xml version="1.0" encoding="utf-8" standalone="yes"?><entry xml:base="http://localhost/Test2/pubs.svc/" xmlns:ads="http://schemas.microsoft.com/ado/2007/08/dataweb" xmlns:adsm="http://schemas.microsoft.com/ado/2007/08/dataweb/metadata" adsm:type="pubsModel.employee" xmlns="http://www.w3.org/2005/Atom"> <id>http://localhost/Test2/pubs.svc/employee('PMA42628M')</id> <updated /> <title /> <author> <name /> </author> <link rel="edit" href="employee('PMA42628M')" title="employee" /> <content type="application/xml"> <ads:emp_id>PMA42628M</ads:emp_id> <ads:fname>Paolo</ads:fname> <ads:minit>M</ads:minit> <ads:lname>Accorti</ads:lname> <ads:job_lvl adsm:type="Nullable`1[System.Byte]">35</ads:job_lvl> <ads:hire_date adsm:type="DateTime">1992-08-27T00:00:00</ads:hire_date> </content> <link rel="related" title="jobs" href="employee('PMA42628M')/jobs" type="application/atom+xml;type=entry" /> <link rel="related" title="publishers" href="employee('PMA42628M')/publishers" type="application/atom+xml;type=entry" /></entry>
linkを確認してみましょう。まず、 <link rel="edit" href="employee('PMA42628M')" title="employee" />とあります。このrel属性値であるeditは、このリソースを更新するためのアドレスを意味しています。例えばこのアドレスで、PUTリクエストを出せばUpdateが可能です。
次に、 <link rel="related" title="jobs" href="employee('PMA42628M')/jobs" type="application/atom+xml;type=entry" /> <link rel="related" title="publishers" href="employee('PMA42628M')/publishers" type="application/atom+xml;type=entry" />
と2つあります。これは、employeeは、jobとpublisherに関連づいており、この場合、上記のアドレスから関連するリソースを取得することが出来ます。(rel="related"の意味は、内容が関連リソースであることです。)
ちなみに、ADO.NET Data ServiceはJSONでのリソース表現も可能ですので、同じことをJSONでもやってみましょう。
HTTP/1.1 200 OKCache-Control: no-cacheContent-Type: application/jsonServer: Microsoft-IIS/7.0X-AspNet-Version: 2.0.50727X-Powered-By: ASP.NETDate: Fri, 21 Mar 2008 11:53:07 GMTContent-Length: 454
?{ "d" : {__metadata: {uri: "http://localhost/Test2/pubs.svc/employee(\'PMA42628M\')", type: "pubsModel.employee"}, emp_id: "PMA42628M", fname: "Paolo", minit: "M", lname: "Accorti", job_lvl: 35, hire_date: "\/Date(714873600000)\/", jobs: {__deferred: {uri: "http://localhost/Test2/pubs.svc/employee(\'PMA42628M\')/jobs"}}, publishers: {__deferred: {uri: "http://localhost/Test2/pubs.svc/employee(\'PMA42628M\')/publishers"}}} }
こんな結果になりました。直列データといえども、リンクを返していることがわかると思います。
さて、今までの話しも含めて、ADO.NET Data Serviceは、マイクロソフトが提供する、非常に完成度の高いRESTfulな実装になっており、広く利用を促進するような考えが設計から伺えたのではないでしょうか?そして、その設計思想を考慮に入れつつ実装に臨んでいただければと思います。
こだかたろう