---
title: "GraphQLのコンテンツスキーマ"
slug: "the-graphql-content-schema"
abstract: "GraphQL標準スキーマプロバイダーでSitecoreのコンテンツアイテムをクエリする説明。"
---
# GraphQLのコンテンツスキーマ

Sitecore GraphQLは標準的なスキーマプロバイダーを備えており、Sitecoreコンテンツ項目をクエリするために使います。このプロバイダーは、強型テンプレートアクセス、フィールドタイプのメタデータサポートなど、コンテンツデータを必要とするほとんどのフロントエンドプロジェクトSitecore理想的なアクセスレイヤーを備えています。

## 強いタイプ型の項目

GraphQLは型とインターフェースをサポートしており、テンプレート定義をスキーマに注入することでそれらを利用できます。特定のタイプからフィールドを選択するインラインフラグメントを使うことで、強い型付けのテンプレートフィールドを得ることができます。以下は、この方法でデフォルトのホームアイテムのフィールドを取得する例です:

{
 item(path: "/sitecore/content/home") {
 id
 ...on SampleItem {
 text {
 editable
 }
 title {
 editable
 }
 }
 }
}

このクエリは次のような結果を返します。

{
 "data": {
 "item": {
 "id": "{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}",
 "text": {
 "editable": "<p style=\\"line-height: 22px;\\">From a single connected platform that also integrates with other customer-facing platforms, to a single view of the customer in a big data marketing repository, to completely eliminating much of the complexity that has previously held marketers back, the latest version of Sitecore makes customer experience highly achievable. Learn how the latest version of Sitecore gives marketers the complete data, integrated tools, and automation capabilities to engage customers throughout an iterative lifecycle &ndash; the technology foundation absolutely necessary to win customers for life.</p>\\n<p>For further information, please go to the <a rel=\\"noopener noreferrer\\" href=\\"https://doc.sitecore.net/\\" target=\\"\_blank\\" title=\\"Sitecore Documentation site\\">Sitecore Documentation site</a></p>"
 },
 "title": {
 "editable": "Sitecore Experience Platform"
 }
 }
 }
}

GraphQL型システムはテンプレート継承をサポートしています。以下の例は、アイテムのInsert Optionsが指す項目を取得する方法を示しています:

{
 item(path: "/sitecore/content/home") {
 # Treat the home item as the system 'Insert Options' template type, and this works
 ...on InsertOptions {
 masters {
 targetItems {
 displayName
 uri
 }
 }
 }
 }
}
## タイプされたフィールドアクセス

Sitecore GraphQLリンクフィールドやマルチリストなどのフィールド値への型付きアクセスをサポートしています。

以下は、拡張サンプルアイテムテンプレート上で実行されたパスによるアイテムクエリの例です。

{
 item(path: "/sitecore/content/home") {
 \_\_typename
 # Sample multilist and link (additional fields also available)
 ...on SampleItem {
 myMultilist {
 targetItems {
 id
 path
 ...on Home {
 navigationTitle {
 editable
 }
 }
 }
 }
 myLinkField {
 url
 text
 editable
 }
 }

 # Typing in named-field API
 myLinkFieldByName: field(name: "My Link Field") {
 name
 editable
 ...on LinkField {
 url
 text
 }
 }
 }
}

前述の例で定義されたクエリでは、Sitecore GraphQLは次のようなデータ構造を返します。

{

"data": {
 "item": {

"\_\_typename": "SampleItem",

"myMultilist": {

"targetItems": 
 {

"id": "{C7C95984-E060-42D9-BBC6-B45C18768905}",

"path": "/sitecore/content/Habitat/Settings"
 },
 {
 "id":
"{DAC24EDD-44FB-42EF-9ECD-1E8DAF706386}",

"path": "/sitecore/content/Habitat/Home",

"navigationTitle": {

"editable": "Navigation Title"
 }
 }
 
 },

"myLinkField": {

"url": "https://sitecore.net",

"text": "Awesome Link",

"editable": "<a
href=\\"https://sitecore.net\\">Awesome Link</a>"
 },

"myLinkFieldByName": {

"name": "My Link Field",

"editable": "<a href=\\"https://sitecore.net\\">Awesome
Link</a>",

"url": "https://sitecore.net",

"text": "Awesome Link"
 }
 }
 }
}

## テンプレートアクセス

APIを使ってSitecoreテンプレートにアクセスできます。例えば:

{
 templates(path: "/sitecore/templates/sample/Sample Item") {
 name
 baseTemplates {
 name
 }
 ownFields {
 name
 id
 unversioned
 shared
 }
 }
}

GraphQL型システムにより、ownFieldsが返す型は、定義上アイテムフィールド上で返されるのと同じ型の配列であり、同じ実装で返されます。これにより、例えば特別なアイテムフィルタリングの結果を公開したい場合など、リッチAPIを公開しやすくなります。その後、GraphQLフィールドから返ItemInterfaceGraphTypeし、Itemをソースとして渡します。テンプレートフィールドの定義を取得するなど、ユーザーにはそのItemInterfaceGraphTypeクエリの全機能が利用可能です。

## コンテンツ検索API

キーワード検索のニーズを満たすために設計された基本的なコンテンツSearch APIがあります。主に、検索クエリが汎用APIの複雑さを超えて急速に複雑になるためです。以下はこのAPIの利用例です:

{
 search(keyword: "sample" first: 3 facetOn: "\_template") {
 results {
 # Result info using the Connection pagination pattern
 # (the standard way to do paging in GraphQL)
 totalCount
 pageInfo {
 hasNextPage
 hasPreviousPage
 }
 items {
 # these values are from the index
 score
 path
 # but this resolves the actual item - and because it's an Item type
 # we can do anything we can do to an item - type it, query it
 # anything. It's lazy, so unless we query the item property, the item
 # is not looked up.
 item {
 icon
 ...on Template {
 masters {
 displayName
 }
 }
 }
 }
 }
 # and we can do faceting, too
 facets {
 name
 values(hideEmpty: true) {
 count
 # just like the search results, for facets that are IDs,
 # we can choose to resolve their Item from the database
 # and query it with full capabilities
 item {
 displayName
 icon
 }
 }
 }
 }
}

結果は以下の通りです:

{
 "data": {
 "search": {
 "results": {
 "totalCount": 12,
 "pageInfo": {
 "hasNextPage": true,
 "hasPreviousPage": false
 },
 "items": 
 {
 "score": 2.16668963432312,
 "path": "/sitecore/system/settings/rules/insert options/rules/analytics campaigns",
 "item": {
 "icon": "http://habitat.dev.local/-/icon/Software/32x32/shape\_ellipse.png"
 }
 },
 ...
 
 },
 "facets": 
 {
 "name": "\_template",
 "values": 
 {
 "count": 3,
 "item": {
 "displayName": "Sublayout",
 "icon": "http://habitat.dev.local/-/icon/Software/16x16/element\_selection.png"
 }
 },
 {
 "count": 2,
 "item": {
 "displayName": "Folder",
 "icon": "http://habitat.dev.local/-/icon/Applications/16x16/folder.png"
 }
 },
 ...
 
 }
 
 }
 }
}

## 購読

サブスクリプションはリアルタイムのデータ更新に対する単純な抽象化です。これは[SignalR](https://www.asp.net/signalr)の動作に似ていますが、サブスクリプションは特定の種類のGraphQLクエリに限定されています。クエリは行いますが、すぐには結果が得られません。クエリは停止を指示するまで開いたままで、複数のリアルタイム結果を返すことができます。例としてはitemSavedサブスクリプションがあります。

subscription {
 itemSaved {
 item {
 id
 ...on SampleItem {
 title {
 rendered
 }
 }
 }
 changes {
 fieldChanges {
 fieldName
 newValue
 }
 }
 }
}

このサブスクリプションが開始されると、コンテンツエンドポイントのデータベースにアイテムが保存されるたびに新しいクエリ結果が表示されます。

{
 "itemSaved": {
 "item": {
 "id": "{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}",
 "title": {
 "rendered": "subscriptions rock"
 }
 },
 "changes": {
 "fieldChanges": 
 {
 "fieldName": "\_\_Updated",
 "newValue": "20171222T153248Z"
 },
 ...
 
 }
 }
}

サブスクリプションはWebSocketプロトコルを使ってリアルタイム性を実現します。UIのリアルタイム要素を可能にします。サブスクリプションはサーバーの[Reactive Extensions](https://github.com/Reactive-Extensions/Rx.NET)やクライアントの[RxJS](https://github.com/Reactive-Extensions/RxJS)のObservableパターンによく合致します。observableは非同期のイベントストリームや、複数回解決可能なJavaScript Promiseのようなものと考えられます。

## ユニークな名前

Sitecoreでは、複数のテンプレートが同じ名前(例: *File*)を持ち、テンプレートはアイテムグラフタイプのコアフィールドと名前が競合するフィールドを持つことができます(例: *Icon*)。

GraphQLでは、型やフィールドの名前は一意でなければなりません。命名の衝突が発生した場合、最新の作成日を持つアイテムやフィールドアイテムが名前に付加 \_{guid} されています。作成日が使われるのは、順序付けが安定していてグラフタイプ名が時間経過しても一貫性を保つよう設計されているためです。もし誤ってシステムテンプレートと同じ名前のテンプレートを作成しても、そのシステムテンプレートのグラフタイプ名は古いため変わりません。

この問題を避けるために、Sitecoreで定義されたテンプレートの一部だけを強くタイプできます。これは顧客が作成したAPIエンドポイントのベストプラクティスであり、これらのエンドポイントはプロジェクト内で定義されたテンプレートのみを提供すればよいからです。

> !注テンプレート名の変更は生成されたGraphQLスキーマに影響を与えることがあります。場合によっては、テンプレートの名前変更がタイプ名の変更を引き起こすことがあります(例えば、重複名が存在し、曖昧さ回避が再計算される場合など)、これによりそれらの型名に依存する既存のクエリが壊れることがあります。可能な限り自動生成型名に依存するのは避けてください。