Computer >> 컴퓨터 >  >> 프로그램 작성 >> Redis

Upstash Redis 및 Next.js로 설문조사 앱 구축

요즘은 Redis 데이터베이스가 없는 IT 세계를 상상하기 어렵습니다. 2021년에 발표된 Stackoverflow의 개발자 설문조사에서 인메모리 데이터베이스는 큰 인기를 얻었으며 70000명 이상의 개발자가 가장 사랑하는 데이터베이스로 선택되었습니다. 인메모리 데이터베이스로서 Redis는 강력한 성능을 제공하여 짧은 응답이 필요한 시나리오에 이상적입니다. 시간 및 최소 대기 시간. 그러나 Redis의 사용 사례는 종종 캐싱 및 메시지 중개에 국한되는 것으로 잘못 이해됩니다. 오늘은 이것이 잘못된 이유를 살펴보고 기본 데이터베이스의 역할로 Redis를 사용합니다.

아이디어

우리는 사용자가 온라인 설문조사 형식으로 피드백을 남길 수 있는 작은 앱을 만들고 싶습니다. 이 특정한 경우에 회사에 대한 피드백을 수집하고 싶다고 가정해 보겠습니다. 간단하게 하기 위해 다음과 같은 앱 기능에 중점을 둘 것입니다.

  1. 사용자는 세 가지 질문에 답할 수 있습니다.
    • 저희 제품/서비스에 대해 어떻게 생각하십니까? 1 - 10점
    • 동료들에게 우리를 추천하시겠습니까? 예/아니요(참/거짓)
    • 당신의 생각을 공유해주세요... 자유로운 텍스트
  2. 사용자가 양식을 제출할 수 있습니다.
  3. 각 개별 설문조사 결과는 데이터베이스(해시)에 단일 레코드로 저장됩니다.
  4. 사용자가 설문조사 결과를 볼 수 있습니다.

여기에서 데모 앱을 확인할 수 있습니다.

기술 스택

우리의 소규모 설문조사 앱은 서버리스 아키텍처의 잠재력을 최대한 활용하는 완벽한 예입니다. 서버리스는 비용을 최소화하면서 최대 확장성을 보장하며 다음 기술을 통해 달성할 수 있습니다.

Next.js

Next.js는 서버 측 렌더링, 정적 페이지 생성 및 가장 중요한 API 경로와 같은 기능으로 기존 React 웹 애플리케이션을 향상시키는 오픈 소스 개발 프레임워크입니다. . 우리는 Next.js를 사용하여 앱의 프론트엔드와 API를 모두 만들 것입니다.

업스태시 Redis

Upstash는 놀랍도록 사용하기 쉽고 요청당 매우 저렴한 가격을 제공하는 완전한 서버리스 영구 Redis 데이터베이스를 제공합니다. 기존 Redis를 기반으로 구축된 Upstash는 Redis의 타의 추종을 불허하는 성능과 디스크 스토리지의 내구성을 결합하여 사용 사례에 완벽하게 맞습니다.

프로젝트 설정

  1. Next.js 앱 만들기:npx create-next-app survey-app .
  2. Upstash 콘솔에서 Upstash Redis 데이터베이스를 만들고 UPSTASH_REDIS_REST_URL과 UPSTASH_REDIS_REST_TOKEN을 모두 복사합니다.

프로젝트는 두 개의 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가지 작업을 수행합니다.

  1. 요청 본문에서 설문조사 데이터를 가져와 Redis용으로 준비합니다.
  2. 설문조사 항목을 Redis에 해시로 삽입
  3. 조사 항목의 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 풀스택 웹 애플리케이션을 개발했습니다. Redis를 기본 데이터베이스로 사용하는 방법과 다른 데이터베이스(예:SQL)에서 Redis로 전환할 때 수행해야 하는 설계 변경 사항을 살펴보았습니다.

설정이 간편한 서버리스 Redis 데이터베이스 Upstash를 사용하면 클라우드에 양식 데이터를 매우 쉽게 저장할 수 있습니다.

이 게시물이 Redis를 이해하고 Upstash Redis에 대한 느낌을 얻고 데이터를 저장할 수 있는 새로운 가능성으로 애플리케이션 구축을 시작하는 데 도움이 되기를 바랍니다.