Directus にフロントエンドからアクセスする
Directus は headless CMS なので、フロントエンドから動的にコンテンツ取得、もしくは SSG のようなツールを使ってビルド時にコンテンツ取得などをして利用することになる。そこで欠かせないのが公式の SDK だ。
公式の SDK は以下のページに詳細が記載されており、なかなか手厚いサポートがされている。
導入は以下のようにパッケージをプロジェクトに追加するだけ。
$ npm install @directus/sdk
ちなみに、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 の指定の仕方には癖があり、どうやって抽出すればいいか試行錯誤が発生することが何度かあったということもある。もうちょっとクエリ組み立てのための仕組みがあったらありがたいと思ったりした。