LoginSignup
4
2

More than 5 years have passed since last update.

SPARQL Endpoint に AJAX でアクセスする方法

Posted at

SPARQL Endpoint にブラウザ javascript から AJAX でアクセスする方法を紹介します。またこのポストは SPARQL 1.1 Protocol の紹介も兼ねています。

1. シナリオ

DBpedia Japanese の SPARQL Endpoint のトリプル数を表示する HTML ページを作りなさい、というお題が出ました。エンドポイントの URL とトリプル数をカウントするための SPARQL は以下のように与えられています。

endpoint
http://ja.dbpedia.org/sparql
sparql
select (count(*) as ?count) where {?s ?p ?o.}

なお DBpedia Japanese は SPARQL 1.1 Protocol に準拠しており、GET や POST のアクセスを受け付けることが可能です。

image

http://www.w3.org/TR/sparql11-protocol/#query-operation によれば QUERY オペレーションに対して以下の3種類の方法が定義されています。

  • query via GET
  • query via URL-encoded POST
  • query via POST directly

実際にこの方法が使えるか試してみましょう。

2. Query via GET

query-via-get
<script>
  var endpoint = "http://ja.dbpedia.org/sparql";
  var query = "select (count(*) as ?count) where {?s ?p ?o.}";

  var x = new XMLHttpRequest();
  x.onreadystatechange = function() {
    if (x.readyState == 4 && x.status == 200)
      document.body.appendChild(document.createTextNode(x.responseText));
  };
  x.open("GET", endpoint + "?query=" + encodeURIComponent(query), true);
  x.setRequestHeader("Accept", "application/sparql-results+json");
  x.send();
</script>

この方法はうまくいきます。クエリーが比較的短い文字列の場合にはオススメです。

x.setRequestHeader("Accept", "application/sparql-results+json");
によって SPARQL Endpoint に対して JSON 形式のレスポンスを返すように指示していることに注意してください。Content-negotiation という方式です。SPARQL 1.1 としては以下のようなレスポンスフォーマットが定義されていますが、フォーマットをサポートするかどうかは Endpoint 次第です。

(補足)

よく ?query=...&format=text/html&debug=on のように query 以外のパラメータのついた SPARQL リクエストを見かけることがあると思いますが、 基本的には各エンドポイントが独自に拡張したものだと考えておいたほうがいいでしょう。
SPARQL 1.1 Protocol としては query default-graph-uri named-graph-uri だけが定義されています。

3. Query via URL-encoded POST

query-via-url-encoded-post
<script>
  var endpoint = "http://ja.dbpedia.org/sparql";
  var query = "select (count(*) as ?count) where {?s ?p ?o.}";

  var x = new XMLHttpRequest();
  x.onreadystatechange = function() {
    if (x.readyState == 4 && x.status == 200)
      document.body.appendChild(document.createTextNode(x.responseText));
  };
  x.open("POST", endpoint, true);
  x.setRequestHeader("Accept", "application/sparql-results+json");
  x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  x.send("query=" + encodeURIComponent(query));
</script>

この方法もうまくいきます。クエリーがとても長い場合にはこちらを選択するとうまくいくかもしれません。

GET の場合とだいたい一緒ですが
x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
をつけることを忘れないようにしましょう。

4. Query via POST directly

query-via-post-directly
<script>
  var endpoint = "http://ja.dbpedia.org/sparql";
  var query = "select (count(*) as ?count) where {?s ?p ?o.}";

  var x = new XMLHttpRequest();
  x.onreadystatechange = function() {
    if (x.readyState == 4 && x.status == 200)
      document.body.appendChild(document.createTextNode(x.responseText));
  };
  x.open("POST", endpoint, true);
  x.setRequestHeader("Accept", "application/sparql-results+json");
  x.setRequestHeader("Content-Type", "application/sparql-query");
  x.send(query);
</script>

この方法はうまくいかないのでオススメしません(もしもうまくいく方法があれば教えてください)。かわりに Query via URL-encoded POST を使いましょう。

(補足)

この方法を使った場合のログを観察すると POST リクエストが投げられる前に OPTIONS リクエストが発行されていることがわかります。

image

これは W3C | Cross-Origin Resource Sharing| 7.1.5 Cross-Origin Request with Preflightとして規定されている挙動であり異常なものではないとのことです。ただ、これをパスして SPARQL Endpoint にアクセスする根性がないのでここでは Query via URL-encoded POST をオススメしておきます。

5.まとめ

  • SPARQL Endpoint に SPARQL 1.1 Protocol に従った方法で AJAX でアクセスする方法を紹介しました
  • AJAX でコンテントネゴシエーションに対応したリクエストを作成する方法を紹介しました
  • 短いクエリーなら GET、長いクエリーには POST を使いましょう
  • Query via POST directly はブラウザから使うには不都合があるのでご注意を
4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2