1. GraphQL について
1)GraphQL とは
GraphQL(グラフキューエル)とは、2012年にFacebook社が社内で開発し、2015年にオープンソース化したAPI向けに作られたクエリ言語(Query Language)、およびその実装(ランタイム)を指します。
2)GraphQL と REST の比較
GraphQLを使うと、1回のHTTPリクエストで複数の異なる種類のデータを受け取ることが可能になります。

出典:「GraphQLとRESTの比較」
(1)RESTのようなレスポンスのデータを使ってさらにAPIリクエストの繰り返しを回避することができます。
(2)特定の要件に限定して配信することができる。
(3)単一のAPIクエリに対するレスポンスとして、レンダリングに必要なものだけを一括して配信できるようにする。
3)GraphQLの用語
【1】エンドポイント(Endpoint)
エンドポイントとは、特定のリソースに与えられる一意のURIのことです。GraphQLは基本的に単一のエンドポイントです。
例えば、AEM グローバル GraphQL エンドポイントのリポジトリパスは以下の通りです。
/content/cq:graphql/global/endpoint.json
この場合、アプリはリクエストURLで以下のパスを使用することができます。
http://localhost:4502/content/_cq_graphql/global/endpoint.json
【2】クエリ(Query)
GraphQLのクエリ言語は、基本的にオブジェクトのフィールドを選択するものです。
query {
user (id: 1){
id
name
address {
street
city
}
}
}
{
"data": {
"user": {
"id": 1,
"name": "Elmo",
"address": {
"street": "Sesame street",
"city": "New York City"
}
}
}
}
【3】スキーマ(Schema)
GraphQL スキーマは、GraphQL APIの型システムを定義するものです。
クライアントがアクセスできるデータの完全な集合を記述しています。
GraphQL スキーマは、オブジェクトタイプで構成され、どの種類のオブジェクトをリクエストでき、どのフィールドを指定できるかを定義します。
type Query {
user: User
}
type User{
id: ID!
name: String!
address: Address!
}
type Address{
street: String!
city: String!
}
【4】型(Type)
(1)スカラー(Scalar)型
- String(文字列型)
- Int(整数型)
- Float(浮動小数点型)
- Boolean(論理型)
- ID(ID型)
なお、ID型の実態は文字列型(String)ですが、GraphQLの仕様上ユニークでなければならない点でString型と区別されています。
(2)オブジェクト(Object)型
1つ以上のスキーマで定義されているフィールドの集合をオブジェクト型といいます。JSONのように入れ子にすることが可能です。
下記の Group 、 User は、オブジェクト型です。
type Group {
id: ID!
name: String
user: User
}
type User {
id: ID!
firstName: String
lastName: String
age: Int
}
(3)リスト(List)型
フィールドには型のリストを定義することが可能です。
type Group {
id: ID!
memberName: [String]
}
(4)ルート(Root)型
GraphQLのクエリはルート型で始まります。
【5】フィールド(Field)
フィールドは、オブジェクトから取り出せるデータの単位です。
GraphQLの操作はすべて、スカラー値を返すフィールドまで指定して、明確に形成されたレスポンスを確保する必要があります。
2. AEM に GraphQL 利用の前提条件
AEMでGraphQL APIを使用すると、ヘッドレスCMSの実装でJavaScriptクライアントに Content Fragment を効率的に配信することができます。ただし、AEMでGraphQLを利用するためには、さまざまな条件を満たす必要があります。
1)AEM の シナリオ
GraphQLは現在、AEMの2つの(別々の)シナリオで使用されています。
(1)AEM Commerceは、GraphQLを介してCommerceプラットフォームからデータを消費します。
(2)AEM Content Fragmentsは、AEM GraphQL API(標準のGraphQLをベースにカスタマイズされた実装)と連携し、アプリケーションで使用する構造化コンテンツを提供します。
本記事では、(2)に関して紹介します。
2)AEM の 環境要件
今現在GraphQLを利用できるのは、下記2種類のAEM環境です。
下記ツールのインストールファイルを予め用意する必要があります。
特に、AEMインスタンスにNode.jsをインストールすることを忘れないでください。
リポジトリを追加します。
$ curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -
Node.jsをインストールします。
$ sudo yum install -y nodejs
正常にインストールされることを確認します。
$ node -v
3. AEM における GraphQL の実現
これから、AEM における GraphQL の実現方法を紹介致します。アーキタイププロジェクトの作成については、付録に参考してください。
1)GraphQL プロジェクトの作成
(1)AEMの[スタート]メニューから、 [ツール] >[一般] >[設定ブラウザ]に移動します。

(2)WKND SPA React を選択し、「Properties」アイコンをクリックします。

(3)GraphQL Persistent Queries を選択し、「Save & Close」アイコンをクリックします。

(4)CRXDE Lite画面より、/conf/wknd-spa-react/settingsの配下、graphqlノードが追加されたことを確認できます。

2)GraphQL エンドポイントの有効化と公開
(1)AEMの[スタート]メニューから、 [ツール] >[アセット] >[GraphQL]に移動します。

(2)Create をクリックします。

(3)Name を入力し、「Use GraphQL schema provided by ... *」に、上記作成したプロジェクトを選択し、「Create」をクリックします。

(4)下記のメッセージが表示されています。
セキュリティコンソールを使用して、新しく作成されたエンドポイントに適切な権限が設定されていることを確認してください。
メッセージの内容に従い、「the Security console」リンクをクリックします。

(5)everyone グループの権限設定画面に遷移され、

/content/cq:graphql/wknd-spa-react にリード権限を付与します。

(6)CRXDE Lite画面より、/content/cq:graphql/wknd-spa-react の配下、endpoint ノードが追加されたことを確認できます。

(7)再び[GraphQL]画面に移動し、作成したエンドポイントを選択し、「公開」ボタンを押下すると、公開されます。
CORS - Cross Origin Resource Sharing
(1)AEMのOSGi 設定画面を開きます。
http://localhost:4502/system/console/configMgr
(2)Adobe Granite Cross-Origin Resource Sharing Policy をクリックし、下記のように入力し保存します。

(3)Adobe Granite CSRF Filter をクリックし、下記のように入力し保存します。

4)言語ルートフォルダ の作成
(1)AEMの[スタート]メニューから、 [ナビゲーション] >[アセット] >[ファイル]に移動します。

(2)WKND SPA React フォルダーをクリックします。

(3)[Create] >[Folder]をクリックします。

(4)Nameに言語コード(英語:en)で入力し、「Create」をクリックします。

(5)言語フォルダーを選択し、「Properties」をクリックします。

(6)フォルダーのプロパティ設定画面が遷移され、「Cloud Services」タブをクリックし、「Inherited from /content/dam/wknd-spa-react」がチェックされていることを確認します。

5)コンテンツフラグメント モデルの定義
(1)AEMの[スタート]メニューから、 [ツール] >[アセット] >[コンテンツフラグメントモデル]に移動します。

(2)WKND SPA React をクリックします。

(3)右上の「Create」アイコンをクリックし、「コンテンツフラグメント」をクリックします。

(4)先に「Address」のコンテンツフラグメントモデルを作成します。

※ここでは、「モデルを有効化」の☑チェックボックスを入れます。
(5)二つのテキストフィールド「Street」、「City」を作成し、保存します。

(6)次に「User」のコンテンツフラグメントモデルを作成します。

(7)番号フィールド「ID」とテキストフィールド「Name」を先に作成します、

フラグメント参照フィールドを追加し、「許可されているコンテンツフラグメントモデル」をクリックします。
(8)パス選択画面では、「Address」コンテンツフラグメントモデルを選択し、「選択」をクリックします。

(9)「User」コンテンツフラグメントモデル編集画面に戻り、保存します。

※「Address」コンテンツフラグメントモデルが選択されることが確認できます。
(10)また、その他のコンテンツフラグメントモデルの作成方法について、下記に参照してください。
Create Content Fragment Models
作成したコンテンツフラグメントモデルは、下記のようです。

(11)CRXDE Lite画面より、/conf/wknd-spa-react/settings/dam/cfm/models の配下、コンテンツフラグメントモデルのノードが追加されたことを確認できます。

6)コンテンツフラグメント モデルの確認
(1)ここでは、GraphQL Tool 画面を開き、追加されたコンテンツフラグメントモデル情報を確認します。
http://localhost:4502/content/graphiql.html
キーボードの「Ctlキー」を押しながら、「Spaceキー」を押下すると、入力出来る候補一覧が表示されます、ここで、「query」をクリックします。

「{」を入力し、再び候補一覧を表示すると、「addressList」、「userList」が表示されることを確認できます。これは、「Address」コンテンツフラグメントモデル、「User」コンテンツフラグメントモデルが作成されることで、自動生成されるものです。

さらに、「addressList」を選択し、候補一覧より「items」を入力し、クエリ実行ボタンを押下すると、「addressList」の項目定義が表示されています。中身がまだ空っぽです。

同様に、「userList」の項目定義も表示できます。

7)コンテンツフラグメント の作成
(1)これから、「Address」コンテンツフラグメントを作成します。
AEMの[スタート]メニューから、 [ツール] >[アセット] >[ファイル]に移動します。
WKND SPA React をクリックし、右上の「Create」アイコンをクリックし、「コンテンツフラグメント」をクリックします。

「Address」コンテンツフラグメントモデルを選択し、「次へ」をクリックします。

タイトルを入力し、「作成」をクリックします。

コンテンツフラグメント編集画面では、番地(Street)と市区町村(City)を入力し、保存します。

(2)次は、「User」コンテンツフラグメントを作成します。
右上の「Create」アイコンをクリックし、「コンテンツフラグメント」をクリックします。

「User」コンテンツフラグメントモデルを選択し、「次へ」をクリックします。

タイトルを入力し、「作成」をクリックします。

コンテンツフラグメント編集画面では、IDと名前(Name)を入力し、Addressの選択ダイアログを開きます。

選択ダイアログでは、先ほどの「Address」コンテンツフラグメントを選択し、「選択」ボタンをクリックします。

コンテンツフラグメント編集画面に戻り、Addressのパスを確認し、保存します。

8)コンテンツフラグメント の確認
(1)再び、GraphQL Tool 画面を開き、作成されたコンテンツフラグメント情報を確認します。
http://localhost:4502/content/graphiql.html
「addressList」の項目には、ちゃんと「Address」コンテンツフラグメントの各フィールドの値が表示されることを確認できます。

「userList」の項目にでも、「Address」フィールドを含め、「User」コンテンツフラグメントの各フィールドの値が表示されることを確認できます。

【付録】 アーキタイププロジェクトの作成
1)開発環境(Author、Publish)作成
AEM as a Cloud Service の開発環境を事前に作成します。

任意のフォルダーに、Git Bash より下記のMavenコマンドを入力します。
$mvn -Padobe-public \
-B archetype:generate \
-D archetypeGroupId=com.adobe.aem \
-D archetypeArtifactId=aem-project-archetype \
-D archetypeVersion=31 \
-D aemVersion=cloud \
-D sdkVersion=latest \
-D appTitle="WKND SPA React" \
-D appId="wknd-spa-react" \
-D artifactId="aem-guides-wknd-spa.react" \
-D groupId="com.adobe.aem.guides.wkndspa.react" \
-D frontendModule="react" \
-D includeExamples=n \
-D singleCountry=n \
-D includeDispatcherConfig=n
BUILD SUCCESS が表示したら、aem-guides-wknd-spa.reactフォルダーが追加され、

中身が下記の構造になっています。

作成したアーキタイププロジェクトをビルドする前に、AEMのプロセスを起動します。
また、aem-guides-wknd-spa.reactフォルダー直下のpom.xmlに、AEMプロセスのIPアドレス、ポート番号、パスワードの設定が必要です。

下記のMavenコマンドを入力し、アーキタイププロジェクトをビルドします。
$mvn -Padobe-public clean install -DskipTests=true -PautoInstallSinglePackage
下記メッセージが表示すれば、ビルド完了です。
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for WKND SPA React 1.0.0-SNAPSHOT:
[INFO]
[INFO] WKND SPA React ..................................... SUCCESS [ 1.460 s]
[INFO] WKND SPA React - Core .............................. SUCCESS [ 19.357 s]
[INFO] WKND SPA React - UI Frontend ....................... SUCCESS [01:21 min]
[INFO] WKND SPA React - Repository Structure Package ...... SUCCESS [ 3.071 s]
[INFO] WKND SPA React - UI apps ........................... SUCCESS [ 17.958 s]
[INFO] WKND SPA React - UI content ........................ SUCCESS [ 11.120 s]
[INFO] WKND SPA React - UI config ......................... SUCCESS [ 1.138 s]
[INFO] WKND SPA React - All ............................... SUCCESS [01:03 min]
[INFO] WKND SPA React - Integration Tests ................. SUCCESS [ 46.317 s]
[INFO] WKND SPA React - UI Tests .......................... SUCCESS [ 0.553 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
AEMのパケージマネージャー画面より、ビルドしたパケージが自動的にインストールされることを確認できます。
