Next.js 및 tRPC를 사용한 전체 스택 유형 안전 애플리케이션 개발
목차
소개
When working with a modern UI library, we often need to fetch data from an external source, a REST or GraphQL API. Synchronizing the client with a server state comes with some challenges, including type definitions and safety. All the external data sources define schemas, but they are not immediately consumable from our UI without redefining them, leveraging types generations libraries, or importing monorepo packages. The lack of immediately available types and the introduction of more dedicated tools create friction and slow developers’ productivity and velocity. Suppose your organization is also split into a front-end and back-end team. The communication overhead adds a layer of potential conflicts because the two parts must agree on the schema before starting the development of features.
tRPC provides all the tools to create full-stack end-to-end type-safe applications. It is a library that combines the power of TypeScript and react-query to register all the server endpoints and make them instantly available with types to the client. It increases team productivity because backend endpoints are just functions, and the developers can effectively work on the entire stack. Any team can significantly benefit from this tool because code generation, types package, and communication overhead are phased out.
tRPC also has some downsides. A single developer maintains it. Files cannot be uploaded without any 3rd parties services like Amazon S3. WebSockets have limited support, and data is limited to JSON.
Pros
- Full-stack end-to-end type-safe application development.
- Better team productivity and velocity.
- Minimal communication overhead.
- If you trust the type system and there is no complex business logic, unit tests may not be required.
Cons
- Solo maintainer.
- TypeScript could slow down your IDE.
- Data is limited to JSON.
- Limited support for WebSocket.
tRPC 튜토리얼
tRPC 전제 조건
The tutorial assumes you are familiar with the following libraries:
- React,
- Next.js,
- Prisma or other ORMs,
- react-query.
tRPC 프로젝트 부트스트랩
Let’s initialize a new tRPC project with the create-t3-app
CLI:
npx create-t3-app@latest
You will be prompted to answer some questions:
- Name your application.
- Select TypeScript.
- Select Prisma and tRPC.
- Initialize a git repository.
- Run
npm install
.
프로젝트가 부트스트랩되면
prisma/schema.prisma
로 이동하여 새Blog
모델로 업데이트합니다.model Blog {
id String @id @default(cuid())
title String
content String
createdAt DateTime @default(now())
}
터미널에서
npx prisma db push
를 실행하여 로컬 SQLite 데이터베이스에 모델을 적용합니다.tRPC 백엔드 개발
We are ready to work on the backend of our application. Navigate to src/server/router
and create a new file named blog.ts.
Please copy the following code to create two endpoints. One handles the creation of a blog post, and the other lists the inserted articles.
import { createRouter } from "./context";
// `zod` is a schema declaration and validation library. We use it to define the shape of request arguments.
import { z } from "zod";
// `createRouter` exposes functions to create new API endpoints.
export const blogRouter = createRouter()
// A `mutation` defines an operation that modifies our data.
// It behaves like`POST`, `PUT`, `DELETE` operations.
// The input property accepts an optional `zod` schema to validate the request body.
.mutation("create", {
input: z.object({
title: z.string(),
content: z.string(),
}),
// The API handler is a simple `resolve` function that contains all the business logic to handle the request.
resolve({ input, ctx }) {
return ctx.prisma.blog.create({
data: {
title: input.title,
content: input.content,
},
});
},
})
// A `query` defines an operation that reads data from our backend.
// It behaves like a GET request.
.query("all", {
resolve({ ctx }) {
return ctx.prisma.blog.findMany();
},
});
Once we have defined the routes, we can register them in src/server/router/index.ts.
// src/server/router/index.ts
import { createRouter } from "./context";
import superjson from "superjson";
import { blogRouter } from "./blog";
export const appRouter = createRouter()
.transformer(superjson)
// Registering the blogRouter
.merge("blog.", blogRouter);
// export type definition of the API
export type AppRouter = typeof appRouter;
UI 개발
Navigate to src/pages/index.tsx
and paste the following code. The tRPC utilities that wrap react-query enable us to access the defined type-safe backend procedures.
import type { NextPage } from "next";
import { useState } from "react";
import BlogPost from "../components/BlogPost";
import Layout from "../components/Layout";
// import trpc utils that wrap react-query
import { trpc } from "../utils/trpc";
const Home: NextPage = () => {
// Hovering on data shows the types defined in our backend
const { isLoading, data } = trpc.useQuery(["blog.all"]);
return (
<Layout>
<h1>My personal blog</h1>
{isLoading ? (
<div>Loading posts</div>
) : (
data?.map((blog) => <BlogPost blog={blog} key={blog.id} />)
)}
<CreatePostSection />
</Layout>
);
};
export default Home;
const CreatePostSection = () => {
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
const ctx = trpc.useContext();
const createMutation = trpc.useMutation("blog.create");
return (
<div>
{createMutation.isLoading}
<h2>Create a new blog post</h2>
<div>
<input
name="title"
placeholder="Your title..."
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
</div>
<div>
<textarea
rows={10}
cols={50}
value={content}
placeholder="Start typing..."
onChange={(e) => setContent(e.target.value)}
/>
</div>
<div>
<button
onClick={() =>
// mutate exposes the types of arguments as defined in our router
createMutation.mutate(
{ title, content },
{
onSuccess() {
ctx.invalidateQueries("blog.all");
setContent("");
setTitle("");
},
}
)
}
disabled={createMutation.isLoading}
>
Create new post
</button>
</div>
</div>
);
};
npm run dev
to check the platform. You can further practice with tRPC by expanding the application with new features. Some examples are finding by id, deleting, or updating a single post. A complete solution can be found here https://github.com/andrew-hu368/t3-blog .
Reference
이 문제에 관하여(Next.js 및 tRPC를 사용한 전체 스택 유형 안전 애플리케이션 개발), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/andrewhu368/full-stack-type-safe-applications-development-with-nextjs-and-trpc-3ggj텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)