コケない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)[]
>;