📝

JSON-LDの基礎

2024/01/27に公開

はじめに JSON-LDとは

JSON-LDは、Linked dataをJSON形式で記述する規格、またはJSON形式で書かれたLinked dataを指します。
Linked dataとは、あるデータをコンピュータにとって読みやすく、かつ他のWeb上のデータと容易に結び付けられるようにしようという考え方です。

仰々しい書き方がされていますが、JSONに対して型を導入して、プロパティ名や値のデータ型・フォーマットを限定しようというのが根底にあるアイデアだと理解しています。

この記事は、JSON-LDで用いられるLinked dataの基本的な文法を紹介することを目的として書かれています。SEOの話題には一切触れませんので、ご容赦ください。

リンク集

先んじてリンク集を貼っておきます。特にプレイグラウンドは開いた状態で記事を読み進めていただき、適宜サンプルコードを貼り付けながら記事を読むと理解の助けになるかと思います。

  • プレイグラウンド

https://json-ld.org/playground

https://www.w3.org/TR/json-ld11/

基本文法

JSON-LDはJSONとして書かれるので、基本的な文法はJSONと同一です。

例えば人物を表すデータを書くことを考えます。
一例として以下のようなJSONが考えられますが、複数のウェブサイトがそれぞれ人物のデータを掲載するときには、それぞれ独特のプロパティ名が使われたり、国の慣習や個人の好みでデータのフォーマットが違ったりする場合がしばしばあります。

json
{
  "name": "John Smith",
  "birthday": "2004/01/26"
}

そこで次のようにJSON-LDで書き直します。

json-ld
{
  "https://schema.org/name": "John Smith",
  "https://schema.org/birthDate": "2004-01-26"
}

ここでプロパティ名に指定されているURLはIRI (Internationalized Resource Identifier)と呼ばれる統一的な識別子で、これによってJSON-LDの各プロパティの性質を一意に特定しています。実際にこのURLにアクセスすると、値の型やフォーマットの明確に定義を確認できます。

例えば、JSON-LDで書き直すにあたり、誕生日のフォーマットを2004/01/26から2004-01-26へと変更しました。これは、今回プロパティのIRIに https://schema.org を使おうと決めたからです。(ここは決めの問題であり、JSON-LDを使うなら https://schema.org を使わなければならないということはありません)
具体的には、まずbirthdayプロパティに https://schema.org/birthDate を使うことに決めました。そこでbirthDateプロパティのドキュメントを読むと「値はDate型でなければならない」とあるため、日付は https://schema.org/Date で定められたフォーマットで指定する必要があることが分かりました。再び、今度はDate型のドキュメントを読むと「日付は ISO 8601 date format で書かれた値である」とあるため、誕生日はISO 8601の形式で書き直さなければならなかったのです。

このようにして、プロパティ名とその値の文法的なフォーマット(シンタクス)・意味論(セマンティクス)とをウェブ横断的に統一します。

なお https://schema.org は一般的な用途に使えるポピュラーなIRIを提供してくれるサイトです。専門的な分野でJSON-LDを使う場合は、そちらの規格で定められたプロパティと型を使うことが多いです。

キーワード

JSON-LDでは、先頭に@がついたプロパティは特別な意味を持ち、キーワードと総称されます。

この記事では、最も重要ないくつかのキーワードに絞って紹介します。

@id キーワード

@idキーワードは、そのオブジェクトを一意に特定する識別子を指定します。識別子はIRIである必要があります。[1]

{
  "@id": "https://example.com/users/john-smith",
  "https://schema.org/name": "John Smith",
  "https://schema.org/birthDate": "2004-01-26"
}

@type キーワード

@typeキーワードは、そのオブジェクトの型を指定します。識別子と同様に、型はIRIである必要があります。[2]
以下の例では型として https://schema.org/Person を使っています。ドキュメントを読むと、このオブジェクトが持ちうるフィールドの一覧を確認できます。

{
  "@type": "https://schema.org/Person",
  "https://schema.org/name": "John Smith",
  "https://schema.org/birthDate": "2004-01-26"
}

なお https://schema.org で使うことのできるすべての型のリストは以下にあります。

https://schema.org/docs/full.html

@context キーワード

@contextは、これまでとは少し毛色の違うキーワードです。

JSON-LDでは、基本的にプロパティ名をIRIで書くことになるため、工夫しなければ素のJSONと比べて著しく可読性が落ちてしまいます。
そこで、@contextキーワードを使うと、IRIに対して人間が読みやすい名前を割り当てることができます。

下の例では@contextを使って各IRIに別名を付けています。

{
  "@context": {
    "name": "https://schema.org/name",
    "birthDate": "https://schema.org/birthDate"
  },
  "name": "John Smith",
  "birthDate": "2004-01-26"
}

また型として設定されているIRIであっても別名を付けることができます。

{
  "@context": {
    "name": "https://schema.org/name",
    "birthDate": "https://schema.org/birthDate",
    "Person": "https://schema.org/Person"
  },
  "@id": "https://example.com/users/john-smith",
  "@type": "Person",
  "name": "John Smith",
  "birthDate": "2004-01-26"
}

キーワードに対して別名をつけることも可能です。ここでは@idに対してidという別名を付けています。

{
  "@context": {
    "id": "@id",
    "name": "https://schema.org/name",
    "birthDate": "https://schema.org/birthDate",
    "Person": "https://schema.org/Person"
  },
  "id": "https://example.com/users/john-smith",
  "@type": "Person",
  "name": "John Smith",
  "birthDate": "2004-01-26"
}

また@contextは、以下のようにプロパティの値の型を指定することもできます。
このようにすることでimageプロパティの値であるhttps://example.com/users/john-smith/icon.pngが単なるリテラルではなくIRIであることを示せます。

{
  "@context": {
    "id": "@id",
    "name": "https://schema.org/name",
    "birthDate": "https://schema.org/birthDate",
    "image": {
        "@id": "https://schema.org/image",
        "@type": "@id"
    }
  },
  "id": "https://example.com/users/john-smith",
  "name": "John Smith",
  "birthDate": "2004-01-26",
  "image": "https://example.com/users/john-smith/icon.png"
}

ここまではJSON-LDの中にインラインで文脈を書いてきました(Embedded context)が、@contextは外部の文脈(External context document)を参照することもできます。
以下の例では schema.org で用意されているコンテキストを利用してJSON-LDを記述しています。namebirthDateのみならず、idimageについても schmea.org が定義してくれているため、@contextを非常に簡単に済ますことができました。

{
  "@context": "https://schema.org",
  "id": "https://example.com/users/john-smith",
  "name": "John Smith",
  "birthDate": "2004-01-26",
  "image": "https://example.com/users/john-smith/icon.png"
}

インラインの文脈と外部の文脈を同時に使いたい場合には、JSONの配列を利用できます。

{
  "@context": [
    "https://schema.org",
    {
      "url": "@id"
    }
  ],
  "url": "https://example.com/users/john-smith",
  "name": "John Smith",
  "birthDate": "2004-01-26",
  "image": "https://example.com/users/john-smith/icon.png"
}

その他のキーワード

すべてのキーワードの一覧は以下に網羅されています。

https://www.w3.org/TR/json-ld/#syntax-tokens-and-keywords

RDFとの関連

JSON-LDは、RDF(Resource Description Framework)を記述するものでもあります。詳しくは 10. Relationship to RDF を参照してください。

また RDFを記述する構文 も参考になります。

参考

脚注
  1. > A string is interpreted as an IRI when it is the value of a map entry with the key @id https://www.w3.org/TR/json-ld/#iris ↩︎

  2. > In Linked Data, types are uniquely identified with an IRI. https://www.w3.org/TR/json-ld/#node-identifiers ↩︎

GitHubで編集を提案

Discussion