ทุกวันนี้ เป็นเรื่องยากที่จะสร้างภาพโลกไอทีที่ไม่มีฐานข้อมูล Redis ในแบบสำรวจสำหรับนักพัฒนาซอฟต์แวร์ของ Stackoverflow ที่เผยแพร่ในปี 2021 ฐานข้อมูลในหน่วยความจำได้รับความนิยมอย่างมากและได้รับเลือกให้เป็นฐานข้อมูลที่เป็นที่ชื่นชอบมากที่สุดโดยนักพัฒนากว่า 70000 ราย Redis เป็นฐานข้อมูลในหน่วยความจำที่มีประสิทธิภาพ ทำให้เหมาะอย่างยิ่งในสถานการณ์ที่ต้องการการตอบสนองสั้นๆ ครั้งและเวลาแฝงน้อยที่สุด อย่างไรก็ตาม กรณีการใช้งานของ Redis มักถูกเข้าใจผิดว่าจำกัดเฉพาะการแคชและนายหน้าข้อความ วันนี้เราจะมาดูว่าเหตุใดจึงไม่ถูกต้องและใช้ Redis ในบทบาทของฐานข้อมูลหลัก
ไอเดีย
เราต้องการสร้างแอปขนาดเล็กที่อนุญาตให้ผู้ใช้แสดงความคิดเห็นในรูปแบบของแบบสำรวจออนไลน์ได้ ในกรณีนี้ ลองจินตนาการว่าเราต้องการรวบรวมคำติชมสำหรับบริษัท เพื่อให้ง่าย เราจะเน้นที่ฟังก์ชันของแอปซึ่งควรเป็นดังต่อไปนี้:
- ผู้ใช้สามารถตอบคำถามได้สามข้อ
- คุณรู้สึกอย่างไรเกี่ยวกับผลิตภัณฑ์/บริการของเรา 1 - 10 คะแนน
- คุณจะแนะนำเราให้เพื่อนร่วมงานของคุณหรือไม่? ใช่/ไม่ใช่ (จริง/เท็จ)
- โปรดแบ่งปันความคิดของคุณ... ข้อความฟรี
- ผู้ใช้สามารถส่งแบบฟอร์มได้
- ผลการสำรวจแต่ละรายการจะถูกจัดเก็บเป็นระเบียนเดียวในฐานข้อมูล (แฮช)
- ผู้ใช้สามารถดูผลการสำรวจได้
คุณสามารถตรวจสอบแอปสาธิตได้ที่นี่
กลุ่มเทคโนโลยี
แอปสำรวจขนาดเล็กของเราเป็นตัวอย่างที่สมบูรณ์แบบในการใช้ประโยชน์จากสถาปัตยกรรมแบบไร้เซิร์ฟเวอร์ Serverless ช่วยให้มั่นใจได้ถึงความสามารถในการปรับขนาดสูงสุดในขณะที่รักษาต้นทุนให้ต่ำที่สุดและสามารถทำได้ด้วยเทคโนโลยีต่อไปนี้:
Next.js
Next.js เป็นเฟรมเวิร์กการพัฒนาโอเพ่นซอร์สที่ปรับปรุงเว็บแอปพลิเคชัน React แบบดั้งเดิมด้วยคุณสมบัติต่างๆ เช่น การแสดงผลฝั่งเซิร์ฟเวอร์ การสร้างเพจแบบสแตติก และที่สำคัญที่สุด เส้นทาง API . เรากำลังจะใช้ Next.js เพื่อสร้างทั้งส่วนหน้าและ API ของแอปของเรา
อัพสแตชเรดิส
Upstash นำเสนอฐานข้อมูล Redis แบบไร้เซิร์ฟเวอร์และต่อเนื่อง ซึ่งใช้งานง่ายอย่างน่าอัศจรรย์และเสนอราคาต่อคำขอที่ต่ำมาก Upstash สร้างขึ้นจาก Redis แบบดั้งเดิม โดยนำประสิทธิภาพที่เหนือชั้นของ Redis มารวมเข้ากับความทนทานของพื้นที่จัดเก็บดิสก์ซึ่งทำให้เหมาะอย่างยิ่งสำหรับกรณีการใช้งานของเรา
การตั้งค่าโครงการ
- สร้างแอป Next.js:
npx create-next-app survey-app
. - สร้างฐานข้อมูล Upstash Redis ในคอนโซล Upstash และคัดลอกทั้ง UPSTASH_REDIS_REST_URL และ UPSTASH_REDIS_REST_TOKEN
โปรเจ็กต์จะเป็นแอปพลิเคชันหน้าเดียวที่มีจุดปลาย API สองจุด:
pages/api/submit.js
เก็บรายการแบบสำรวจpages/api/results.js
เรียกค้นรายการสำรวจทั้งหมด
เพื่อให้สื่อสารกับ Upstash ได้ง่ายขึ้น ให้ติดตั้ง @upstash/redis
แพ็คเกจ npm ผ่าน npm install @upstash/redis
.
รหัส
สร้างไฟล์ใหม่ pages/api/submit.js
ดังต่อไปนี้:
// pages/api/submit.js
import { Redis } from "@upstash/redis";
const redis = new Redis({
url: "INSERT_YOUR_URL_HERE",
token: "INSERT_YOUR_TOKEN_HERE",
});
const submitHandler = async (req, res) => {
const body = req.body;
// Prepare data to be inserted into the DB
const data = {
rating: String(body.rating) || "0",
recommendation: String(body.recommendation) || "false",
comment: String(body.comment) || "",
};
// Generate a random id to store the survey entry under
const id =
Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15);
// Insert data into Upstash redis
try {
//Store the survey data
await redis.hset(`entries:${id}`, data);
//Store the id of the survey to retrieve it later
await redis.sadd("entries", `entries:${id}`);
} catch (error) {
console.error("Failed to insert data into redis", error);
return res.status(500).json({
success: false,
message: "Failed to insert data into redis",
});
}
return res.status(200).json({
success: true,
message: "Data inserted successfully",
});
};
export default submitHandler;
เราทำสามสิ่งที่นี่:
- นำข้อมูลการสำรวจจากหน่วยคำขอและเตรียมข้อมูลสำหรับ Redis
- แทรกรายการสำรวจลงใน Redis เป็นแฮช
- ผนวก id ของรายการแบบสำรวจเข้ากับชุด
คุณอาจสงสัยว่าเหตุใดเราจึงสร้างแฮชสำหรับรายการแบบสำรวจ แล้วจึงใส่รหัสลงในชุดเพิ่มเติม ขั้นตอนนี้จะมีความสำคัญทันทีที่เราต้องการเรียกข้อมูลกิจกรรมจาก Redis อีกครั้ง Redis ทำงานเป็นที่เก็บคีย์-ค่า ซึ่งหมายความว่าไม่เหมือนกับที่เราคุ้นเคยกับฐานข้อมูล SQL Redis ไม่ได้สร้างขึ้นเพื่อค้นหาข้อมูล เว้นแต่เราจะระบุคีย์ที่แน่นอนซึ่งมันถูกเก็บไว้ แบบสอบถามเช่น SELECT * FROM SurveyResults;
จะได้รับการสนับสนุนใน SQL แต่ด้วย Redis เราจะต้องใช้เคล็ดลับอื่น สำหรับสิ่งนี้ เราสร้างชุดและเพิ่มคีย์ Redis ทั้งหมดของรายการผลการสำรวจลงไป เมื่อเราต้องการดึงข้อมูลรายการสำรวจทั้งหมด เราก็สามารถค้นหาคีย์ของพวกมันในชุดได้ แต่กลับมาที่การเขียนโค้ดตอนนี้และดูว่าสิ่งนี้มีลักษณะอย่างไรในทางปฏิบัติ
สร้างไฟล์ใหม่ pages/api/results.js
ดังต่อไปนี้:
// pages/api/results.js
import { Redis } from "@upstash/redis";
const resultsHandler = async (req, res) => {
// Retrieve data from redis
const redis = new Redis({
url: "INSERT_YOUR_URL_HERE",
token: "INSERT_YOUR_TOKEN_HERE",
});
try {
//Find all the entries in the set
const entries = await redis.smembers("entries");
//Get all survey entries by id/key
//To run multiple queries at once, Upstash supports the use of the pipeline command. This way we can run multiple queries at once and get the results in a single call.
const p = redis.pipeline();
entries.forEach((id) => {
p.hgetall(id);
});
const results = await p.exec();
return res.status(200).json({
success: true,
message: "Data retrieved successfully",
data: results,
});
} catch (error) {
console.error("Failed to retrieve data from redis", error);
return res.status(500).json({
success: false,
message: "Failed to retrieve data from redis",
});
}
};
export default resultsHandler;
แบ็กเอนด์ของเราทำงานอยู่ในขณะนี้ และเราสามารถทำให้แอปของเราเสร็จด้วยฟรอนต์เอนด์
สร้างไฟล์ใหม่ pages/index.js
ดังต่อไปนี้:
// pages/index.js
import Head from "next/head";
import Image from "next/image";
import styles from "../styles/Home.module.css";
export default function Home() {
const handleSubmit = async (e) => {
e.preventDefault();
const form = e.target;
const data = {
rating: form.rating.value,
recommendation: form.recommendation.value,
comment: form.comment.value,
};
// send data to backend
await fetch("/api/submit", {
body: JSON.stringify(data),
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
method: "POST",
});
alert("Thank you for your feedback!");
};
const RatingOption = ({ value }) => (
<div>
<input type="radio" name="rating" value={value} required />{" "}
<label>{value}</label>
</div>
);
return (
<div className={styles.container} onSubmit={handleSubmit}>
<form>
<div>
<label>How do you feel about our products/services?</label>
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((value) => (
<RatingOption key={value} value={value} />
))}
</div>
<div>
<label>Would you recommend us to your colleagues?</label>
<div>
<input type="radio" name="recommendation" value="true" required />{" "}
<label>Yes</label>
</div>
<div>
<input type="radio" name="recommendation" value="false" required />{" "}
<label>No</label>
</div>
</div>
<div>
<label>Please share your thoughts... (Optional)</label>
<textarea
name="comment"
placeholder="This is what I liked most/this is what you can improve..."
></textarea>
</div>
<input type="submit" />
</form>
</div>
);
}
ตอนนี้เพื่อให้สไตล์ใช้งานได้ ให้แทนที่เนื้อหาของ styles/Home.styles.css
ดังต่อไปนี้:
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.container form > div {
padding: 20px;
display: flex;
flex-direction: column;
align-items: stretch;
}
.container form > div > label {
margin-bottom: 10px;
}
ตอนนี้เราพร้อมที่จะรับรายการสำรวจแล้ว! แต่เดี๋ยวก่อน ยังมีอีก เรายังคงต้องใช้ผลการสำรวจในส่วนหน้า
สร้างไฟล์ใหม่ pages/results.js
ดังต่อไปนี้:
import { useEffect, useState } from "react";
import styles from "../styles/Results.module.css";
export default function Results() {
const [surveyData, setSurveyData] = useState([]);
useEffect(() => {
fetch("/api/results")
.then((res) => res.json())
.then((response) => setSurveyData(response.data));
}, []);
return (
<div className={styles.container}>
{" "}
{surveyData.map((data) => (
<div key={data.id}>
<p>
<strong> Rating: </strong> {data.rating}{" "}
</p>{" "}
<p>
<strong> Recommendation: </strong> {data.recommendation}{" "}
</p>{" "}
<p>
<strong> Comment: </strong> {data.comment}{" "}
</p>{" "}
</div>
))}{" "}
</div>
);
}
และสุดท้ายสร้างไฟล์ styles/Results.module.css
โดยมีเนื้อหาดังต่อไปนี้:
.container {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
min-height: 100vh;
margin: 50px 0;
}
.container > div {
background: rgba(0, 0, 0, 0.05);
border-radius: 10px;
padding: 15px;
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
}
.container p {
margin: 0;
}
คุณสามารถดูภาพรวมของรายการสำรวจทั้งหมดได้ที่ localhost:3000/results
.
ซอร์สโค้ดที่สมบูรณ์ของแอปพลิเคชันมีอยู่ในที่เก็บ GitHub upstash-survey-app
บทสรุป
ในโพสต์นี้ เราได้พัฒนาเว็บแอปพลิเคชัน Next.js fullstack ที่จัดการรายการแบบฟอร์มและจัดเก็บแบบฟอร์มใน Upstash Serverless Redis เราเห็นว่า Redis สามารถใช้เป็นฐานข้อมูลหลักได้อย่างไร และคุณต้องเปลี่ยนการออกแบบอย่างไรเมื่อเปลี่ยนจากฐานข้อมูลอื่น (เช่น SQL) เป็น Redis
ด้วยฐานข้อมูล Redis แบบไร้เซิร์ฟเวอร์ที่ตั้งค่าได้ง่าย Upstash ทำให้ง่ายต่อการจัดเก็บข้อมูลแบบฟอร์มในระบบคลาวด์
ฉันหวังว่าโพสต์นี้จะช่วยให้คุณเข้าใจ Redis เข้าใจ Upstash Redis และเริ่มสร้างแอปพลิเคชันของคุณด้วยความเป็นไปได้ใหม่ๆ ในการจัดเก็บข้อมูล