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

สร้างทางเลือก LinkTree แบบโอเพ่นซอร์สฟรีด้วย Astro, Upstash และ GitHub

ในโพสต์นี้ ฉันพูดถึงวิธีที่ itsmy.fyi (ทางเลือกโอเพ่นซอร์สสำหรับ LinkTree) ถูกสร้างขึ้นด้วย Upstash, Astro, GitHub และ Edgio Upstash ช่วยให้ฉันจัดการข้อมูล (CRUD) ของผู้ใช้ทั้งหมด เสนอการจำกัดอัตราที่กว้างขวางเมื่อเปรียบเทียบกับ GitHub API สำหรับการดำเนินการ CRUD และใช้การจำกัดอัตราแบบละเอียด

สร้างทางเลือก LinkTree แบบโอเพ่นซอร์สฟรีด้วย Astro, Upstash และ GitHub

สิ่งที่เราจะใช้

  • Astro (ส่วนหน้าและส่วนหลัง)
  • Upstash (การจำกัดอัตราและการดำเนินการ CRUD)
  • ปัญหา GitHub และ Webhooks (CMS สาธารณะเพื่อจัดการโปรไฟล์ผู้ใช้)
  • Tailwind CSS (สไตล์)
  • Edgio (การปรับใช้)

สิ่งที่คุณต้องการ

  • บัญชี GitHub
  • บัญชี Upstash เพื่อสร้างฐานข้อมูล

การตั้งค่า Upstash Redis

เมื่อคุณสร้างบัญชี Upstash และเข้าสู่ระบบแล้ว คุณจะไปที่แท็บ Redis และสร้างฐานข้อมูล

สร้างทางเลือก LinkTree แบบโอเพ่นซอร์สฟรีด้วย Astro, Upstash และ GitHub

สร้างทางเลือก LinkTree แบบโอเพ่นซอร์สฟรีด้วย Astro, Upstash และ GitHub

หลังจากที่คุณสร้างฐานข้อมูลแล้ว คุณจะไปที่แท็บรายละเอียด เลื่อนลงไปจนพบ 02 ส่วน คัดลอกเนื้อหาและบันทึกไว้ในที่ที่ปลอดภัย

สร้างทางเลือก LinkTree แบบโอเพ่นซอร์สฟรีด้วย Astro, Upstash และ GitHub

นอกจากนี้ ให้เลื่อนลงไปจนกว่าคุณจะพบส่วน REST API แล้วเลือกปุ่ม .env คัดลอกเนื้อหาและบันทึกไว้ในที่ที่ปลอดภัย

สร้างทางเลือก LinkTree แบบโอเพ่นซอร์สฟรีด้วย Astro, Upstash และ GitHub

การตั้งค่าโครงการ

หากต้องการตั้งค่า เพียงโคลน repo ของแอปแล้วทำตามบทช่วยสอนนี้เพื่อเรียนรู้ทุกอย่างที่อยู่ในนั้น หากต้องการแยกโปรเจ็กต์ ให้รัน:

git clone https://github.com/rishi-raj-jain/itsmy.fyi
cd itsmy.fyi
yarn install

เมื่อคุณโคลน repo แล้ว คุณจะต้องสร้างไฟล์ .env คุณกำลังจะเพิ่มรายการที่เราบันทึกไว้จากส่วนด้านบน

มันควรมีลักษณะดังนี้:

.env
# Obtained from your GitHub repo
GITHUB_API_TOKEN="to_create_and_update_github_comments"
GITHUB_WEBHOOK_SECRET="if_you_are_matching_github_webhooks_sha256"
 
# Obtained from the steps as above
UPSTASH_DB="your_upstash_redis_from_above"
UPSTASH_REDIS_REST_URL="your_upstash_redis_rest__url_from_above"
UPSTASH_REDIS_REST_TOKEN="your_upstash_redis_rest__token_from_above"

หลังจากขั้นตอนเหล่านี้ คุณควรจะสามารถเริ่มต้นสภาพแวดล้อมภายในเครื่องได้โดยใช้คำสั่งต่อไปนี้:

yarn run edgio:dev

โครงสร้างพื้นที่เก็บข้อมูล

นี่คือโครงสร้างโฟลเดอร์หลักสำหรับโปรเจ็กต์ ฉันได้วงกลมสีแดงไว้ในไฟล์ที่จะกล่าวถึงเพิ่มเติมในโพสต์นี้ที่เกี่ยวข้องกับการดำเนินการ CRUD การจำกัดอัตรา และไฟล์ที่มีการอ้างอิง

สร้างทางเลือก LinkTree แบบโอเพ่นซอร์สฟรีด้วย Astro, Upstash และ GitHub

กระแสข้อมูลระดับสูง

นี่คือแผนภาพระดับสูงที่แสดงการไหลของข้อมูล

  • หากผู้ใช้เยี่ยมชม itsmy.fyi/me/slug และการตอบสนองต่อหน้านี้ไม่ได้ถูกแคชไว้ (หรือกำลังได้รับการตรวจสอบความถูกต้องอีกครั้ง) ผู้ใช้จะเรียกใช้ฟังก์ชัน getUserInfo ซึ่งจะดึงข้อมูล json ของผู้ใช้จาก Upstash DB
  • หากผู้ใช้สร้าง อัปเดต หรือลบปัญหา GitHub GitHub จะทริกเกอร์ Webhook ซึ่ง POST ไปยังจุดสิ้นสุด ในตำแหน่งข้อมูลนั้น อันดับแรกจะใช้การจำกัดอัตรา Upstash เพื่อประเมินว่าสามารถทำการเปลี่ยนแปลงที่ร้องขอได้หรือไม่ จากนั้นใช้ Upstash ผู้ใช้ json จะถูกสร้างขึ้น อัปเดต หรือลบ

สร้างทางเลือก LinkTree แบบโอเพ่นซอร์สฟรีด้วย Astro, Upstash และ GitHub

โปรไฟล์ผู้ใช้ การดำเนินการ CRUD ผ่าน Upstash Redis

ในส่วนนี้ เราจะเจาะลึกเกี่ยวกับวิธีการดึงข้อมูล การอัปเดต และการลบโปรไฟล์ผู้ใช้ เราใช้ Upstash อย่างต่อเนื่อง (ผ่าน 14 ) เพื่อดึงและแสดงข้อมูล

เหตุใดฉันจึงย้ายจาก GitHub ไปยัง Upstash สำหรับการดำเนินการ CRUD

ในขณะที่ฉันเริ่มต้นด้วย GitHub เป็นแหล่งที่มาของการจัดการข้อมูล:จากแบบฟอร์มข้อมูล Github Issuesas ไปจนถึง GitHub Webhooks ไปจนถึง jsons ผู้ใช้ CRUD ภายในพื้นที่เก็บข้อมูล ข้อจำกัดของ GitHub REST API:27 ดูเหมือนจะจำกัดและค่อนข้างถดถอยการใช้งานตามวัตถุประสงค์ของแพลตฟอร์ม

Upstash โดดเด่นกว่ามากเพราะมันเสนอคำสั่งให้ฉัน 10,000 คำสั่งทุกวันในแผนฟรีของพวกเขาเพื่อเริ่มต้น และหลังจากนั้นก็มีอัตราที่น้อยมากเมื่อการใช้งานของฉันปรับขนาด แนวทางประเภทนี้ทำให้ฉันได้ผู้ใช้มามากขึ้นโดยแทบไม่ต้องเสียค่าใช้จ่ายเลย และทำซ้ำได้เร็วขึ้นโดยไม่ต้องกังวลกับการปรับขนาดและการจัดการต้นทุนของฐานข้อมูล

getUserInfo:การดึงฟังก์ชันโปรไฟล์ผู้ใช้

33 ฟังก์ชั่นใช้ 47 ของ ioredis ผ่าน slug เป็นกุญแจสำคัญในการสร้างคำขอ API เพื่อ Upstash สำหรับหน้าโปรไฟล์ผู้ใช้ที่เกี่ยวข้อง ซึ่งระบุด้วย 54 ที่ไม่ซ้ำกัน หากไม่มีโปรไฟล์ผู้ใช้นั้น (หรือมีข้อผิดพลาด) ฟังก์ชันจะถูกตั้งค่าให้ส่งคืนออบเจ็กต์ที่มี 65 เพื่อให้ผู้ใช้สามารถเปลี่ยนเส้นทางไปที่ 404 โดยอัตโนมัติในเส้นทางไดนามิกของ Astro

// File: lib/Upstash/users/get.js
// Read User Profile Code
 
import redis from "../setup";
 
export async function getUserInfo(slug) {
 try {
 const userData = await redis.hget("profiles", slug);
 const parsedData = JSON.parse(userData);
 if (parsedData.slug === slug) {
 return { ...parsedData, code: 1 };
 }
 return {
 code: 0,
 error: `slug doesn't match for the user.`,
 };
 } catch (e) {
 const error = e.message || e.toString();
 console.log(error);
 return {
 code: 0,
 error,
 };
 }
}

ในทำนองเดียวกัน การดำเนินการ CRUD ที่เหลือจะเป็นดังนี้:

import redis from "../setup";
 
// File: @/lib/Upstash/users/delete.js
// Delete User Profile Code
export async function deleteUserInfo(slug) {
 try {
 await redis.hdel("profiles", slug);
 return { code: 1 };
 } catch (e) {
 console.log(e.message || e.toString());
 return {
 code: 0,
 };
 }
}
 
// File: @/lib/Upstash/users/post.js
// Create/Update User Profile Code
export async function postUserInfo(data) {
 try {
 await redis.hset("profiles", data.slug, JSON.stringify(data));
 return { code: 1 };
 } catch (e) {
 const error = e.message || e.toString();
 console.log(error);
 return {
 code: 0,
 error,
 };
 }
}

การจำกัดอัตรา

หากต้องการใช้การจำกัดอัตราในสภาพแวดล้อมแบบไร้เซิร์ฟเวอร์ด้วย Edgio เราใช้ไคลเอนต์ฐานข้อมูล Upstash Redis และไลบรารีตัวจำกัดอัตราที่เรียกว่า 70 .

@/lib/Upstash/ratelimit.js
// Reference Function to ratelimiting
 
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
 
import { getENV } from "@/lib/env";
 
const url = getENV("UPSTASH_REDIS_REST_URL");
const token = getENV("UPSTASH_REDIS_REST_TOKEN");
 
export const ratelimit = (number, time) => {
 if (url && token) {
 return new Ratelimit({
 redis: new Redis({
 url,
 token,
 }),
 limiter: Ratelimit.fixedWindow(number, time),
 });
 }
 return;
};

การใช้การจำกัดอัตราทำให้ฉันสามารถบรรลุสิ่งต่อไปนี้:

ก. ใช้บริการ - ฟรีและไม่จำกัด

ด้วยการใช้การจำกัดอัตรา ฉันสามารถเปิดเผย API การสร้างโปรไฟล์แบบสาธารณะได้! สิ่งนี้ทำให้ฉันสามารถแสดงประโยชน์ของระบบ เช่น ความง่ายในการตั้งค่าโปรไฟล์ผ่าน GUI แท้จริงแล้วใครก็ตามสามารถสร้าง 3 โปรไฟล์ในหนึ่งสัปดาห์ผ่านทางเว็บไซต์ (itsmy.fyi) เอง และสำหรับการเข้าถึงคุณสมบัติอย่างไม่จำกัด เช่น แก้ไขโปรไฟล์ สร้างโปรไฟล์ไม่จำกัด ผู้ใช้จะต้องเปลี่ยนไปใช้วิธีสร้างโปรไฟล์ของ GitHub เราสามารถบังคับใช้ขีดจำกัดอัตรา 3 โปรไฟล์ในหนึ่งสัปดาห์ตาม IP ที่อยู่เป็นคีย์

// Rate limit 3 profiles in a week via the web for a user
const ratelimitUser = ratelimit(3, 7 * 24 * 60 * 60 + " s");
 
if (rateLimiter) {
 // Look at the x-0-client-ip set by Edgio in serverless
 const result = await rateLimiter.limit("x-0-client-ip");
 limit = result.limit;
 remaining = result.remaining;
 if (!result.success) {
 // Return a message
 }
}

บี ใช้การกลั่นกรองแบบละเอียดกับจำนวนการแก้ไขโดยผู้ใช้

นอกจากนี้ ด้วยการจำกัดอัตรา เราจึงสามารถกลั่นกรองจำนวนการแก้ไขที่ทำโดยผู้ใช้ในหนึ่งนาทีตามชื่อผู้ใช้ GitHub ของพวกเขา ณ ขณะนี้ เราอนุญาตให้พวกเขาทำการเปลี่ยนแปลงได้สูงสุด 3 รายการภายในหนึ่งนาที ซึ่งจะช่วยลดสแปมที่มองไม่เห็น

@/pages/github/hook/issue.js
const rateLimiter = ratelimit(3, "60 s");
 
if (rateLimiter) {
 const result = await rateLimiter.limit(context.sender.login);
 limit = result.limit;
 remaining = result.remaining;
 if (!result.success) {
 return {
 headers: {
 "X-RateLimit-Limit": limit,
 "X-RateLimit-Remaining": remaining,
 },
 body: JSON.stringify({
 message:
 "Too many updates in 1 minute. Please try again in a few minutes.",
 }),
 };
 }
}

การใช้งานเก่าขณะตรวจสอบใหม่บน Edge สำหรับโปรไฟล์ผู้ใช้ทั้งหมด

รหัสต่อไปนี้อธิบายวิธีการใช้แนวคิด Stale While Revalidate เพื่อปรับปรุงอัตราการเข้าชมแคช ในรหัส (ใน 88 ) 97 ใช้เพื่อจับคู่โปรไฟล์ผู้ใช้ทั้งหมด (ที่ขึ้นต้นด้วย 106 ).ภายในวิธีการแคช เราป้องกันการแคชเพจในเบราว์เซอร์ และเปิดใช้งานเฉพาะการแคช Edge เท่านั้นเพื่อให้ให้บริการผู้ใช้อย่างรวดเร็วและด้วยเนื้อหาล่าสุดเสมอ ตัวเลือก Edge ถูกตั้งค่าเป็น 119 เพื่อให้แน่ใจว่าข้อมูลถูกแคชไว้เพียงวินาทีเดียว 129 ตัวเลือกถูกตั้งค่าเป็นปีเพื่อให้ข้อมูลสามารถให้บริการได้โดยตรงจากแคชในขณะที่แคชกำลังรีเฟรช

เส้นทาง js
// User path(s)
router.match("/me/:path", ({ cache, removeUpstreamResponseHeader }) => {
 // Remove the cache-control header from Astro's standalone server
 removeUpstreamResponseHeader("cache-control");
 // Disable in browser caching, and use Edgio's edge to use SWR
 cache({
 edge: {
 maxAgeSeconds: 1,
 staleWhileRevalidateSeconds: 60 * 60 * 24 * 365,
 },
 browser: false,
 });
});

การใช้ Stale While Revalidate สามารถช่วยปรับปรุงประสิทธิภาพของแอปได้โดยการลดภาระบนเซิร์ฟเวอร์และให้การตอบสนองแก่ผู้ใช้เร็วขึ้น

การสร้างโปรไฟล์ผู้ใช้แบบไดนามิกได้ทันที

Astro ทำให้การตั้งค่าเส้นทางแบบไดนามิกเป็นเรื่องง่ายมาก ในแอป คุณจะพบ 133 ซึ่งจับคู่หน้าที่ขึ้นต้นด้วย 147 .ตัวอย่างได้แก่ 152 และ 163 .

กำลังดึงข้อมูลโปรไฟล์ผู้ใช้

เราดึงข้อมูลสำหรับผู้ใช้ปัจจุบันโดยใช้ 173 พารามิเตอร์การสืบค้นที่แยกออกจากพารามิเตอร์ Astro และเรียกใช้ฟังก์ชัน getUserInfo (ตามที่อธิบายไว้ข้างต้น) เพื่อรับข้อมูลผู้ใช้ที่เกี่ยวข้องทั้งหมด ในกรณีที่ไม่พบหรือมีข้อผิดพลาด เราจะเปลี่ยนเส้นทางผู้เยี่ยมชมไปที่ 404

src/pages/me/[กระสุน].astro
import { getUserInfo } from "@/lib/Upstash/users";
 
// Extract slug query
const { slug } = Astro.params;
 
// Get data from Upstash using the getUserInfo function
const {
 name: userName,
 image: userImage,
 links = [],
 socials = [],
 about = "",
 og = {},
 background = {},
 code = 1,
} = await getUserInfo(userSlug);
 
// In case the code: 0 is recevied, redirect to a 404
if (code === 0) {
 return Astro.redirect("/404");
}

ปรับใช้จาก CLI

คุณสามารถสร้างเวอร์ชันที่ใช้งานจริงของแอปและทดสอบในเครื่องได้โดยใช้:

yarn run edgio:build && yarn run edgio:production

การปรับใช้ต้องมีบัญชีใน Edgio ลงทะเบียนที่นี่ฟรี เมื่อคุณมีบัญชีแล้ว คุณสามารถปรับใช้กับ Edgio ได้โดยการรันคำสั่งต่อไปนี้ในโฟลเดอร์รูทของโปรเจ็กต์ของคุณ:

yarn run edgio:deploy

ตอนนี้เราเสร็จสิ้นการปรับใช้แล้ว! ใช่ นั่นคือทั้งหมด

บทสรุป

โดยสรุป โปรเจ็กต์นี้ได้มอบประสบการณ์อันมีค่าในการใช้งานการจำกัดอัตราแบบละเอียด การดำเนินการข้อมูล CRUD ในแบบไร้เซิร์ฟเวอร์ ใช้ปัญหา GitHub เป็น CMS และตัดสินใจได้ดีขึ้นในการจัดส่ง MVP โดยใช้บริการที่ปรับขนาดตามความต้องการของคุณ เช่น Upstash