Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

สร้างระบบโควต้าที่เชื่อถือได้สำหรับ SaaS ของคุณด้วย Upstash &Next.js

ในโพสต์นี้ เราจะแสดงวิธีใช้ Upstash เพื่อสร้างระบบโควต้าสำหรับแอปพลิเคชัน SaaS ที่สร้างด้วย Next.js และ ปริซึม . เราจะใช้เส้นทาง Next.js API เพื่อสร้าง API แบบง่าย

ในแอปพลิเคชัน SaaS จำนวนมาก คุณอาจพบระบบโควต้า เป็นระบบที่จำกัดจำนวนการกระทำที่ผู้ใช้สามารถทำได้ในช่วงเวลาที่กำหนด

ในตัวอย่างของเรา ผู้ใช้สามารถส่งคำขอ API ได้เพียง 1,000 คำขอต่อเดือน บน "ฟรี" แผน หากผู้ใช้พยายามส่งคำขอ API มากกว่า 1,000 รายการ แอปพลิเคชันจะบล็อกผู้ใช้ไม่ให้ส่งคำขอเพิ่มเติม

คำขอ API เหล่านั้นใช้เพื่อดึงเนื้อหาของสเปรดชีตและแปลงเป็น JSON นี่คือสิ่งที่ Fastsheet ทำ เปลี่ยนสเปรดชีต Google ชีตให้เป็น JSON API

สร้างระบบโควต้าที่เชื่อถือได้สำหรับ SaaS ของคุณด้วย Upstash &Next.js

การกำหนดสคีมาฐานข้อมูล

ดังที่ได้กล่าวไว้ก่อนหน้านี้ เราจะใช้ Prisma เป็น ORM เพื่อโต้ตอบกับฐานข้อมูล นี่คือตัวอย่างของ 03 โมเดลที่ใช้ระบบโควต้า เช่นเดียวกับ 11 รูปแบบการจัดเก็บ สเปรดชีต :

model User {
 id Int @id @default(autoincrement())
 planId String @default("FREE")
 email String @unique
 quota Int @default(0)
 spreadsheets Spreadsheet[]
}
model Spreadsheet {
 id Int @id @default(autoincrement())
 userId Int
 user User @relation(fields: [userId], references: [id])
 content String
}
  • รหัส <24 ช่องคือแผนที่ผู้ใช้สมัครเป็นสมาชิก
  • 36 ฟิลด์คือจำนวนคำขอ API ที่ผู้ใช้ได้ทำในเดือนปัจจุบัน
  • รหัส <42 model แสดงถึงสเปรดชีตที่เชื่อมต่อกับ 52 .
  • A 60 สามารถมีได้หลาย 77 เชื่อมโยงกับมัน

เพื่อให้ทุกอย่างง่ายขึ้น เราจะจัดการเฉพาะ 82 เท่านั้น แผนซึ่งอนุญาต คำขอ API 1,000 รายการต่อเดือน .

การเพิ่มโควต้าของผู้ใช้

เราต้องการเพิ่มโควต้าของผู้ใช้ทุกครั้งที่ผู้ใช้ส่งคำขอ API

เมื่อมองแวบแรก สิ่งนี้ดูเหมือนง่ายและตรงไปตรงมา เราสามารถเพิ่มโควต้าของผู้ใช้ได้ 1 ทุกครั้งที่ผู้ใช้ส่งคำขอ API บนเส้นทาง Next.js API ของเรา:

// pages/api/spreadsheets/[id]/index.ts
import type { NextApiRequest, NextApiResponse } from "next";
 
const MAX_FREE_TIER_QUOTA = 1000;
 
export default async function handler(
 req: NextApiRequest,
 res: NextApiResponse,
) {
 // Get the ID of the spreadsheet from the URL.
 const { id } = req.params;
 
 // Get the spreadsheet and its associated user from the database.
 const spreadsheet = await prisma.spreadsheet.findUnique({
 where: { id: Number(id) },
 include: { user: true },
 });
 
 // Verify that the spreadsheet exists.
 if (!spreadsheet) {
 return res.status(404).json({ error: "Spreadsheet not found" });
 }
 
 // Verify that the user is not over the quota.
 if (spreadsheet.user.quota >= MAX_FREE_TIER_QUOTA) {
 return res.status(429).json({ error: "Quota exceeded" });
 }
 
 // Increase the user's quota by 1.
 await prisma.user.update({
 where: { id: spreadsheet.user.id },
 data: { quota: { increment: 1 } },
 });
 
 // Return the spreadsheet's content.
 return res.json({ content: spreadsheet.content });
}

อย่างไรก็ตาม แนวทางนี้มีปัญหา แต่ก็ไม่เร็วเท่าที่ควร

แท้จริงแล้ว เรากำลังสร้างธุรกรรมฐานข้อมูลเพื่อเพิ่มโควต้าของผู้ใช้ในทุกคำขอ API .

เราเข้าถึงฐานข้อมูลเพื่อรับโควต้าของผู้ใช้ สร้างธุรกรรมเพื่อเพิ่มโควต้า 1 แล้วส่งเนื้อหาสเปรดชีต

สิ่งนี้ไม่เหมาะสมด้วยเหตุผลหลายประการ:

  • ฐานข้อมูลของคุณอาจช้า ซึ่งจะทำให้เวลาตอบสนองของคุณช้าลง
  • ฐานข้อมูลของคุณอาจอยู่ไกลจากเซิร์ฟเวอร์ของคุณ ซึ่งจะทำให้เวลาตอบสนองของคุณช้าลงอีกครั้ง
  • โค้ดนี้ยากที่จะทำให้ เข้ากันได้กับ Edge คุณต้องสร้างแบบจำลองฐานข้อมูลหลายแห่งทั่วโลก (ไม่ใช่เรื่องง่ายที่จะทำ!) .

การใช้ Upstash เพื่อเพิ่มโควต้าของผู้ใช้

เพื่อแก้ไขปัญหานี้ เราจะใช้ Upstash Redis® เพื่อเพิ่มโควต้าของผู้ใช้ Upstash Redis® เป็นฐานข้อมูล Redis® ที่รวดเร็วและเชื่อถือได้ ซึ่งโฮสต์อยู่ในระบบคลาวด์ที่สร้างขึ้นสำหรับสภาพแวดล้อมแบบไร้เซิร์ฟเวอร์ พร้อมสำหรับ Edge (เรียกใช้โค้ดใกล้กับผู้ใช้ของคุณ) .

เราจะใช้ 97 คำสั่ง Redis® เพื่อเพิ่มโควต้าของผู้ใช้ 1 คำสั่งนี้เป็นแบบอะตอมมิก ซึ่งหมายความว่าจะดำเนินการเพียงครั้งเดียวและจะดำเนินการอย่างรวดเร็ว

นี่คือโค้ดเดียวกันกับเมื่อก่อน แต่ใช้ Upstash Redis® เพื่อจัดการโควต้าของผู้ใช้:

// pages/api/spreadsheets/[id]/index.ts
import type { NextApiRequest, NextApiResponse } from "next";
 
import { Redis } from "@upstash/redis";
 
const MAX_FREE_TIER_QUOTA = 1000;
 
// Generate an Upstash Redis instance using environment variables.
// Make sure those are defined in your .env file.
const redis = new Redis({
 url: process.env.UPSTASH_REDIS_REST_URL!,
 token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});
 
export default async function handler(
 req: NextApiRequest,
 res: NextApiResponse,
) {
 // Get the ID of the spreadsheet from the URL.
 const { id } = req.params;
 
 // Get the spreadsheet and its associated user from the database.
 const spreadsheet = await prisma.spreadsheet.findUnique({
 where: { id: Number(id) },
 include: { user: true },
 });
 
 // Verify that the spreadsheet exists.
 if (!spreadsheet) {
 return res.status(404).json({ error: "Spreadsheet not found" });
 }
 
 // Redis quota key, unique for each user by its ID.
 const quotaKey = `user:${spreadsheet.user.id}:quota`;
 
 // Retrieve the user's quota from Redis.
 const quota = await redis.incr(quotaKey);
 
 // If the key did not exist before, the returned value will be 1
 // and we set the expiration to 1 day.
 if (quota === 1) {
 await redis.expire(quotaKey, 60 * 60 * 24);
 }
 
 // Verify that the user is not over the quota.
 if (quota > MAX_FREE_TIER_QUOTA) {
 return res.status(429).json({ error: "Quota exceeded" });
 }
 
 // Return the spreadsheet's content.
 return res.json({ content: spreadsheet.content });
}

การใช้ Upstash Redis® ทำให้โค้ดของคุณสามารถปรับขนาดได้อย่างง่ายดาย เนื่องจากคุณสามารถใช้ประโยชน์จากพลังของ Upstash Redis® Edge เพื่อเรียกใช้โค้ดของคุณใกล้กับผู้ใช้ของคุณ

บทสรุป

Upstash Redis® ทำให้การติดตั้งระบบแคชสำหรับสภาพแวดล้อมแบบไร้เซิร์ฟเวอร์เป็นเรื่องง่ายมาก

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

เป้าหมายสุดท้ายของการแคชคือทำให้ API ของคุณเร็วขึ้นและมีแนวโน้มที่จะใช้ทรัพยากรน้อยลง (เช่น ข้อความค้นหาการอ่าน/เขียนฐานข้อมูล Planetscale) .

ในบทความหน้า เราจะดูวิธีใช้ Upstash QStash เพื่อดึงโควต้าของผู้ใช้จาก Redis® และจัดเก็บไว้ในฐานข้อมูล เพื่อให้แน่ใจว่าโควต้าของผู้ใช้เป็นข้อมูลล่าสุดอยู่เสมอและไม่สูญหาย

ดูสด

หากคุณต้องการเห็นการเพิ่มประสิทธิภาพประเภทนี้แบบสด คุณสามารถดู fastsheet ซึ่งเป็นบริการ API ที่เปลี่ยน Google ชีตของคุณให้เป็น API ได้ในไม่กี่คลิก ใช้งานได้ฟรีด้วยระดับฟรีจำนวนมาก