スキーマチュートリアル
スキーマチュートリアルレッスン10:ブロックから構造化データを取得する

レッスン10:ブロックから構造化データを取得する

投稿内の(Gutenberg)ブロックを繰り返し処理し、ブロック構造の深部からその属性を抽出することで、これらの属性をサイトのあらゆる機能に活用できるようになります。

たとえば、投稿内のすべての core/image ブロックに含まれる画像URLを抽出することで、それらの画像を使ったイメージカルーセルを作成できます。

さらに、ブロックの属性がブロックエディター外でも広くアクセス可能になることで、これらをまさに構造化コンテンツとして扱い、APIを通じて公開することで、モバイルアプリやニュースレターなどあらゆるアプリケーションに活用できます。

これにより、ブロックをすべてのコンテンツの唯一の信頼できる情報源として扱い、COPE("Create Once, Publish Everywhere")戦略に従って異なるメディアやアプリにコンテンツを配信することができます。

このチュートリアルレッスンでは、投稿内のすべての core/image ブロックから画像URLを取得する方法を示します。

投稿内のすべての core/image ブロックから画像URLを抽出する

このGraphQLクエリは、フィールド blockFlattenedDataItems を使って投稿内のすべてのブロック(インナーブロックを含む)を取得し、core/image タイプでフィルタリングします。次にすべてのエントリを繰り返し処理し、各エントリからプロパティ attributes.url を抽出してフィールド値を上書きします。最後に @arrayUnique を使って重複するURL(2つの core/image ブロックが同じ画像を使用している場合)を削除します:

query GetImageBlockImageURLs($postID: ID!) {
  post(by: { id: $postID } ) {
    coreImageURLs: blockFlattenedDataItems(
      filterBy: { include: "core/image" }
    )
      @underEachArrayItem(
        passValueOnwardsAs: "blockDataItem"
      )
        @applyField(
          name: "_objectProperty"
          arguments: {
            object: $blockDataItem,
            by: {
              path: "attributes.url"
            }
          }
          setResultInResponse: true
        )
      @arrayUnique
  }
}

レスポンスは以下のとおりです:

{
  "data": {
    "post": {
      "coreImageURLs": [
        "https://d.pr/i/fW6V3V+",
        "https://gatographql.lndo.site/wp-content/uploads/2022/05/GatoGraphQL-logo-1024x622.jpg",
        "https://gatographql.lndo.site/wp-content/uploads/2022/05/GatoGraphQL-logo-suki-1024x598.webp"
      ]
    }
  }
}

@underEachArrayItemField Value Iteration and Manipulation エクステンションが提供)は、コンポーザブルディレクティブ(または「メタディレクティブ」、ネストされたディレクティブを含むことができるディレクティブ)であり、要素の配列を繰り返し処理し、各要素にネストされたディレクティブを適用します。

@underEachArrayItem は GraphQL の型間の橋渡しに役立ちます。[String] 値を返すフィールドに対して、String 値を入力として受け取るディレクティブを適用すること(またはその他の組み合わせ)が可能になります。

たとえば、以下のクエリでは:

  • フィールド User.capabilities[String] を返します
  • ディレクティブ @strUpperCaseString を受け取ります

@underEachArrayItem のおかげで、すべてのcapabilityアイテムを大文字に変換できます:

{
  user(by: { id: 3 }) {
    capabilities
      @underEachArrayItem
        @strUpperCase
  }
}

...結果は以下のとおりです:

{
  "data": {
    "user": {
      "capabilities": [
        "LEVEL_0",
        "READ",
        "READ_PRIVATE_EVENTS",
        "READ_PRIVATE_LOCATIONS"
      ]
    }
  }
}