UpstashRedisとNext.jsを使用して調査アプリを構築する
今日、RedisデータベースなしでITの世界をイメージすることは困難です。 2021年に公開されたStackoverflowの開発者調査では、インメモリデータベースは非常に人気があり、70000人を超える開発者から最も愛されているデータベースとして選ばれました。インメモリデータベースとして、Redisは強力なパフォーマンスを提供し、短い応答が必要なシナリオに最適です。時間と最小の遅延。ただし、Redisのユースケースは、キャッシングとメッセージブローカリングに限定されていると誤って理解されることがよくあります。今日は、これが間違っている理由を見て、プライマリデータベースの役割でRedisを使用します。
ユーザーがオンラインアンケートの形でフィードバックを残すことができる小さなアプリを作成したいと考えています。 この特定のケースでは、会社のフィードバックを収集したいとします。簡単にするために、次のようなアプリの機能に焦点を当てます。
- ユーザーは3つの質問に答えることができます。
- 当社の製品/サービスについてどう思いますか? 1-10ポイント
- 同僚に私たちをお勧めしますか? はい/いいえ(true / false)
- ご意見をお聞かせください...フリーテキスト
- ユーザーはフォームを送信できます。
- 個々の調査結果は、データベース(ハッシュ)に単一のレコードとして保存されます。
- ユーザーは調査結果を確認できます。
ここでデモアプリを確認できます。
私たちの小さな調査アプリは、サーバーレスアーキテクチャの可能性を最大限に活用するための完璧な例です。サーバーレスは、コストを最小限に抑えながら最大のスケーラビリティを保証し、次のテクノロジーで実現できます。
Next.js
Next.jsは、サーバー側レンダリング、静的ページ生成、そして最も重要なAPIルートなどの機能を備えた従来のReactWebアプリケーションを強化するオープンソース開発フレームワークです。 。 Next.jsを使用して、アプリのフロントエンドとAPIの両方を作成します。
Upstash Redis
Upstashは、完全なサーバーレスで永続的なRedisデータベースを提供します。これは、驚くほど使いやすく、リクエストごとの価格が非常に低くなっています。従来のRedisの上に構築されたUpstashは、Redisの比類のないパフォーマンスを採用し、ディスクストレージの耐久性と組み合わせることで、私たちのユースケースに最適です。
- Next.jsアプリを作成します:
npx create-next-app survey-app
。 - UpstashコンソールでUpstashRedisデータベースを作成し、UPSTASH_REDIS_REST_URLとUPSTASH_REDIS_REST_TOKENの両方をコピーします。
プロジェクトは、2つのAPIエンドポイントを持つシングルページアプリケーションになります:
-
pages/api/submit.js
調査エントリを保存します -
pages/api/results.js
すべての調査エントリを取得します
Upstashとより簡単に通信するために、@upstash/redis
をインストールしましょう。 npm install @upstash/redis
を介したnpmパッケージ 。
新しいファイルを作成する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;
ここでは3つのことを行います:
- リクエスト本文から調査データを取得し、Redis用に準備します
- 調査エントリをハッシュとしてRedisに挿入します
- 調査エントリのIDをセットに追加します
なぜ調査エントリのハッシュを作成し、さらにその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で入手できます。
この投稿では、フォームエントリを処理し、入力されたフォームをUpstashサーバーレスRedisに保存するNext.jsフルスタックWebアプリケーションを開発しました。 Redisをプライマリデータベースとして使用する方法と、他のデータベース(SQLなど)からRedisに切り替えるときに行う必要のある設計変更について説明しました。
セットアップが簡単なサーバーレスRedisデータベースUpstashにより、フォームデータをクラウドに非常に簡単に保存できました。
この投稿が、Redisを理解し、Upstash Redisの感触をつかみ、データを保存するための新しい可能性を備えたアプリケーションの構築を開始するのに役立つことを願っています。
-
Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート2
このチュートリアルシリーズのパート2へようこそ。最初のパートでは、Upstash、Serverless Framework、およびRedisを使用してRESTAPIを構築する方法を説明しました。 このパートでは、Flutterを使用してモバイルアプリケーションを構築し、RESTAPIエンドポイントを使用します。 始めましょう🙃 まず、フラッターをコンピューターにインストールして実行する必要があります フラッター IDEで新しいフラッタープロジェクトを作成し、任意の名前を付けます。 pubspec.yamlを開きます flutterプロジェクトのルートディレクトリにあるファイルを
-
Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1
この投稿では、データを保存するためのFlutter、Serverless Framework、Upstash、Redisを使用してサーバーレスモバイルアプリケーションを構築します。 Upstashとは? Upstashは、Redis用のサーバーレスデータベースです。 Upstashを使用すると、リクエストごとに支払います。これは、データベースが使用されていないときに課金されないことを意味します。 Upstashはデータベースを構成および管理します。これは、DynamoDBやFaunaなどの他のデータベースの強力な代替手段であり、などの利点があります。 低レイテンシ REDISAPIと同