Computer >> Máy Tính >  >> Lập trình >> Redis

Ứng dụng CẦN LÀM Next.js tối giản nhất

Trong bài viết này, chúng tôi sẽ xây dựng một ứng dụng TODO dựa trên Serverless Next.js. Chúng tôi sẽ cố gắng hết sức để làm cho nó tối giản. Nó sẽ không có bất kỳ kết nối cơ sở dữ liệu nào. Nó sẽ không có thêm bất kỳ phụ thuộc nào ngoài Next.js. Nó sẽ không có bất kỳ nút nào. Bên cạnh đó, minimalism mát mẻ và sạch sẽ, tôi thích nó vì tôi là một nhà phát triển lười biếng :)

Tại sao chúng tôi tránh kết nối cơ sở dữ liệu?

Next.js là một khung công tác hiện đại cho phép các nhà phát triển front-end phát triển các ứng dụng ngăn xếp đầy đủ. Các chức năng serverless có một vai trò quan trọng trong việc đơn giản hóa việc phát triển phần phụ trợ cho các nhà phát triển Next.js. Như bạn có thể biết, các hàm không máy chủ không thích các kết nối cơ sở dữ liệu do bản chất không trạng thái của chúng. Xem đây và đây là ví dụ về các sự cố kết nối cơ sở dữ liệu bên trong các chức năng không máy chủ.

REST là một câu trả lời

REST cho phép máy khách và máy chủ giao tiếp mà không có thông tin phiên. Tính không trạng thái và bản chất đơn giản của nó làm cho REST trở thành một giao thức truyền thông hoàn hảo cho môi trường không máy chủ. Chúng tôi sẽ truy cập Upstash Redis bằng REST.

Ngăn xếp Dự án

  • Giao diện người dùng:Next.js
  • Backend:Các hàm Vercel
  • Cơ sở dữ liệu:Upstash Redis với REST API

Xem bản demo:https://nextjs-todo-zeta.vercel.app/

Xem mã:https://github.com/upstash/examples/tree/master/nextjs-todo

Thiết lập dự án

Tạo ứng dụng Next.js:npx create-next-app

Tạo cơ sở dữ liệu Upstash Redis trong khu vực AWS-US-EAST-1 và sao chép URL và mã thông báo REST.

Dự án sẽ là một ứng dụng trang đơn với 3 điểm cuối API:

  • pages / api / list.js:Liệt kê các mục CẦN LÀM.
  • pages / api / add.js:Thêm một mục CẦN LÀM.
  • pages / api / remove.js:Xóa một mục CẦN LÀM.

Thêm trang / api / list.js như sau:

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);
    });
};

Thêm trang / api / add.js như sau:

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);
    });
};

Thêm các trang / api / remove.js như sau:

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);
    });
};

Cập nhật các trang / index.js như bên dưới:

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>
  );
}

Như bạn thấy, nó là một ứng dụng React cơ bản sử dụng hook. Chúng tôi có 3 phương thức tương tác với API:addTodo, removeTodo và loadTodos.

Và cuối cùng là cập nhật tệp styles / Home.module.css như tại đây.

Chạy và Triển khai

Chạy dự án của bạn cục bộ với npm run dev . Nếu mọi thứ đều ổn, bạn có thể triển khai dự án của mình bằng cách chạy vercel trong thư mục dự án. Vercel sẽ tạo các hàm không máy chủ cho các hàm API của bạn. Vùng mặc định cho các hàm Vercel là US-EAST-1, đó là lý do tại sao chúng tôi tạo cơ sở dữ liệu của mình trong cùng một vùng.

LƯU Ý

  • Giữ mã thông báo cơ sở dữ liệu trong biến môi trường Vercel sẽ an toàn hơn.
  • Tốt nhất là giữ chức năng không máy chủ và cơ sở dữ liệu Redis ở cùng một khu vực.
  • Chúng tôi có thể sử dụng ứng dụng khách Redis thay vì API REST. Nhưng như tôi đã đề cập trước đây, các kết nối cơ sở dữ liệu có thể gây ra sự cố bên trong các chức năng không có máy chủ. Cũng xin lưu ý rằng chúng tôi không nhận thấy sự khác biệt lớn về hiệu suất giữa API Upstash REST và API gốc.