コケないREST APIの実装

にメンテナンス済み

kintone の JavaScript カスタマイズにおいて、パフォーマンスに最も影響があるのは REST API の実行、もしくは外部 API の実行である場合が多いかと思います。

REST API のパフォーマンス改善を考えた際、まず検討すべきポイントはレコードの取得条件と取得フィールドを最小限にすることです。

ただ、取得フィールドを制限することで、取得したものと勘違いしてフィールドを参照し、エラーになる経験をされた方は多いんじゃないでしょうか。

TypeScript を使用していれば、厳格な型定義を行うことで防ぐことが可能ですが、今まではどうしても冗長な定義が必要になっていました。

TypeScript 4.9 から実装された satisfies operator を使用することで、無駄のない型定義をもって安全に REST API のレコード情報を取り扱えるようになりました。

今回は satisfies operator を使った絶対にコケない REST API の実装方法を紹介します。

必要な環境

  • TypeScript 4.9 以上

サンプルコード

/** dts-genで作成したアプリの型定義 */
type SavedFields = sample.SavedFields;

/** REST APIで取得するアプリのフィールド */
const FIELD_CODES = ['フィールドコードA', 'フィールドコードB'] as const satisfies Readonly<
  (keyof SavedFields)[]
>;

/** REST APIで取得するアプリのフィールド */
type FieldCodes = (typeof FIELDS)[number];

/** 取得したフィールドに限定したレコード情報 */
type ReferencedFields = Pick<SavedFields, FieldCodes>;

const client = new KintoneRestAPIClient({
  /* ... */
});

const getRecords = async (): Promise<ReferencedFields[]> => {
  const app = 9999;
  const query = 'ID = 99999';

  const records = await client.record.getAllRecordsWithCursor<ReferencedFields>({
    app,
    query,
    fields: FIELD_CODES,
  });

  return records;
};

解説

satisfies operator で実現できるようになったのは以下の部分です。

const FIELD_CODES = ['フィールドコードA', 'フィールドコードB'] as const satisfies Readonly<
  (keyof SavedFields)[]
>;

今までは使用するフィールドコードを定数として定義しようとした場合、以下のように定義する必要がありました。

const FIELD_CODES: (keyof SavedFields)[] = ['フィールドコードA', 'フィールドコードB'];

これによって、「指定したフィールドコードが確かに存在しているか」をチェックすることは可能です。

ただ、型推論が働かず、取得するレコード情報の型としてこの定数を利用することができませんでした。

const FIELD_CODES: (keyof SavedFields)[] = ['フィールドコードA', 'フィールドコードB'];

type FieldCodes = (typeof FIELD_CODES)[number]; // keyof SavedFields と推論され、厳格ではない

定数を REST API のレコード情報として反映したい場合は as const を使用することで実現できますが、今度は「指定したフィールドコードが確かに存在しているか」をチェックすることができません。

const FIELD_CODES = ['フィールドコードA', 'フィールドコードB'] as const;

type FieldCodes = (typeof FIELD_CODES)[number]; // "フィールドコードA" | "フィールドコードB"

satisfies operator を使用することで、前述したコードの両方の条件を満たした定数定義・型定義が可能になります。

const FIELD_CODES = ['フィールドコードA', 'フィールドコードB'] as const satisfies Readonly<
  (keyof SavedFields)[]
>;
#kintone #typescript