이 게시물에서는 SvelteKitand Serverless Redis(Upstash)를 사용하여 간단한 TODO를 작성합니다.
<블록 인용>SvelteKit은 아름다운 개발 경험과 유연한 파일 시스템 기반 라우팅을 통해 모든 규모의 웹 애플리케이션을 구축하기 위한 프레임워크입니다.
프로젝트 생성
아래 명령을 실행하십시오:
npm init svelte@next todo-app-with-redis
프로젝트가 준비되었습니다. 이제 종속성을 설치하고 실행해 보겠습니다.
npm install
npm run dev
사용자 인터페이스
우리는 할 일 항목을 유지하기 위해 간단한 양식과 목록을 만듭니다. 지금은 비어 있고 나중에 데이터베이스에 바인딩합니다.
// src/routes/index.svelte
<script lang="ts">
import type {Todo} from "../lib/types";
import TodoItem from "../components/Todo.svelte";
export let todos: Todo[] = [
{
id: '1',
text: 'Create database',
status: true
},
{
id: '2',
text: 'Copy database url',
status: false
}
];
const uncheckedTodos = todos.filter((todo) => !todo.status);
const checkedTodos = todos.filter((todo) => todo.status);
</script>
<main class="container">
<form class="new" action="/" method="post">
<input
type="text"
name="text"
autofocus
aria-label="Add todo"
class="input"
placeholder="What needs to be done?"
/>
</form>
{#if uncheckedTodos.length}
<div class="todos">
{#each uncheckedTodos as todo (todo.id)}
<TodoItem {todo}/>
{/each}
</div>
{/if}
{#if checkedTodos.length}
<div class="todos todos-done">
{#each checkedTodos as todo (todo.id)}
<TodoItem {todo}/>
{/each}
</div>
{/if}
</main>
다음은 TODO 구성 요소입니다.
// src/components/Todo.svelte
<script lang="ts">
import type {Todo} from "../lib/types";
export let todo: Todo;
</script>
<div class="todo">
<form action="/?_method=PATCH" method="post">
<input type="hidden" name="todo" value={JSON.stringify(todo)}/>
<button
class="checkbox"
aria-label="Mark todo as {todo.status ? 'not done' : 'done'}"
>
{todo.status ? "✓" : ""}
</button>
</form>
<span class="text">{todo.text}</span>
<form action="/?_method=DELETE" method="post">
<input type="hidden" name="id" value={todo.id}/>
<button class="delete" aria-label="Delete todo">✕</button>
</form>
</div>
이제 다음이 표시됩니다.
데이터베이스 준비
Upstash Redis에 데이터를 보관할 것이므로 Upstash 데이터베이스를 생성합니다. Serverless 환경에 친숙한 HTTP 기반 Upstash 클라이언트를 사용합니다. 설치하자:
npm install @upstash/redis
이제 Upstash Console에서 Redis 데이터베이스를 생성해 보겠습니다. UPSTASH_REDIS_REST_URL
복사/붙여넣기 및 UPSTASH_REDIS_REST_TOKEN
.env 파일로 이동합니다.
UPSTASH_REDIS_REST_URL=https://global-renewing-gecko-31543.upstash.io
UPSTASH_REDIS_REST_TOKEN=AXs3ACsjfg684jJBFQgN34je7RFJ58wYjg4NjMt=
dotenv를 설치해야 합니다. 환경 변수를 사용합니다.
npm install dotenv
이제 lib/redis.ts
를 만듭니다. 아래와 같이 새 Redis 인스턴스를 생성합니다.
// src/lib/redis.ts
import "dotenv/config";
import { Redis } from "@upstash/redis";
export const databaseName =
process.env.NODE_ENV === "development"
? "redis-with-svelte-kit-dev"
: "redis-with-svelte-kit";
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN,
});
export default redis;
API 생성
폴더에서 js/ts
파일은 API 백엔드로 사용됩니다. 그래서 index.svelte
-> 프런트엔드, index.ts
-> 백엔드.
index.ts
를 만들어 봅시다. 필요한 API 메서드를 추가합니다.
// src/routes/index.ts
import redis, { databaseName } from "../lib/redis";
import type { RequestHandler } from "@sveltejs/kit";
const redirect = {
status: 303,
headers: {
location: "/",
},
};
export const get: RequestHandler = async () => {
// runs every time the page is loaded
return { body: { todos: [] } };
};
export const post: RequestHandler = async ({ request }) => {
// form: create todo
return redirect;
};
export const patch: RequestHandler = async ({ request }) => {
// form: update todo
return redirect;
};
export const del: RequestHandler = async ({ request }) => {
// form: delete todo
return redirect;
};
POST
할 일 만들기
TODO 아이템 생성을 구현해보자:
// src/routes/index.ts
export const post: RequestHandler = async ({ request }) => {
const form = await request.formData();
const text = form.get("text");
const id = Date.now().toString();
const todo = JSON.stringify({ text, status: false });
await redis.hset(databaseName, id, todo);
return redirect;
};
GET
할 일 로드
이제 TODO 항목을 나열해 보겠습니다.
// src/routes/index.ts
export const get: RequestHandler = async () => {
let todos = [];
const data = await redis.hgetall(databaseName);
if (!data) return { body: { todos } };
// normalize data
todos = Object.keys(data)
.map((key) => ({
id: key,
text: data[key]["text"],
status: data[key]["status"],
}))
// id = timestamp
.sort((a, b) => parseInt(b.id) - parseInt(a.id));
return { body: { todos } };
};
<블록 인용>
게시물을 간단하게 유지하기 위해 task deletion
를 추가하지 않았습니다. 및 taks completion
코드는 여기에 있지만 github 리포지토리에서 볼 수 있습니다.
이제 모든 것이 준비되었습니다!
소스 코드| 데모 앱
Next.js로 동일한 TODO 애플리케이션을 구현할 계획입니다. 그런 다음 이 프레임워크에서 제 경험을 비교하겠습니다.
Twitter 및 Discord에서 계속 지켜봐 주시고 팔로우하세요.