よりひろい フロントエンド
Author : Kazuhiro Hara
Author : Kazuhiro Hara
Fri Jun 21 2024

Directus にフロントエンドからアクセスする

Directus は headless CMS なので、フロントエンドから動的にコンテンツ取得、もしくは SSG のようなツールを使ってビルド時にコンテンツ取得などをして利用することになる。そこで欠かせないのが公式の SDK だ。

公式の SDK は以下のページに詳細が記載されており、なかなか手厚いサポートがされている。

導入は以下のようにパッケージをプロジェクトに追加するだけ。

$ npm install @directus/sdk

ちなみに、Directus 上にある情報にアクセスしたい場合は、きちんと読み込みのパーミッションを設定しないといけないので注意しよう。結構パーミッションの設定画面はわかりやすいと思っている。

Directus のパーミッション設定画面

Directus へのアクセスは大きく分けると2つのインターフェースが用意されている。REST で行う形式と GraphQL を使って行う形式だ。実は RealTime というちょっと野心的なインターフェースも用意されているが、それは後のお楽しみにとっておいてある。

通常 CMS の情報にアクセスするには REST 形式か GraphQL 形式かということになるが、僕自身はプロジェクト内で以下のようにどちらもクライアントを用意して使っている。 NEXT_PUBLIC_DIRECTUS_URL というのは、CMS を置いてある URL で環境変数から読み込むようにしてある。

import { createDirectus, graphql, rest } from "@directus/sdk";

// Client with GraphQL support
export const graphqlClient = createDirectus(process.env.NEXT_PUBLIC_DIRECTUS_URL || '').with(graphql());

// Client with Rest support
export const restClient = createDirectus(process.env.NEXT_PUBLIC_DIRECTUS_URL || '').with(rest());

では、REST 版と GraphQL 版でどんな風にアクセスの違いがあるのだろう。

典型的なページを読み込んでみる。このページは多言語化対応をしたコンテンツが登録できるように組んである。それを取得するには、一段階入れ子になった翻訳コンテンツを取得することになるので少し指定が複雑になる。

まずは GraphQL 版。graphqlClient を使い query を指定する。ちなみに /* graphql */ と書いてあるのは、こうすることでテンプレートリテラル内のシンタックスハイライトがオンになるためだ。この関数は特定の1ページだけが欲しいので slug (ページ ID のようなもの) で抽出している。

export async function getPage(
  slug: string,
): Promise<Pages | null> {
  const result = await graphqlClient.query(/* graphql */ `query {
    pages(filter: {slug: {_eq: "${slug}"}}) {
      id
      status
      slug
      translations {
        id
        title
        body
        languages_code {
          code
          name
          direction
        }
      }
    }
  }`);
  return result?.pages || null;
}

つづいて REST 版。REST版も細かな API は違うものの、オブジェクトにてフィルタをかけたり必要なフィールドを指定したりする。

export async function getPage(
  slug: string,
): Promise<Pages | null> {
  const result = await restClient.request<Articles[]>(
    readItems('pages', {
      filter: {
        slug: {
          _eq: slug,
        },
      },
      fields: [
        '*',
        {
          translations: ['*'],
        },
      ],
    })
  );
  // console.log(result);
  return result || null;
}

2つとも使ってみて、個人的には REST 版のほうが使いやすいというのが今の時点の結論。というのも、オブジェクトで指定する REST 版のほうがコード的にいろいろな処理を加えやすいからだ。

加えて、ちょっと Directus の GraphQL の指定の仕方には癖があり、どうやって抽出すればいいか試行錯誤が発生することが何度かあったということもある。もうちょっとクエリ組み立てのための仕組みがあったらありがたいと思ったりした。

DirectusCMSNext.js

Share

About site

「よりひろいフロントエンド」はじめました

いろいろやっている自分を一言で表す言葉として「より広いフロントエンド」を思いつきました。このサイトではこの言葉を中心に ウェブ、XR、UI デザイン、バックエンド、インフラストラクチャーやその周辺のことを興味の赴くまま広くディスカバリーしていきます

About Me

カンソクインダストリーズのロゴ

「よりひろいフロントエンド」運営元 カンソクインダストリーズ では、フロントエンドを中心によろずご相談お受けいたします。お気軽にお問い合わせください。