この記事はmicroCMS Advent Calendar 2021 23日目の記事です。
現在のWeb開発では、JavaScriptではなくTypeScriptを導入することが主流となっています。型安全な開発は、ヒューマンエラーを事前に回避できるなど開発時の負担を減らすことができます。
今回は型安全にフォーカスして、Web APIに型付できるHTTPクライアントライブラリ「Aspida」をご紹介します。microCMSで作成したAPIを例に上げてAspidaを体験してみましょう。
Aspidaのリポジトリはこちらになります。
https://github.com/aspida/aspida
Aspidaを使うメリット
microCMSのAPIを取得する単純なFetch APIのコード例は以下になります。
const response = await fetch(`${BASE_URL}/content?limit=10`, {
headers: {
"X-MICROCMS-API-KEY": "your-key",
},
});
そして、AspidaでAPIを取得する場合は以下になります。
const response = await client.content.$get({ query: { limit: 10 } });
単純なFetch APIを使ったコード例と比べて、Aspidaを使うと以下3点の型定義の恩恵を受けられるようになります。
- エンドポイントがプロパティとなり補完される
- GETリクエストで使えるクエリが補完される
- 返り値に型が付く
型がないFetch APIの例では、エンドポイントが単純なstringだったので、打ち間違い等でエラーが起こる可能性がありました。それが型定義によって回避されます。
ここまでの型情報があれば、microCMSで扱っているAPIを把握しやすいですし、ヒューマンエラーも事前に防ぐことができます。これがAspidaを使う最大のメリットとなります。
microCMSでAPIを作成する
Aspidaで型定義を作成する前に、microCMSの管理画面でAPIを作成してみましょう。初めてご利用する場合はドキュメントの操作マニュアルを参照してください。
APIの基本情報を入力しましょう。API名にコンテンツ、エンドポイントにcontentとします。
APIの型を選択します。ここではリスト形式を選択します。
APIスキーマ(インターフェース)にはtitle(テキストフィールド)とbody(リッチエディタ)を定義します。右下の完了をクリックしてAPIを作成しましょう。
APIの作成が完了したら、コンテンツを作成しましょう。タイトルと内容を入力して公開します。
作成したコンテンツのレスポンス例は以下となります。
{
"contents": [
{
"id": "emvw8q6i4",
"createdAt": "2021-12-09T07:19:31.259Z",
"updatedAt": "2021-12-09T07:19:31.259Z",
"publishedAt": "2021-12-09T07:19:31.259Z",
"revisedAt": "2021-12-09T07:19:31.259Z",
"title": "これはテストです",
"body": "<p>これはテストです!</p>"
}
],
"totalCount": 1,
"offset": 0,
"limit": 10
}
Aspidaのセットアップ
まずは、Aspidaとmicrocms-js-sdkをインストールしていきます。microcms-js-sdkでは、レスポンスやクエリなどの型定義をSDK内部で提供しています。
$ npm install --save aspida microcms-js-sdk
そして、pacakge.jsonのscriptsにapi:buildコマンドを追加します。
scripts: {
"api:build": "aspida"
}
Aspidaでクライアントを生成する
Aspidaではapiディレクトリ配下の定義ファイルを参照して生成します。
デフォルトはルートディレクトリ配下のapiディレクトリですが、aspida.config.js
の設定にinputを追加することで、参照するパスを変更することもできます。
// aspida.config.js
module.exports = {
input: "src/api",
};
コンテンツの型定義を作成します。ここだけは手動で型定義をします。
// api/types.ts
export type Content = {
title?: string
body?: string
}
そして、型定義を生成するための設定ファイルを作成します。apiディレクトリ配下にcontent/index.ts
を作成します。これで、コンテンツの一覧情報を取得したい場合は、client.content.$get()とすることデータを取得することができます。
// api/content/index.ts
import { MicroCMSListResponse, MicroCMSQueries } from 'microcms-js-sdk';
import { Content } from '../types';
export type Methods = {
get: {
query?: MicroCMSQueries,
resBody: MicroCMSListResponse<Content>
}
}
MicroCMSListResponseの型定義は以下のようになっています。これはmicroCMSのレスポンスの型定義となります。
export interface MicroCMSListResponse<T> {
contents: (T & MicroCMSListContent)[];
totalCount: number;
limit: number;
offset: number;
}
これでビルドしてみましょう。$api.ts
が生成されます。
$ npm run api:build
$api.ts
の使い方は以下になります。your-keyはmicroCMSで確認できるAPIキーを入力してください。
// index.ts
import api from "./api/$api";
import aspida from "@aspida/fetch";
const fetchConfig = {
headers: {
'X-MICROCMS-API-KEY': 'your-key',
},
baseURL: 'https://your.microcms.io/api/v1',
};
const client = api(aspida(fetch, fetchConfig));
実際にAPIを呼び出す例はこのようになります。queryはオプションとなります。
const response = await client.content.$get({ query: { limit: 10 } });
コンテンツ詳細のクライアントを生成する
次に、コンテンツ詳細の型定義をしていきましょう。フォルダ名を_id@stringとすると、パスに渡す変数の型定義もすることができます。
// api/content/_id@string/index.ts
import { MicroCMSObjectContent, MicroCMSQueries } from 'microcms-js-sdk';
import { Content } from '../../types';
export type Methods = {
get: {
query?: Pick<MicroCMSQueries, 'draftKey' | 'fields' | 'depth'>,
resBody: Content & MicroCMSObjectContent
}
}
生成した型定義を利用する例は以下となります。content_idは管理画面で確認することができます。
const response = await client.content._id("content_id").$get()
最後に
以上、Aspida + microcms-js-sdkを使った型安全なAPI開発をご紹介しました。現在microCMSではOpenAPIに対応したAPIを開発中です。Aspidaを含め、型安全に開発する方法として、将来的にさまざまな選択肢が増える予定です。ぜひお待ちいただければ嬉しいです。
参考記事
https://zenn.dev/ria/articles/0356a07280d8d153e5e5
https://speakerdeck.com/texmeijin/next-dot-js-isr-x-microcms-x-linaria-x-aspidadebao-su-medeiakai-fa
-----
microCMSは日々改善を進めています。
ご意見・ご要望は管理画面右下のチャット、公式Twitter、お問い合わせからお気軽にご連絡ください!
引き続きmicroCMSをよろしくお願いいたします!