最もミニマリストのNext.jsTODOアプリ
この記事では、サーバーレスNext.jsベースのTODOアプリケーションを構築します。ミニマリストにするために最善を尽くします。データベース接続はありません。 Next.js以外の追加の依存関係はありません。ボタンはありません。その上、minimalism
クールでクリーンです。怠惰な開発者なので大好きです:)
データベース接続を回避する理由
Next.jsは、フロントエンド開発者がフルスタックアプリケーションを開発できるようにする最新のフレームワークです。サーバーレス機能は、Next.js開発者のバックエンド開発を簡素化する上で重要な役割を果たします。ご存知かもしれませんが、サーバーレス関数はステートレスな性質があるため、データベース接続を好みません。サーバーレス機能内のデータベース接続の問題の例として、こことここを参照してください。
RESTを使用すると、クライアントとサーバーはセッション情報なしで通信できます。このステートレス性とその単純な性質により、RESTはサーバーレス環境に最適な通信プロトコルになります。 RESTを使用してUpstashRedisにアクセスします。
- フロントエンド:Next.js
- バックエンド:Vercel関数
- データベース:RESTAPIを使用したRedisのアップスタッシュ
デモをご覧ください:https://nextjs-todo-zeta.vercel.app/
コードを参照してください:https://github.com/upstash/examples/tree/master/nextjs-todo
Next.jsアプリを作成します:npx create-next-app
AWS-US-EAST-1リージョンにUpstashRedisデータベースを作成し、RESTURLとトークンをコピーします。
プロジェクトは、3つのAPIエンドポイントを持つシングルページアプリケーションになります:
- pages / api / list.js:TODOアイテムを一覧表示します。
- pages / api / add.js:TODOアイテムを追加します。
- pages / api / remove.js:TODOアイテムを削除します。
以下のようにpages/api / list.jsを追加します:
export default async (req, res) => {
const token = "REPLACE_YOUR_TOKEN";
const url = "https://REPLACE_YOUR_ENDPOINT/lrange/todo/0/100?_token=" + token;
return fetch(url)
.then((r) => r.json())
.then((data) => {
let result = JSON.stringify(data.result);
return res.status(200).json(result);
});
};
以下のようにpages/api / add.jsを追加します:
export default async (req, res) => {
if (!req.query.todo) {
return res.status(400).send("todo parameter required.");
}
let todo = encodeURI(req.query.todo);
const token = "REPLACE_YOUR_TOKEN";
const url =
"https://REPLACE_YOUR_ENDPOINT/lpush/todo/" + todo + "?_token=" + token;
return fetch(url)
.then((r) => r.json())
.then((data) => {
let result = JSON.stringify(data.result);
return res.status(200).json(result);
});
};
以下のようにpages/api / remove.jsを追加します:
export default async (req, res) => {
if (!req.query.todo) {
return res.status(400).send("todo parameter required.");
}
let todo = encodeURI(req.query.todo);
const token = "REPLACE_YOUR_TOKEN";
const url =
"https://REPLACE_YOUR_ENDPOINT/lrem/todo/1/" + todo + "?_token=" + token;
return fetch(url)
.then((r) => r.json())
.then((data) => {
let result = JSON.stringify(data.result);
return res.status(200).json(result);
});
};
次のようにpages/index.jsを更新します:
import Head from "next/head";
import Image from "next/image";
import styles from "../styles/Home.module.css";
import { useEffect, useState } from "react";
export default function Home() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [todo, setTodo] = useState("");
let changeHandler = (event) => {
setTodo(event.target.value);
};
let addTodo = (event) => {
setLoading(true);
event.preventDefault();
fetch("/api/add?todo=" + todo)
.then((res) => res.json())
.then((data) => {
loadTodos();
});
};
let removeTodo = (rtodo) => {
setLoading(true);
fetch("/api/remove?todo=" + rtodo)
.then((res) => res.json())
.then((data) => {
loadTodos();
});
};
let loadTodos = () => {
console.log("load todos");
fetch("/api/list")
.then((res) => res.json())
.then((data) => {
setData(data);
setLoading(false);
});
};
useEffect(() => {
setLoading(true);
loadTodos();
}, []);
if (!data) return "Loading...";
return (
<div className={styles.container}>
<Head>
<title>Next.js TODO APP</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<div className={styles.grid}>
<h1 className={styles.title}>
TODO App with{" "}
<a href="https://blog.upstash.com/nextjs-todo">Next.js!</a>
<br />
<br />
</h1>
{loading ? (
<a href="#" className={styles.card}>
<img src="/loader.gif" />
</a>
) : (
<form className={styles.cardForm} onSubmit={addTodo}>
<input
className={styles.cardInput}
type="text"
name="todo"
onChange={changeHandler}
placeholder="Enter your exciting TODO item!"
/>
</form>
)}
{data.map((item) => (
<a
href="#"
onClick={() => removeTodo(item)}
className={styles.card}
>
<p>{item}</p>
</a>
))}
</div>
</main>
<footer className={styles.footer}>
<a
href="https://blog.upstash.com/nextjs-todo"
target="_blank"
rel="noopener noreferrer"
>
Powered by{" "}
<span className={styles.logo}>
<Image src="/logo.png" alt="Upstash Logo" width={87} height={25} />
</span>
</a>
</footer>
</div>
);
}
ご覧のとおり、これはフックを使用する基本的なReactアプリケーションです。 APIとやり取りするメソッドは、addTodo、removeTodo、loadTodosの3つです。
そして最後に、styles/Home.module.cssファイルをここのように更新します。
npm run dev
を使用してプロジェクトをローカルで実行します 。すべてが良好に見える場合は、vercel
を実行してプロジェクトをデプロイできます プロジェクトフォルダにあります。 Vercelは、API関数用のサーバーレス関数を作成します。 Vercel関数のデフォルトのリージョンはUS-EAST-1です。そのため、同じリージョンにデータベースを作成しました。
- データベーストークンをVercel環境変数に保持する方が安全です。
- サーバーレス機能とRedisデータベースを同じリージョンに維持することがパフォーマンスに最適です。
- RESTAPIの代わりにRedisクライアントを使用できます。ただし、前述したように、データベース接続はサーバーレス機能内で問題を引き起こす可能性があります。また、UpstashRESTAPIとネイティブAPIの間に大きなパフォーマンスの違いは見られなかったことにも注意してください。
-
Google ニュース アプリを最大限に活用するための 5 つのヒントとコツ
最近、Google は I/O カンファレンスで専用のニュース アプリをリリースしました。この驚くべきアプリは、Google ニュース &天気アプリとニューススタンドをほぼ置き換え、これらのアプリ機能を 1 つのフードの下に革新的に組み合わせました。最高のニュース体験を提供するために、私たちの興味や好みに基づいて世界中からニュースを取得します。 Google ニュース アプリが提供するすべての素晴らしい機能を簡単に紹介します。しかし、待ってください。それだけではありません。 Google ニュース アプリには、まだまだ探求すべきことがたくさんあります。 Google ニュースの便利なヒン
-
YouTube Music の 5 つの機能を最大限に活用しよう!
オンライン ストリーミングは、今日の世代のものになりました。お気に入りの映画や番組をテレビでストリーミングする場合でも、電話で音楽をストリーミングする場合でも、オンライン ストリーミングはスマート ガジェットで行うのに最適な方法の 1 つです。オンライン ストリーミングには独自の利点があり、最大の利点の 1 つは、ストレージ容量を心配する必要がないことです。デバイスにダウンロードすることを心配することなく、できるだけ多くのコンテンツを探索し、手間をかけずにいつでもアクセスできます。 オンライン音楽ストリーミングに関して言えば、Spotify はそもそも私たちの頭をよぎる主要なサービスの 1