次の方法で共有


SharePoint 2013

SharePoint 2013 REST インターフェイスを理解して使用する

**Jim Crowley
**Ricky Kirkham

SharePoint 2013 では、SharePoint 2013 の開発プラットフォームを標準的な Web テクノロジと Web 言語で使用可能にする Representational State Transfer (REST) インターフェイスが提供されます。SharePoint の機能は長い間 Web アプリでクライアント オブジェクト モデルを介して利用できましたが、その API は .NET のアプリと言語でしか利用できません。SharePoint 2013 の充実した REST インターフェイスを使用すると、ほとんどの SharePoint の機能とエンティティに JavaScript や PHP などの標準的な Web 言語でアクセスでき、REST をサポートするあらゆるテクノロジ スタックや言語にアクセスできます。

REST インターフェイスにはクライアント アセンブリの参照が不要なので、Web アプリのサイズも抑えることができます。これは、特にモバイル アプリでは重要な考慮事項です。REST は、マイクロソフト以外のプラットフォーム (iOS デバイスや Android デバイスなど) 用に作成されたモバイル アプリでは明らかに優れていますが、Windows 8 アプリ開発者にとって役に立つリソースでもあります。HTML5 と JavaScript で記述された Windows 8 アプリでは、すべての SharePoint 操作に REST インターフェイスが必要になるので、アプリのサイズを懸念する C# 開発者にも、REST の使用を検討することをお勧めします。今回の記事では、このインターフェイスを使用して SharePoint プラットフォームの機能をアプリに組み込み、SharePoint エンティティによる高度な操作を実行する方法を説明します。

基礎

SharePoint に関する処理を実行するには、リモート Web アプリまたはモバイル アプリでは認証済みアクセス権を取得する必要があります。SharePoint 2013 には、SharePoint サイトへのアクセスを認証する 2 つの一般的な方法があります (REST を使用しているかどうかは関係ありません)。1 つ目の方法では SharePoint ユーザーを認証します。この場合、アプリにはそのユーザーと同じ SharePoint のデータと機能へのアクセス権が付与されます。Web アプリやモバイル アプリからユーザーを認証する他の方法については、今回の記事では詳しく説明しません。ただし、SharePoint 2013 の 2 つの新しいオプションについては、REST 要求の作成方法に影響するので簡単に触れておきます。

  • 使用するコードをクライアント側コード (HTML と JavaScript) だけに限定できないリモートでホストされたアプリから SharePoint を呼び出していて、SharePoint とアプリの間にファイアウォールがない場合は、マイクロソフトのアクセス制御サービス (ACS) をセキュリティ トークン サーバーとする OAuth 2.0 トークンを使用できます。
  • クライアント側コードが十分で、SharePoint にログインしているユーザーのアクセス許可が十分な場合は、JavaScript クロスドメイン ライブラリ (msdn.microsoft.com/ja-jp/library/fp179927.aspx) が OAuth の代替手段として適しています。クロスドメイン ライブラリは、ファイアウォールを介したリモート呼び出しを行う場合の便利な OAuth の代替手段でもあります。MSDN ライブラリの記事「SharePoint 2013 アプリのデータ アクセス オプション」(msdn.microsoft.com/ja-jp/library/fp179897.aspx) では、これらのオプションについて詳しく説明しています。

OAuth の使用: MSDN ライブラリの記事「SharePoint 2013 アプリの承認と認証」(msdn.microsoft.com/ja-jp/library/fp142384.aspx) では、SharePoint 2013 における OAuth の動作と、アプリのアクセス トークンを取得する方法について詳しく説明しています。トークンを取得したら、各 REST 要求でそのトークンを渡す必要があります。そのためには、次のように、アクセス トークンを値として渡す Authorization ヘッダーを "Bearer" の後に追加します。

Authorization: Bearer access_token

この処理を行う C# コードと JavaScript コードの例については、MSDN ライブラリの記事「[方法] SharePoint 2013 REST エンドポイントを使用して基本的な操作を完了する」(msdn.microsoft.com/ja-jp/library/jj164022.aspx) の「SharePoint 2013 REST インターフェイスを使用してデータを読み取る」のセクションを参照してください。SharePoint サイトからすべてのリストを取得する今回の例では、OAuth トークンを渡す次のような基本的な REST 要求を示しています。

HttpWebRequest endpointRequest =
  (HttpWebRequest)HttpWebRequest.Create(
  "http:// <http:///> <site url>/_api/web/lists");
endpointRequest.Method = "GET";
endpointRequest.Accept = "application/json;odata=verbose";
endpointRequest.Headers.Add("Authorization", 
  "Bearer " + accessToken);
HttpWebResponse endpointResponse =
  (HttpWebResponse)endpointRequest.GetResponse();

クロスドメイン JavaScript ライブラリの使用: SharePoint のクロスドメイン ライブラリは、SharePoint サーバーの virtual /_layouts/15/ ディレクトリにある SP.RequestExecutor.js ファイルに含まれています。このライブラリを使用するには、リモート Web ページでこのファイルを読み込みます。JavaScript で SP.RequestExecutor オブジェクトを作成し、その executeAsync メソッドを呼び出します。このメソッドのパラメーターとして、REST サービスに対する HTTP 要求を作成するためにメソッドで必要な情報を渡します。OAuth を使用した REST 呼び出しとクロスドメイン ライブラリを使用した REST 呼び出しの主な違いは、REST 呼び出しでは、要求でアクセス トークンを渡す必要がないものの、クライアント コンテキスト サイトの役割を果たす SharePoint Web サイトを (RESTful URL で) 指定する必要があることです。MSDN ライブラリの記事「方法: クロスドメイン ライブラリを使用してリモート アプリから SharePoint 2013 のデータにアクセスする」(msdn.microsoft.com/ja-jp/library/fp179927.aspx) では、詳しい違い (アプリ Web とホスト Web の違いなど) についてより包括的に説明しています。SharePoint サイトからすべてのリストを取得する今回の例では、クロスドメイン ライブラリを使用する次のような REST 要求を示しています。

var executor = new SP.RequestExecutor(appweburl);
  executor.executeAsync(
    {
      url:
        appweburl +
"/_api/SP.AppContextSite(@target)/web/lists?@target='" +
  hostweburl + "'",
  method: "GET",
  headers: { "Accept": "application/json; odata=verbose" },
  success: successHandler,
    error: errorHandler
    }
      );

RESTful URL の構築: SharePoint REST サービスは SharePoint Web サイトの /_vti_bin 仮想フォルダーにある client.svc ファイルで実装されていますが、SharePoint 2013 では "_vti_bin/client.svc" の代わりとして "_api" という省略形をサポートしています。すべてのエンドポイントのベース URL は、次のとおりです。

http://<domain>/<site url>/_api/

特定のエンドポイントのサービス相対 URL は、このベース URL に追加します。たとえば、次の URL を使用すると SharePoint サイトからリストを取得できます。

http://<domain>/<site url>/_api/web/lists

リストの ID を指定するか次の例のようにタイトルを指定すると、特定のリストへの参照を取得できます。

_api/web/lists/getByTitle('samplelist')/

これらの例の "web" はプレースホルダーではなく、SharePoint クライアント オブジェクト モデルにおける Web クラスのオブジェクト名です。"lists" はコレクション プロパティの名前で、"getByTitle" はそのコレクション オブジェクトのメソッドです。このパラダイムにより、マイクロソフトはエンドポイントの API 参照と JavaScript オブジェクト モデルを組み合わせることができます。例として、SP.Web.lists (bit.ly/14a38wZ、英語) と SP.ListCollection.getByTitle (bit.ly/WNtRMO、英語) を参照してください。また、この構文は SharePoint テナンシーの構造をおおまかに反映しています。サイト コレクションに関する情報は _api/site で、SharePoint Web サイトに関する情報は _api/web で、Web サイトのすべてのリストに関する情報は _api/web/lists で取得できます。最後の URL は、SharePoint サイトのすべてのリストで構成されたリスト コレクションを返します。また、開発サイト コレクションのこれらの URL に移動すると、各オブジェクトが XML でどのように表示されるか確認できます。

サイト コレクション、Web サイト、リスト、フォルダー、フィールド、リスト項目など、SharePoint コンテンツ オブジェクト モデルにおけるすべての主要なクラスを利用できます。ユーザーに関する情報は、SP.User (bit.ly/15M4fzo、英語)、SP.UserCollection (bit.ly/16TQTnW、英語)、SP.Group (bit.ly/X55Pga、英語)、および SP.GroupCollection (bit.ly/ZnFHbG、英語) の各クラスから取得できます。図 1の表は、読み取り操作のためのさまざまなエンドポイントの例を示しています。

図 1 読み取り操作のためのエンドポイント

URL 戻り値
_api/web/title 現在のサイトのタイトル
_api/web/lists(guid'') リスト
_api/web/lists/getByTitle('Announcements')/fields お知らせリストの列
_api/web/lists/getByTitle('Task')/items タスク リストの項目
_api/web/siteusers サイトのユーザー
_api/web/sitegroups サイトのユーザー グループ
_api/web/sitegroups(3)/users グループ 3 のユーザー
_api/web/GetFolderByServerRelativeUrl('/Shared Documents') 共有ドキュメント ライブラリのルート フォルダー
_api/web/GetFolderByServerRelativeUrl('/Plans')/Files('a.txt')/$value Plans ライブラリの a.txt ファイル

既定では、データは OData 形式で拡張された AtomPub 形式の XML として返されますが、HTTP 要求に次の accept ヘッダーを追加すればデータを JSON 形式で取得できます。

accept: application/json;odata=verbose

JSON と Atom (XML) のどちらを使用するかについては、スキル セット、使用しているプログラミング プラットフォーム、およびアプリでネットワーク待機時間が問題となるかどうかによって決まります。JSON の方が使用する文字がはるかに少ないので、ネットワーク経由の小規模なペイロードに適しています。一方、Microsoft .NET Framework を含む大部分の主要プラットフォームには、充実した XML 解析ライブラリがあります。

OData クエリ演算子を使用した、データの選択、フィルター処理、および順序付けの方法については、後で説明します。

SharePoint への書き込み: ここまでに挙げたすべての要求では、HTTP 動詞の GET を使用します。SharePoint に書き込む場合は、要求には POST 動詞を使用します。ただし、一部の場合では、X-HTTP-Method ヘッダーを要求に追加し、PUT、MERGE、または DELETE の値を指定することで、この動詞をオーバーライドします。一般に、サイト、リスト、リスト項目などのオブジェクトを作成する場合は POST を使用します。MERGE は、オブジェクトの特定のプロパティを更新する場合に、他のプロパティで現在の値を維持する必要があるときに使用します。PUT は、項目を置き換える場合に使用し、要求で特に指定されていないプロパティは既定値に設定されます。DELETE は、項目を削除する場合に使用します。

SharePoint に書き込むすべての要求には、フォーム ダイジェストを含める必要があります。コードでは、次のエンドポイントから返される一連の情報の一部としてダイジェストを取得します。

_api/contextinfo

既に説明したように、この要求 (本文は空) には POST 動詞を使用し、Authorization ヘッダーを含める必要があります。一部のフレームワークでは、POST 要求の長さを 0 に指定する必要があります。返される構造体には、フォーム ダイジェストが含まれる FormDigestValue という名前のプロパティがあります。以降のすべての POST 要求には、ダイジェストを値として指定した X-Request­Digest ヘッダーを追加します。

SharePoint でホストされるアプリと SharePoint の既定のマスター ページを使用するページを開発する場合、ダイジェストが既にページ上の "__REQUESTDIGEST" という ID (2 文字のアンダースコア文字を使用) の要素に存在していることに注意してください。そのため、contextinfo エンドポイントを呼び出す代わりに、単純に次の jQuery コードのようなスクリプトで値を読み取ることができます。

var formDigestValue = $("__REQUESTDIGEST").val()

もちろん、書き込むデータや、削除するデータの ID を要求本文に追加する必要があります。AtomPub/OData 形式と JSON 形式のどちらを使用してもかまいません。JSON 形式を選択する場合は、次のように要求に content-type ヘッダーを追加する必要があります。

content-type: application/json;odata=verbose

SharePoint オブジェクトに対する作成、読み取り、更新、および削除 (CRUD) 操作の具体例については、「[方法] SharePoint 2013 REST エンドポイントを使用して基本的な操作を完了する」(msdn.microsoft.com/ja-jp/library/jj164022.aspx) を参照してください。

高度な操作

SharePoint 2013 REST インターフェイスの機能には、ある程度の複雑さが付きまといます。このインターフェイスでは、返されたデータの並べ替え、フィルター処理、および順序付けの操作をサポートしています。また、多数の SharePoint 固有の操作もサポートしています。これらの追加機能によって、標準的な REST 実装では必ずしも利用できない機能と利点が実現します。以降のセクションでは、REST と SharePoint で開発する際に生じる、最も重要な要素をいくつか説明します。

フィルター処理、選択、および並べ替え: OData システム クエリ オプションを使用して、返されるデータとその並べ替え方法を管理できます。図 2は、サポートされているオプションを示しています。

図 2 データのフィルター処理と並べ替えのオプション

オプション 目的
$select 返されるデータに含めるフィールドを指定します。
$filter コレクションのどのメンバー (リストの項目など) を返すか指定します。
$expand 結合リスト内のどの予想されたフィールドを返すか指定します。
$top コレクションまたはリストの最初の n個の項目のみを返します。
$skip コレクションまたはリストの最初の n個の項目をスキップし、残りの項目を返します。
$orderby データを並べ替えてから返すために使用するフィールドを指定します。

たとえば、Books (書籍) という名前のリストから著者、書名、および ISBN を返すには、次の URL を使用します。

_api/web/lists/getByTitle('Books')/items?$select=Author,Title,ISBN

$select オプションを使用しない場合は、返す際にサーバーのリソースを大量に消費する可能性があるフィールドを除き、すべてのフィールドが返されます。これらのフィールドが必要な場合、$select オプションを使用してその名前を指定する必要があります。すべてのフィールドを取得するには、$select=‘*’ を使用します。

Mark Twain の著書をすべて取得するには、次の URL を使用します。

_api/web/lists/getByTitle('Books')/items?$filter=Author eq 'Mark Twain'

$filter オプション用にサポートされているすべての演算子については、MSDN ライブラリの記事「SharePoint 2013 REST サービスを使用したプログラミング」(msdn.microsoft.com/ja-jp/library/fp142385) を参照してください。

書籍を書名の昇順で並べ替えるには、次の URL を使用します。

_api/web/lists/getByTitle('Books')/items?$orderby=Title asc

"asc" の代わりに "desc" を使用すると、降順を指定できます。複数のフィールドで並べ替えるには、フィールドのコンマ区切りのリストを指定します。

"&" 演算子を使用して、複数のオプションを結合できます。Mark Twain が執筆した最初の 2 冊の Title のみを取得するには、次の URL を使用します。

_api/web/lists/getByTitle(
  'Books')/items?$select=Title&$filter=Author eq 'Mark Twain'&$top=2

サービスでは、各オプションを完全に解決してから次のオプションを適用します。そのため、各オプションの適用対象は、URL で左側に記述されているオプションによって生成されるデータ セットだけです。したがって、オプションを適用する順序が重要です。たとえば、次の URL は、項目 3 ~ 10 を返します。

_api/web/lists/getByTitle('Books')/items?$top=10&$skip=2

しかし、2 つのオプションを入れ替えた URL は、項目 3 ~ 12 を返します。

_api/web/lists/getByTitle('Books')/items?$skip=2&$top=10

降順の $orderby と $top オプションを (この順序で) 使用すると、最後の n 項目を取得できます。次の URL は、最後の 2 項目を取得します。

_api/web/lists/getByTitle('Books')/items?$orderby=ID desc&$top=2

SharePoint リストに他のリストに対するルックアップ フィールドが含まれている場合は、2 つのリストの結合として効果的に機能します。$expand オプションを使用すると、予想されたフィールドを結合リストから返すことができます。たとえば、Publisher リストの Name フィールドを参照する PublishedBy フィールドが Books リストに含まれている場合、次の URL でこれらの名前を返すことができます。

_api/web/lists/getByTitle(
  'Books')/items?$select=Title,PublishedBy/Name&$expand=PublishedBy

foreign_list_name/foreign_column_name ではなく lookup_column_display_name/foreign_column_name 構文を使用して外部リストの列を参照することに注意してください。ルックアップ フィールドを展開しない限りそのフィールド名を選択できないことも重要です。

ファイルとフォルダーの操作: ドキュメント ライブラリにアクセスする最適な方法は、/_api/web で利用できる GetFolderByServerRelativeUrl メソッドを活用することです。ファイルをドキュメント ライブラリに追加する場合は、要求本文でファイルの内容を送信し、URL でファイルの名前を渡します。

http://<site url>/_api/web/GetFolderByServerRelativeUrl(
  '/Shared Documents')/Files/add(url='a.txt',overwrite=true)

ファイルを更新する際の重要な考慮事項は、PUT HTTP メソッドだけを使用できることです。そのため、既にドキュメント ライブラリに格納されているファイルにファイルの内容をマージすることはできません。その代わり、ファイルのバージョンを置き換えることができます。また、URL で $value 演算子を使用して、ファイルに関連付けられたメタデータではなくファイル自体の内容にアクセスできるようにする必要があります。

http://<site url>/_api/web/GetFileByServerRelativeUrl(
  '/Shared Documents/a.txt')/$value

SharePoint のベスト プラクティスはファイルをチェックアウトしてから変更することなので、ファイルをチェックアウトしてから更新し、完了したら元の場所にチェックインする必要があります。次の演算子では、これらの URL に要求本文が空の POST 要求を作成することを要求します。

http://<site url>/_api/web/GetFileByServerRelativeUrl(
  '/Shared Documents/a.txt')/CheckOut()
http://<site url>/_api/web/GetFileByServerRelativeUrl(
  '/Shared Documents/a.txt')/CheckIn(comment='Comment', checkintype=0)

CheckIn メソッドは、2 つのパラメーターを受け取ります。comment パラメーターを使用するとチェックインにコメントを追加でき、checkintype パラメーターはこのチェックインがマイナー (0) またはメジャー (1) のチェックインかどうか指定します。

最後の考慮事項になりますが、ブラウザー クライアントで実行するコード (JavaScript など) を開発していて、1.5 MB を超えるファイルをアップロードする必要がある場合、使用できるのは REST のみです。大規模なファイル (1.5 MB 超) に対するこの種の操作は、Internet Explorer 10 (またはそれ以降) と、その同世代の他の最新ブラウザーだけで使用できます。図 3 のサンプルは、クロスドメイン ライブラリを使用してバイナリ ファイルをアップロードする方法を示しています。

図 3 クロスドメイン ライブラリを使用したバイナリ ファイルのアップロード

function uploadFileBinary() {
  var executor = new SP.RequestExecutor(appweburl);
  var body = "";
  for (var i = 0; i < 1000; i++) {
    var ch = i % 256;
    body = body + String.fromCharCode(ch);
  }
  var info = {
    url: "_api/web/lists/getByTitle('Shared Documents')/RootFolder/Files/Add(url='a.dat', overwrite=true)",  
    method: "POST",
    binaryStringRequestBody: true,  
    body: body,  
    success: success,  
    error: fail,  
    state: "Update"};
   executor.executeAsync(info);
}

変更クエリ: ここまでは、SharePoint サイトの構造を反映した URL でアクセスできる SharePoint エンティティに対して、REST がどのように連携しているかを説明してきました。ただし、この方法では一部の SharePoint の型を取得したり表示したりすることができません。これらのうち、REST の場合に最も重要な型は、ChangeQuery 型、ChangeLogItemQuery 型、および ChangeToken 型の 3 種類です。

ChangeQuery オブジェクトを使用すると、SharePoint サイト コレクション、サイト、またはリストの更新について SharePoint 変更ログにクエリできます。REST インターフェイスでは、次の 3 つの場所すべてで getchanges メソッドを公開します。

  • /_api/site (サイト コレクション用)
  • /_api/web (サイト用)
  • /_api/web/lists/list(guid'') または /_api/web/lists/­getByTitle('list title') (リスト用)

関連する URL パスに /getchanges を追加し、要求の POST 本文を使用して ChangeQuery オブジェクトを送信することで、これらのうち任意の場所にクエリを渡します。リストに追加されたすべての項目を照会するシンプルな変更クエリは、次のようになります (JSON の場合)。

{
  'query': {
    '__metadata': {
      'type': 'SP.ChangeQuery'
    }, 
    'Add': 'true',
    'Item': 'true'
  }
}

getchanges メソッドでは、クエリ パラメーター内に ChangeQuery オブジェクトの表現が含まれた要求本文を予想します。この要求を、特定のリストに対する次のような URL に送信します。

/_api/web/lists/list(guid'<list id>')/getchanges

または、次のような URL に送信します。

_api/web/lists/getByTitle('<list title>')/getchanges

応答は、要求に対応する変更のコレクションが含まれた結果を返します。リストに項目が 1 つだけ含まれている場合、応答本文は次のようになります。

{"d":
    {"results":[{
        "__metadata":{
            "id":"https://<site url>/_api/SP.ChangeItema7e7c6e9-2c41-47c3-aae9-2b4a63b7a087",
            "uri":"https://site url/_api/SP.ChangeItem",
            "type":"SP.ChangeItem"},
        "ChangeToken":{"__metadata":{"type":"SP.ChangeToken"},
            "StringValue":"1;3;482e418a-0900-414b-8902-02248c2e44e8;634955266749500000;5749111"},
        "ChangeType":1,
        "SiteId":"ce11bfbb-cf9d-4b2b-a642-8673bd48cceb",
        "Time":"2013-02-03T22:17:54Z",
        "ItemId":1,
        "ListId":"482e418a-0900-414b-8902-02248c2e44e8",
        "WebId":"a975b994-fc67-4203-a519-b160175ca967"}]
    }
}

この応答は、ChangeToken が変更ログで表している日時に単一のリスト項目 (ItemId の値が 1) が追加されたことを伝えます。このオブジェクトの文字列値を使用して、クエリの精度を高めることができます。たとえば、ChangeQuery オブジェクトの ChangeTokenStart プロパティや ChangeTokenEnd プロパティの値を指定して、ある時点の前または後に発生した変更、あるいは 2 つの時点の間に発生した変更を取得できます。

getListItemChangesSinceToken メソッドを使用する場合に ChangeToken オブジェクトの値を使用することもできます。

/_api/web/lists/list(guid'<list id>')/getListChangesSinceToken

このメソッドは REST インターフェイスにのみ存在しています。最初の項目を追加した後にこのリストの項目で発生したすべての変更を確認する場合は、変更トークンを含む次のような ChangeLogItemQuery オブジェクトを作成します。

{
    'query': {
        '__metadata': {
            'type': 'SP.ChangeLogItemQuery'
        }, 
    'ChangeToken':'1;3;482e418a-0900-414b-8902-02248c2e44e8;634955266749500000;5749111'
    }
}

SharePoint Server 2013 の機能領域: 今回の記事で説明したすべての操作は、SharePoint Foundation 2013 と SharePoint Server 2013 の両方に適用されます。これは、両方の製品に SharePoint のコア機能が含まれているためです。また、SharePoint REST インターフェイスでは、SharePoint Server 2013 の機能領域に含まれている多くの機能が公開されます。今回の記事ではこれらの機能領域について詳しく説明しませんが、REST を使用したこれらの機能領域の扱いについては、SDK の次のリソースを参照できます。

  • 「SharePoint 2013: SharePoint 用のアプリから search REST サービスを使用する」(bit.ly/Mt4szN、英語)
  • 「SharePoint 2013 でのソーシャル機能の開発の概要」(msdn.microsoft.com/ja-jp/library/jj163864(v=office.15.aspx))
  • 「SharePoint 2013 BCS REST API リファレンス」(msdn.microsoft.com/ja-jp/library/jj163227.aspx)

デバッグする

REST 操作を実行するために必要になる最も重要な情報は、もちろん正確な URL です。特に重要な URL についてはこの記事で多数紹介しましたが、その他の URL の多くについては SharePoint SDK を参照してください。REST インターフェイスはクライアント オブジェクト モデルでモデル化されているので、REST エンドポイント URL については JavaScript オブジェクト モデル リファレンスを参照できます。たとえば、リスト コレクションの作業に使用できる URL を確認する場合は、bit.ly/108hI1e(英語) で SP.ListCollection オブジェクトのリファレンス ドキュメントを参照できます。

また、ログインしたユーザーとして REST URL にアクセスし、任意の GET 要求の XML 出力を表示して、各エンドポイントで取得できるデータとその構造を確認できます。この方法は、POST 要求では役に立ちませんが、さまざまな SharePoint エンティティと各エンドポイントで使用できる情報を詳しく知ることができます。

コードから送信する HTTP 要求に、正しくエンコードされた URL が含まれていることが重要です。SharePoint から SharePoint 用アプリを起動する場合は SPHostUrl クエリ文字列引数からエンコードされた URL を取得できますが、他のコンテキストでは自分で URL をエンコードする必要があることもあります。

より複雑な操作を行う場合 (特に、POST HTTP 動詞が必要な操作を実行する場合) は、HTTP 要求をデバッグするために HTTP トレース ユーティリティを使用する必要があります。無効な要求を実行すると必ず SharePoint からエラー メッセージが返され、これらのメッセージから要求の問題点に関するさまざまな情報を知ることができます。たとえば、アプリやユーザーに、SharePoint から特定の種類の情報を取得する権限が承認されていない可能性があります。また、無効な JSON オブジェクトを構築した可能性や、プロパティに無効な値を割り当てた可能性もあります。

一部のフレームワークでは、HTTP トレース ユーティリティが提供されます。ASP.NET アプリを開発する場合は、trace.axd (msdn.microsoft.com/ja-jp/library/ms972204.aspx) を使用できます。JavaScript のようにブラウザーから直接要求を送信する場合は、Fiddler (fiddler2.com/fiddler2、英語) を使用できます。今回の記事のサンプル HTTP 要求は、Fiddler を使用して作成しました。

PHP アプリで REST を使用して SharePoint と通信する

冒頭で述べたように、REST インターフェイスを使用すると、Web 開発者がよく使用するあらゆる標準的な言語とフレームワークで SharePoint を操作できます。この手法を実演するために、PHP で作成したリモート Web アプリから SharePoint サイトを操作する方法を実演する、サンプル PHP アプリを公開しました。このアプリは、Office 365 SharePoint サイトから起動され Windows Azure Web サイトで実行されるように設計した SharePoint 用アプリです。このアーキテクチャを採用すると、Web サイトの発行などいくつかの手順が簡略化されますが、サンプルの PHP コードは、PHP をサポートするあらゆるアーキテクチャで実行できます。

サンプルは、コード ギャラリー ページ (bit.ly/ZQsmvP、英語) で表示してダウンロードできます。このサンプルでは、REST でファイルとフォルダーを操作する方法、PHP アプリから有効な OAuth アクセス トークンを取得する方法、JavaScript クロスドメイン ライブラリを使用する方法など、多数の手法を実演します。ここで最も重要なのは、このサンプルでは REST と PHP を使用して SharePoint ドキュメント ライブラリのファイルを取得し、アップロードする方法を実演していることです。

このアプリでは SharePoint サイトにデータを書き込むので、アプリで (アクセス トークンの取得後に) まず実行する必要がある処理の 1 つは、_api/contextinfo のフォーム ダイジェストを要求することです。この要求では、ヘッダーでアクセス トークンを渡し、SSL URL に対する POST 要求を作成します。図 4に示すコードは、PHP クライアント URL オブジェクトを操作したことのある方ならだれもがなじみがあるでしょう。

図 4 フォーム ダイジェストの要求

$opts = array (
    'Authorization: Bearer ' .
    $accToken);
$ch = curl_init();
$url = $appweburl . '/_api/contextinfo';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $opts);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, '');
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);

要求の実行後、アプリで XML を解析し、フォーム ダイジェストの値を格納します。

$root = new SimpleXmlElement($result);

$ns = $root->getNameSpaces(TRUE);
$childrenNodes = $root->children($ns['d']);
$formValue = $childrenNodes->FormDigestValue;

また、アクセス トークンをクッキーに格納します。ユーザーがファイルのアップロードを選択すると、アプリではこれらの値を HTML ファイルに渡し、この HTML ファイルで、ドキュメント ライブラリにファイルをアップロードするための HTTP 要求を作成します。要求を作成する前に、アプリではローカルに格納されているファイルのデータを文字列オブジェクトに読み取り、この文字列オブジェクトを POST 要求の本文として渡します。

$accToken = $_COOKIE["moss_access_token"];

$url = $_REQUEST["target"] . 
$furl = $_FILES["file"]["tmp_name"];
$file = fopen($furl,"r");
$post_data = fread($file,filesize($furl));
fclose($file);

図 5 のコード行では、フォーム ダイジェストとアクセス トークンの値を取得し、ファイルをアップロードする HTTP 要求を作成して実行します。

図 5 ファイルをアップロードする要求の実行

"/_api/web/GetFolderByServerRelativeUrl('Lists/SharedDoc')/Files/
add(url='" . $_FILES["file"]["name"] . "',overwrite=true)";
$opts = array (
'X-RequestDigest:' . $_REQUEST["digest"],
'Authorization: Bearer ' . $accToken);
// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $opts);
// Set URL on which you want to post the Form and/or data
curl_setopt($ch, CURLOPT_URL, $url);
// Data+Files to be posted
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// Pass TRUE or 1 if you want to wait for and catch the 
// response against the request made
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// For Debug mode; shows up any error encountered during the operation
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
// Execute the request
$response = curl_exec($ch);

次のステップ

SharePoint 2013 REST インターフェイスは、クライアント オブジェクト モデルと完全に同等なわけではありませんが、Web アプリやモバイル アプリの開発者が (特に .NET 以外のフレームワークを使用する場合に) 必要とする機能のほとんどを提供できるほど充実していて強力です。この記事では REST インターフェイスを使用してアプリに SharePoint を統合する最も重要な方法を多数説明しましたが、他にも多くの活用方法があります。

SharePoint 2013 SDK には、REST 開発用のリソース集が含まれており、すべてのリソースへのリンクが MSDN ライブラリの「SharePoint 2013 REST API、エンドポイント、およびサンプル」(msdn.microsoft.com/ja-jp/library/jj860569.aspx) に記載されています。PHP サンプルが示すように、REST インターフェイスは SharePoint 開発の世界を大きく広げるので、今後、このリソース集は成長し、非常に幅広いサンプルが掲載されるようになるでしょう。

Jim Crowley は、Office 部門のシニア プログラミング ライターを務めています。彼は、SharePoint 2013 の開発者向けドキュメントを執筆しています。また、Windows Phone 7 用の SharePoint Developer Documentation RSS Reader アプリ (bit.ly/YIVbvY、英語) の作者でもあります。

Ricky Kirkham は、Office 部門のシニア プログラミング ライターを務める、マイクロソフト認定プロフェッショナル デベロッパー (SharePoint 2010) です。Kirkham は、2006 年から SharePoint に関する Microsoft デベロッパー ドキュメント チームに所属しています。

この記事のレビューに協力してくれた技術スタッフの Jyoti Jacob (マイクロソフト) に心より感謝いたします。