<पी> इस पोस्ट में, हम आपको दिखाएंगे कि SaaS एप्लिकेशन के लिए कोटा सिस्टम बनाने के लिए अपस्टैश का उपयोग कैसे करें, जो Next.js के साथ बनाया गया है। और प्रिज्मा . हम एक सरल एपीआई बनाने के लिए Next.js एपीआई मार्गों का उपयोग करेंगे। <पी> कई SaaS एप्लिकेशन में, आपको कोटा प्रणाली का सामना करना पड़ा होगा। यह एक ऐसी प्रणाली है जो एक उपयोगकर्ता द्वारा एक निश्चित समय में किए जाने वाले कार्यों की संख्या को सीमित करती है। <पी> हमारे उदाहरण में, एक उपयोगकर्ता प्रति माह केवल 1,000 API अनुरोध भेज सकता है "निःशुल्क" पर योजना. यदि उपयोगकर्ता 1,000 से अधिक एपीआई अनुरोध भेजने का प्रयास करता है, तो एप्लिकेशन उपयोगकर्ता को अधिक अनुरोध भेजने से रोक देगा। <पी> उन एपीआई अनुरोधों का उपयोग स्प्रेडशीट की सामग्री को पुनः प्राप्त करने और उसे JSON में बदलने के लिए किया जाता है। फ़ास्टशीट यही करती है, किसी भी Google शीट स्प्रेडशीट को JSON API में बदल देती है। <पी>
डेटाबेस स्कीमा को परिभाषित करना
<पी> जैसा कि पहले कहा गया था, हम डेटाबेस के साथ इंटरैक्ट करने के लिए प्रिज्मा को ORM के रूप में उपयोग करेंगे। यहां User का एक उदाहरण दिया गया है मॉडल जो कोटा प्रणाली लागू करता है, साथ ही इसका Spreadsheet भी लागू करता है स्प्रेडशीट संग्रहीत करने के लिए मॉडल : 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 फ़ील्ड वह योजना है जिसकी उपयोगकर्ता ने सदस्यता ली है।
- द
quota फ़ील्ड चालू माह में उपयोगकर्ता द्वारा किए गए एपीआई अनुरोधों की संख्या है।
- द
Spreadsheet मॉडल एक स्प्रेडशीट का प्रतिनिधित्व करता है, जो User से जुड़ा होता है .
- ए
User एकाधिक Spreadsheet हो सकते हैं इससे जुड़ा हुआ.
<पी> चीजों को सरल बनाए रखने के लिए, हम केवल "FREE" को संभालेंगे योजना, जो प्रति माह 1,000 एपीआई अनुरोधों की अनुमति देती है . उपयोगकर्ता का कोटा बढ़ाया जा रहा है
<पी> जब भी उपयोगकर्ता एपीआई अनुरोध करता है तो हम उपयोगकर्ता का कोटा बढ़ाना चाहते हैं। <पी> पहली नज़र में ऐसा करना आसान और सीधा लगता है। जब भी उपयोगकर्ता एपीआई अनुरोध करता है तो हम उपयोगकर्ता का कोटा 1 बढ़ा सकते हैं हमारे 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 });
}
<पी> हालाँकि इस दृष्टिकोण के साथ एक समस्या है, यह उतना तेज़ नहीं है जितना होना चाहिए। <पी> दरअसल, हम प्रत्येक एपीआई अनुरोध पर उपयोगकर्ता का कोटा बढ़ाने के लिए एक डेटाबेस लेनदेन बना रहे हैं . <पी> हम उपयोगकर्ता का कोटा प्राप्त करने के लिए डेटाबेस तक पहुंचते हैं, कोटा को 1 तक बढ़ाने के लिए एक लेनदेन बनाते हैं , और फिर स्प्रेडशीट सामग्री भेजें। <पी> यह कई कारणों से इष्टतम नहीं है: - आपका डेटाबेस धीमा हो सकता है, इससे आपकी प्रतिक्रिया का समय धीमा हो जाएगा।
- आपका डेटाबेस आपके सर्वर से दूर हो सकता है, इससे आपका प्रतिक्रिया समय फिर से धीमा हो जाएगा।
- इस कोड को एज संगत बनाना कठिन है , आपको दुनिया भर में कई डेटाबेस प्रतिकृतियां बनाने की आवश्यकता है (ऐसा करना आसान काम नहीं है!) .
उपयोगकर्ता का कोटा बढ़ाने के लिए अपस्टैश का उपयोग करना
<पी> इस समस्या को हल करने के लिए, हम उपयोगकर्ता का कोटा बढ़ाने के लिए अपस्टैश रेडिस® का उपयोग करेंगे। अपस्टैश रेडिस® एक तेज़ और विश्वसनीय रेडिस® डेटाबेस है, जो सर्वर रहित वातावरण के लिए बनाए गए क्लाउड में होस्ट किया गया है, जो एज के लिए तैयार है (अपने उपयोगकर्ताओं के पास कोड चलाएं) . <पी> हम INCR का उपयोग करेंगे उपयोगकर्ता का कोटा 1 बढ़ाने के लिए 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 });
}
<पी> अपस्टैश रेडिस® का उपयोग करने से आपका कोड आसानी से स्केलेबल हो जाता है, क्योंकि आप अपस्टैश रेडिस® एज की शक्ति का लाभ उठा सकते हैं। अपने कोड को अपने उपयोगकर्ताओं के करीब चलाने के लिए। निष्कर्ष
<पी> अपस्टैश रेडिस® सर्वर रहित वातावरण के लिए कैशिंग सिस्टम को कार्यान्वित करना बहुत आसान बनाता है। <पी> हमने इसका उपयोग कोटा प्रणाली को लागू करने के लिए किया था, लेकिन मूल विचार को बहुत अधिक उपयोग-मामलों पर लागू किया जा सकता है, जैसे कि अधिक डेटाबेस क्वेरीज़ को कैश करना, या एपीआई अनुरोध के परिणामों को कैश करना। <पी> कैशिंग का अंतिम लक्ष्य आपके एपीआई को तेज़ बनाना और कम संसाधनों का उपभोग करने की अधिक संभावना बनाना है (उदाहरण के लिए प्लैनेटस्केल डेटाबेस प्रश्नों को पढ़ता/लिखता है) . <पी> भविष्य के लेख में, हम देखेंगे कि Redis® से उपयोगकर्ता का कोटा पुनर्प्राप्त करने और इसे डेटाबेस में संग्रहीत करने के लिए Upstash QStash का उपयोग कैसे करें, ताकि यह सुनिश्चित हो सके कि उपयोगकर्ता का कोटा हमेशा अद्यतित रहे और खो न जाए। इसे लाइव देखें
<पी> यदि आप इस प्रकार के अनुकूलन को लाइव देखना चाहते हैं, तो आप फ़ास्टशीट देख सकते हैं , एक एपीआई सेवा जो कुछ ही क्लिक में आपकी Google शीट को एपीआई में बदल देती है। यह एक उदार फ्री टियर के साथ उपयोग करने के लिए मुफ़्त है।