สร้าง API เพื่อทำ Pagination ด้วย NestJS และ Prisma

Aug. 13, 2024 · boychawin

วันนี้เราจะทำมา API ให้รองรับ Pagination กันครับ การที่เราจัดการข้อมูลที่มีจำนวนมากในการแสดงผลหน้าเว็บ จำเป็นต้องใช้ Pagination ซึ่งจะช่วยแบ่งข้อมูลออกเป็นหลายๆ หน้า ทำให้ไม่ต้องแสดงข้อมูลทั้งหมดในคราวเดียว ซึ่งจะช่วยลดเวลาในการโหลดและทำให้ UX (User Experience) ดีขึ้น ในบทความนี้ เราจะสาธิตวิธีการสร้าง API สำหรับ Pagination โดยใช้ NestJS และ Prisma

1. การสร้าง API Endpoint สำหรับ Pagination

ก่อนอื่น เราต้องสร้าง API Endpoint ใน NestJS เพื่อรับค่าพารามิเตอร์ skip และ take ซึ่งจะใช้ในการกำหนดจำนวนข้อมูลที่ต้องการข้าม (skip) และจำนวนข้อมูลที่ต้องการดึง (take) จากฐานข้อมูล นอกจากนี้เรายังสามารถใช้ cursor เพื่อระบุจุดเริ่มต้นของการดึงข้อมูล(cursor แต่รอบนี้ยังไม่ใช้นะ 😂)


@Get('getProductList')
getProductList(
  @Query('skip') skip: string,
  @Query('take') take: string,
//   @Query('cursor') cursor: string,
) {
  const params = { skip: +skip, take: +take, cursor: +cursor };
  return this.medicineWarehouseService.getProductList(params);
}

ในโค้ดด้านบน เราได้สร้าง API Endpoint ที่ชื่อว่า getProductList ซึ่งจะรับพารามิเตอร์ skip, take, และ cursor ผ่าน @Query decorator เพื่อใช้ในการกำหนดจำนวนข้อมูลที่จะดึงจากฐานข้อมูล

2. การใช้งาน Prisma ในการดึงข้อมูลจากฐานข้อมูล

หลังจากที่เราได้รับพารามิเตอร์จาก API แล้ว ขั้นตอนต่อไปคือการใช้ Prisma เพื่อดึงข้อมูลจากฐานข้อมูล และนับจำนวนข้อมูลทั้งหมด เพื่อให้สามารถคำนวณจำนวนหน้าที่จะต้องใช้ในการแสดงผลได้


async getProductList(params: any) {
  try {
    let skip: number = params.skip || 0;
    let take: number = params.take || 10;
    let where: Prisma.ListProductWhereInput = {};
    let orderBy: any = [{ id: 'desc' }];

    const transaction = await this.prisma.$transaction([
      this.prisma.listProduct.count(),
      this.prisma.listProduct.findMany({
        skip,
        take,
        where,
        orderBy,
        select: {
          id: true,
          name: true,
          stock: true,
          ...
        },
      }),
    ]);

    const count = transaction[0];
    const results = transaction[1];

    if (results.length <= 0) {
       return "..."
    }

    return { data: results, count: count };
  } catch (error) {
    console.log('error:', error);
    return "..."
  }
}

ในฟังก์ชัน getProductList เราได้ใช้ this.prisma.$transaction เพื่อดึงข้อมูลจากฐานข้อมูลพร้อมกับนับจำนวนข้อมูลทั้งหมดในคราวเดียว การใช้ $transaction ทำให้เราสามารถรันหลายคำสั่ง SQL พร้อมกันได้ในครั้งเดียว ซึ่งจะช่วยเพิ่มประสิทธิภาพในการทำงาน

  • count: ใช้สำหรับนับจำนวนข้อมูลทั้งหมดในตาราง listProduct
  • findMany: ใช้สำหรับดึงข้อมูลที่ต้องการแสดงผลตามพารามิเตอร์ skip และ take

3. การตอบสนองของ API

API ของเราจะส่งข้อมูลจำนวนรายการ (count) และข้อมูลที่ดึงได้ (results) กลับไปยัง Frontend เพื่อใช้ในการแสดงผลตารางพร้อม Pagination โดยข้อมูลทั้งหมดจะถูกจัดเรียง (orderBy) ตามลำดับของ id ในแบบจากมากไปน้อย (desc) และเรามีอีกบทความ สร้างตารางแบ่งหน้า (Pagination) ใน Next.js ด้วย SWR

สรุป

การสร้าง API เพื่อทำ Pagination ใน NestJS โดยใช้ Prisma เป็นวิธีที่มีประสิทธิภาพในการจัดการข้อมูลที่มีจำนวนมาก ช่วยให้สามารถควบคุมการแสดงผลข้อมูลในแต่ละหน้าได้อย่างสะดวก และเพิ่มประสิทธิภาพในการโหลดข้อมูล การใช้พารามิเตอร์ skip และ take ช่วยให้การจัดการ Pagination เป็นไปได้ง่าย และการใช้ $transaction ทำให้เราสามารถรวมหลายคำสั่ง SQL เข้าด้วยกันในครั้งเดียว ช่วยให้การทำงานมีความรวดเร็วมากยิ่งขึ้น

บทความนี้น่าจะช่วยให้เข้าใจวิธีการสร้าง API สำหรับการทำ Pagination ด้วย NestJS และ Prisma และสามารถนำไปประยุกต์ใช้ในโปรเจกต์ได้นะครับ ขอบคุณครับ 🧑🏻‍💻