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

แอปสิ่งที่ต้องทำ Next.js ที่เรียบง่ายที่สุด

ในบทความนี้ เราจะสร้างแอปพลิเคชัน TODO แบบ Serverless Next.js เราจะพยายามทำให้ดีที่สุดเพื่อให้เป็นแบบมินิมอล มันจะไม่มีการเชื่อมต่อฐานข้อมูลใด ๆ มันจะไม่มีการพึ่งพาพิเศษอื่นใดนอกจาก Next.js มันจะไม่มีปุ่มใดๆ นอกจากนี้ minimalism เจ๋งและสะอาด ฉันชอบมันเพราะฉันเป็นนักพัฒนาที่ขี้เกียจ :)

เหตุใดเราจึงหลีกเลี่ยงการเชื่อมต่อฐานข้อมูล

Next.js เป็นเฟรมเวิร์กที่ทันสมัยซึ่งช่วยให้นักพัฒนาส่วนหน้าสามารถพัฒนาแอปพลิเคชันแบบสแต็กแบบเต็มได้ ฟังก์ชันแบบไร้เซิร์ฟเวอร์มีบทบาทสำคัญในการทำให้การพัฒนาแบ็กเอนด์สำหรับนักพัฒนา Next.js ง่ายขึ้น อย่างที่คุณคงทราบ ฟังก์ชันไร้เซิร์ฟเวอร์ไม่ชอบการเชื่อมต่อฐานข้อมูลเนื่องจากลักษณะไร้สัญชาติ ดูที่นี่และที่นี่เป็นตัวอย่างของปัญหาการเชื่อมต่อฐานข้อมูลภายในฟังก์ชันแบบไร้เซิร์ฟเวอร์

REST คือคำตอบ

REST อนุญาตให้ไคลเอ็นต์และเซิร์ฟเวอร์สื่อสารโดยไม่มีข้อมูลเซสชัน การไร้สัญชาติและลักษณะที่เรียบง่ายทำให้ REST เป็นโปรโตคอลการสื่อสารที่สมบูรณ์แบบสำหรับสภาพแวดล้อมแบบไร้เซิร์ฟเวอร์ เราจะเข้าถึง Upstash Redis ด้วย REST

กองโครงการ

  • ส่วนหน้า:Next.js
  • แบ็กเอนด์:ฟังก์ชัน Vercel
  • ฐานข้อมูล:เพิ่ม Redis ด้วย REST API

ดูการสาธิต:https://nextjs-todo-zeta.vercel.app/

ดูรหัส:https://github.com/upstash/examples/tree/master/nextjs-todo

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

สร้างแอป Next.js:npx create-next-app

สร้างฐานข้อมูล Upstash Redis ในภูมิภาค AWS-US-EAST-1 และคัดลอก REST URL และโทเค็น

โปรเจ็กต์จะเป็นแอปพลิเคชันหน้าเดียวที่มี 3 จุดปลาย API:

  • pages/api/list.js:แสดงรายการสิ่งที่ต้องทำ
  • pages/api/add.js:เพิ่มรายการสิ่งที่ต้องทำ
  • pages/api/remove.js:ลบรายการสิ่งที่ต้องทำ

เดอะโค้ด

เพิ่มเพจ/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);
    });
};

เพิ่มเพจ/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);
    });
};

อัปเดตเพจ/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 พื้นฐานที่ใช้ตะขอ เรามี 3 วิธีซึ่งโต้ตอบกับ API:addTodo, removeTodo และ loadTodos

และสุดท้ายให้อัปเดตไฟล์ styles/Home.module.css ดังที่นี่

เรียกใช้และปรับใช้

เรียกใช้โครงการของคุณในเครื่องด้วย npm run dev . หากทุกอย่างดูดี คุณสามารถทำให้โครงการใช้งานได้โดยเรียกใช้ vercel ในโฟลเดอร์โครงการ Vercel จะสร้างฟังก์ชันแบบไร้เซิร์ฟเวอร์สำหรับฟังก์ชัน API ของคุณ ขอบเขตเริ่มต้นสำหรับฟังก์ชัน Vercel คือ US-EAST-1 นั่นคือเหตุผลที่เราสร้างฐานข้อมูลของเราในภูมิภาคเดียวกัน

หมายเหตุ

  • การเก็บโทเค็นฐานข้อมูลไว้ในตัวแปรสภาพแวดล้อม Vercel จะปลอดภัยกว่า
  • เป็นการดีที่สุดสำหรับประสิทธิภาพที่จะรักษาฟังก์ชันแบบไร้เซิร์ฟเวอร์และฐานข้อมูล Redis ไว้ในภูมิภาคเดียวกัน
  • เราสามารถใช้ไคลเอนต์ Redis แทน REST API แต่อย่างที่ฉันได้กล่าวไว้ก่อนหน้านี้ การเชื่อมต่อฐานข้อมูลอาจทำให้เกิดปัญหาภายในฟังก์ชันแบบไร้เซิร์ฟเวอร์ นอกจากนี้ โปรดทราบว่าเราไม่เห็นความแตกต่างด้านประสิทธิภาพที่สำคัญระหว่าง Upstash REST API และ API ดั้งเดิม