🐙

TypeORMでカーソル型ページネーションを実装する

2024/08/29に公開

はじめに

TypeORMでは、skipとtakeを使用したオフセット型ページネーションをサポートしていますが、カーソル型のページネーションはサポートしていません。

そのため、「typeorm-cursor-pagination」というライブラリを使用して実装していきます。
https://www.npmjs.com/package/typeorm-cursor-pagination

実装

こちらが、カーソル型ページネーションの実装です。

import { AppDataSource } from "typeorm";
import { buildPaginator } from 'typeorm-cursor-pagination';

const AppDataSource = new DataSource({
    // DBの設定
})

const queryBuilder = AppDataSource
  .getRepository(User)
  .createQueryBuilder('user')
  .where("user.gender = :gender", { gender: 'male' });

const paginator = buildPaginator({
  entity: User,
  paginationKeys: ['id'],
  query: {
    limit: 10,
    order: 'ASC',
    beforeCursor: cursor.beforeCursor
    afterCursor:  cursor.afterCursor
  },
});

// Pass queryBuilder as parameter to get paginate result.
const { data, cursor } = await paginator.paginate(queryBuilder);

まず、TypeORMのcreateQueryBuilderを使用し、DBから取得するデータの条件などを決めます。

次に、「typeorm-cursor-pagination」のbuildPaginatorを使用し、どのような条件でページネーションを行うかを定義します。

buildPaginator は下記のオプションを指定できます。

  • entity(必須): TypeORMで定義した取得したデータのエンティティ。
  • paginationKeys(オプション): ページネーションに用いられるカラムを指定する。デフォルトはid。
  • query(オプション): ページネーションの仕様を定める
    • limit: 取得するレコード数。デフォルトは100件。
    • order: ASCまたはDESCを指定する。デフォルトはDESC。paginationKeysで指定されたカラムをソートする。
    • beforCursor: 前のページを取得するために指定するカーソル。
    • afterCursor: 次のページを取得するために指定するカーソル。

最後に、paginateメソッドによってデータとカーソルを取得することができます。
取得するデータとカーソルのインターフェースは下記の通り。

interface PagingResult<Entity> {
  data: Entity[];
  cursor: Cursor;
}

interface Cursor {
  beforeCursor: string | null;
  afterCursor: string | null;
}

まとめ

このように、「typeorm-cursor-pagination」を使用すると、TypeORMでも簡単にカーソル型ページネーションを実装できました。
また機会があればプロジェクトで使用したいと思います。

NCDCエンジニアブログ

Discussion