Next.js에서Preisma ORM 활용
Next.js 프로젝트의 초기 형태 만들기
생성
$ mkdir hello-next-app && cd hello-next-app
$ npm init -y
$ npm install next react react-dom --save
$ npm install typescript @types/node @types/react --save-dev
$ code src/index.tsx
scr/index.tsx
export default function Index() {
return <div>index</div>;
}
nextbuild이면typescript의 형식 정의를 생성하여 한번 구축합니다.$ npx next build
구축 대상이 tsx가 있기 때문에next는tsconfig.json
에서 생성next-env.d.ts
.Preisma 설정
의존에 추가합니다.
$ npm install @prisma/client@2 --save
$ npm install @prisma/cli@2 --save-dev
prisma
디렉터리에 모드를 추가합니다.이번에는 sqlite3을 선택하십시오.prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
model Post {
authorId Int?
content String?
id Int @id @default(autoincrement())
published Boolean @default(false)
title String
author User? @relation(fields: [authorId], references: [id])
}
model User {
email String @unique
id Int @id @default(autoincrement())
name String?
posts Post[]
}
VS코드에서 문법을 돋보이게 하려면 Prisma - Visual Studio Marketplace를 넣는 것이 좋다.migration
$ npx prisma migrate dev --preview-feature --name init
$ npx prisma generate # @prisma/client の型の生成
(이 일대의 API는 빈번하게 변화하여 곧 바뀔 것이다)migration이 성공하면
prisma/dev.db
와prisma/migrations
를 생성해야 한다.$ tree prisma/
prisma/
├── dev.db
├── migrations
│ └── 20201222113842_init
│ └── migration.sql
└── schema.prisma
Next.js에서Preisma 활용
인스턴스prisma client안에 발매된query를 보고 싶어서 로그 옵션에 지정
lib/prisma.ts
합니다.import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient({
log: ["query", "error", "info", "warn"],
});
export default prisma;
export * from "@prisma/client";
준비됐습니다!query
pages/index.tsx
에서 프리스마를 두드려 보세요.import type { GetServerSideProps } from "next";
import prisma from "../lib/prisma";
type Props = {
count: number;
};
export const getServerSideProps: GetServerSideProps<Props> = async (ctx) => {
const count = await prisma.user.count();
return {
props: {
count,
},
};
};
export default function Index(props: Props) {
return <div>user count: {props.count}</div>;
}
getServerSideProps()
는 서버가 수행하기 때문에 Dead Code Elimination을 통해 클라이언트에 노출되지 않습니다.getServerSideProps
서버를 시작하고 로그를 보면서 엽니다npx next
.http://localhost:3000
로 나오나요?그때의 일지는 여기에 있다.prisma:query SELECT COUNT(*) FROM (SELECT `dev`.`User`.`id` FROM `dev`.`User` WHERE 1=1 LIMIT ? OFFSET ?) AS `sub`
포스트의 투고
validation에서zed를 사용하고Form 라이브러리로react-final-form을 사용합니다.
$ npm install zod final-form react-final-form --save
title 콘텐츠를 받아 prisma 레코드를 만드는 API Route를 만듭니다.user count: 0
import type { NextApiHandler } from "next";
import prisma from "../../lib/prisma";
import * as z from "zod";
const requestBodySchema = z.object({
title: z.string().min(1),
content: z.string(),
});
const handler: NextApiHandler = async (req, res) => {
try {
const result = requestBodySchema.parse(req.body);
await prisma.post.create({
data: {
title: result.title,
content: result.content,
published: true,
},
});
res.json({
ok: true,
});
return;
} catch (error) {
res.json({ ok: false, error });
}
};
export default handler;
react-final-form으로 이 API를 post하는 Form을 제작한다.pages/api/createPost.ts
import { useCallback } from "react";
import { Form, Field } from "react-final-form";
import { useRouter } from "next/router";
export function PostForm() {
const router = useRouter();
const onSubmit = useCallback(async (formData) => {
const res = await fetch("/api/createPost", {
method: "POST",
body: JSON.stringify(formData),
headers: {
"Content-Type": "application/json",
},
});
const json = await res.json();
if (json.ok) {
router.push("/");
} else {
alert(JSON.stringify(json));
}
}, []);
return (
<Form
onSubmit={onSubmit}
render={({ handleSubmit }) => {
return (
<form onSubmit={handleSubmit}>
<Field<HTMLInputElement>
name="title"
placeholder="title"
render={(props) => {
return (
<div>
<input
{...(props.input as any)}
style={{ width: "80vw" }}
/>
</div>
);
}}
/>
<Field<HTMLTextAreaElement>
name="content"
placeholder="content"
render={(props) => {
return (
<div>
<textarea
{...(props.input as any)}
style={{ width: "80vw", height: "300px" }}
/>
</div>
);
}}
/>
<button type="submit">Submit</button>
</form>
);
}}
/>
);
}
에 쓰여진 Form의 요점은submit이고 다음 API를 실행하는 것이다.const res = await fetch("/api/createPost", {
method: "POST",
body: JSON.stringify(formData),
headers: {
"Content-Type": "application/json",
},
});
조금 게으름을 피워서 실현하지 못하고 API로 실현하면 다시 얻는 것이 번거롭기 때문에 다시 자신의 페이지로 가서 다시 얻는다.이걸 열심히 하면 포스트 리스트가 API화되어react-query로 캐시됩니다.
tannerlinsley/react-query: ⚛️ Hooks for fetching, caching and updating asynchronous data in React
index 페이지에서 트위터처럼 현재 메일박스 일람표를 보여 보세요.
components/PostForm.tsx
import type { GetServerSideProps } from "next";
import React from "react";
import { PostForm } from "../components/PostForm";
import prisma, { Post } from "../lib/prisma";
type Props = {
posts: Pick<Post, "id", "title" | "content">[];
};
export const getServerSideProps: GetServerSideProps<Props> = async (ctx) => {
const posts = await prisma.post.findMany({
select: {
title: true,
content: true,
id: true,
},
});
return {
props: {
posts,
},
};
};
export default function Index(props: Props) {
return (
<>
<PostForm />
<div>post count: {props.posts.length}</div>
{props.posts.map((post) => {
return (
<div key={post.id}>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
);
})}
</>
);
}
서버를 시작하여 완성된 폼에서 투고해 보십시오.현재 내부에서 발행된 조회
prisma:query BEGIN
prisma:query INSERT INTO `dev`.`Post` (`content`, `published`, `title`) VALUES (?,?,?)
prisma:query SELECT `dev`.`Post`.`id`, `dev`.`Post`.`authorId`, `dev`.`Post`.`content`, `dev`.`Post`.`published`, `dev`.`Post`.`title` FROM `dev`.`Post` WHERE `dev`.`Post`.`id` = ? LIMIT ? OFFSET ?
prisma:query COMMIT
이상.이 범위 안에서 그렇게 어렵지 않다고 느낀다.너 이거 왜 썼어?
연말연시를 맞아 넥스트를 선택했다.나는 js에 관한 책을 쓰고 있다.유료 기사로 젠에서 판매할 예정입니다.이 기사를 유료책의 일부로 이 주제로 쓰면 어떨까?써 보았다.
그 장의 일부로서 전체적인 겹쳐진 틀의 장을 쓰려고 한다, 블리츠.js 및 Nextjs Flower를 확인 중입니다.
2021년은 풀스테이크 넥스트다.js 원년이라서 희망이 있어요.모든 js계 프레임워크를 시도해 봤습니다.
해보니 현재 상황은 prisma 외에는 결정타라고 할 만한 것이 없다.
처음에는 블리츠에 초점을 맞추고 싶었지만 오늘 발표한 리액트 서버 컴포니트, 블리츠의 isomorphism 같은 것도 비교적 간단하게 실현할 수 있어 블리츠의 장점 중 하나를 넥스트에 두었다.나는 js 호스트가 쉽게 흡수된다고 생각한다.블리츠를 일부러 잠글 필요는 없다고 생각해요.
Introducing Zero-Bundle-Size React Server Components – React Blog
그렇긴 한데, 넥스트.js+Prism이 아직 보급되지 않았기 때문에 이 기사를 먼저 무료로 공개하는 것이 좋겠다고 생각해서 투고했습니다.
유료판에는 이 외에도 다음과 같은 요소를 해설할 예정이다.
Reference
이 문제에 관하여(Next.js에서Preisma ORM 활용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/mizchi/articles/1c35fdcc77065c02f631텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)