Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Redis

Xây dựng hệ thống hạn ngạch đáng tin cậy cho SaaS của bạn với Upstash &Next.js

Trong bài đăng này, chúng tôi sẽ hướng dẫn bạn cách sử dụng Upstash để tạo hệ thống hạn ngạch cho ứng dụng SaaS, được tạo bằng Next.jsPrisma . Chúng tôi sẽ sử dụng các tuyến API Next.js để tạo một API đơn giản.

Trong nhiều ứng dụng SaaS, bạn có thể đã gặp phải hệ thống hạn ngạch. Đây là một hệ thống giới hạn số lượng hành động mà người dùng có thể thực hiện trong một thời gian nhất định.

Trong ví dụ của chúng tôi, người dùng chỉ có thể gửi 1.000 yêu cầu API mỗi tháng trên "Miễn phí" kế hoạch. Nếu người dùng cố gắng gửi hơn 1.000 yêu cầu API, ứng dụng sẽ chặn người dùng gửi thêm yêu cầu.

Các yêu cầu API đó được sử dụng để truy xuất nội dung của bảng tính và biến nó thành JSON. Đây là chức năng của fastsheet, biến bất kỳ bảng tính Google Trang tính nào thành API JSON.

Xây dựng hệ thống hạn ngạch đáng tin cậy cho SaaS của bạn với Upstash &Next.js

Xác định lược đồ cơ sở dữ liệu

Như đã nói trước đó, chúng tôi sẽ sử dụng Prisma làm ORM để tương tác với cơ sở dữ liệu. Đây là một ví dụ về User mô hình triển khai hệ thống hạn ngạch cũng như Spreadsheet của nó mô hình lưu trữ bảng tính :

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
}
  • planId trường là gói mà người dùng đã đăng ký.
  • Số quota trường là số lượng yêu cầu API mà người dùng đã thực hiện trong tháng hiện tại.
  • Spreadsheet mô hình đại diện cho một bảng tính được kết nối với User .
  • Một User có thể có nhiều Spreadsheet được liên kết với nó.

Để đơn giản, chúng tôi sẽ chỉ xử lý "FREE" gói cho phép 1.000 yêu cầu API mỗi tháng .

Tăng hạn ngạch của người dùng

Chúng tôi muốn tăng hạn ngạch của người dùng mỗi khi người dùng đưa ra yêu cầu API.

Thoạt nhìn, điều này có vẻ dễ dàng và đơn giản để thực hiện. Chúng tôi chỉ có thể tăng hạn ngạch của người dùng lên 1 mỗi khi người dùng đưa ra yêu cầu API trên lộ trình API Next.js của chúng tôi:

// 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 });
}

Tuy nhiên có một vấn đề với cách tiếp cận này, nó không nhanh như mong đợi.

Thật vậy, chúng tôi đang tạo một giao dịch cơ sở dữ liệu để tăng hạn ngạch của người dùng đối với mọi yêu cầu API .

Chúng tôi truy cập cơ sở dữ liệu để lấy hạn ngạch của người dùng, tạo giao dịch để tăng hạn ngạch lên 1 , sau đó gửi nội dung bảng tính.

Điều này không tối ưu vì nhiều lý do:

  • Cơ sở dữ liệu của bạn có thể chậm, điều này sẽ làm chậm thời gian phản hồi của bạn.
  • Cơ sở dữ liệu của bạn có thể ở xa máy chủ, điều này sẽ lại làm chậm thời gian phản hồi của bạn.
  • Mã này khó Tương thích với Edge hơn , bạn cần tạo nhiều bản sao cơ sở dữ liệu trên khắp thế giới (không phải là một nhiệm vụ dễ thực hiện!) .

Sử dụng Upstash để tăng hạn mức người dùng

Để giải quyết vấn đề này, chúng tôi sẽ sử dụng Upstash Redis® để tăng hạn ngạch của người dùng. Upstash Redis® là cơ sở dữ liệu Redis® nhanh và đáng tin cậy, được lưu trữ trên đám mây dành cho môi trường không có máy chủ, sẵn sàng cho Edge (chạy mã gần gũi với người dùng của bạn) .

Chúng ta sẽ sử dụng INCR Lệnh Redis® để tăng hạn ngạch của người dùng lên 1. Lệnh này mang tính nguyên tử, có nghĩa là nó sẽ chỉ được thực thi một lần và sẽ được thực thi nhanh chóng.

Đây là mã tương tự như trước, nhưng sử dụng Upstash Redis® để quản lý hạn ngạch của người dùng:

// 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 });
}

Việc sử dụng Upstash Redis® giúp mã của bạn có thể mở rộng dễ dàng vì bạn có thể tận dụng sức mạnh của Upstash Redis® Edge để chạy mã của bạn gần gũi với người dùng.

Kết luận

Upstash Redis® giúp việc triển khai hệ thống bộ nhớ đệm cho môi trường không có máy chủ trở nên rất dễ dàng.

Chúng tôi đã sử dụng nó để triển khai hệ thống hạn ngạch nhưng ý tưởng ban đầu có thể được áp dụng cho nhiều trường hợp sử dụng hơn, chẳng hạn như lưu vào bộ nhớ đệm nhiều truy vấn cơ sở dữ liệu hơn hoặc lưu vào bộ nhớ đệm kết quả của một yêu cầu API.

Mục tiêu cuối cùng của bộ nhớ đệm là làm cho API của bạn nhanh hơn và có nhiều khả năng tiêu thụ ít tài nguyên hơn (ví dụ:truy vấn đọc/ghi cơ sở dữ liệu Planetscale) .

Trong bài viết sau, chúng ta sẽ xem cách sử dụng Upstash QStash để truy xuất hạn ngạch của người dùng từ Redis® và lưu trữ trong cơ sở dữ liệu, nhằm đảm bảo rằng hạn ngạch của người dùng luôn cập nhật và không bị mất.

Xem trực tiếp

Nếu bạn muốn xem trực tiếp loại tối ưu hóa này, bạn có thể xem fastsheet , một dịch vụ API biến Google Trang tính của bạn thành API chỉ sau vài cú nhấp chuột. Nó được sử dụng miễn phí với mức miễn phí hào phóng.