Aparte na opisie z How to Build a Fullstack App with Next.js, Prisma, and Vercel Postgres
Tworzę aplikację Next.js o nazwie
next-test
npx create-next-app@latest next-test
Zatwierdzam wszystkie parametry domyślne
Uzupełnić
.gitignore
i można sobie uruchomić aplikację, aby sprawdzić czy wszystko działa
npm run dev
Teraz należy przesłać repozytorium do Github
git push origin main
Utworzyć aplikację na Vercel o nnazwie, najlepiej takiej jak utworzona, czyli w naszym przypadku next-test
.
Utworzenie aplikacji na Vercel sprowadza się do nadania jej w Github uprawnienia dla portalu Vercel.
W projekcie Vercel kliknąć zakładkę Storage i utworzyć bazę danych Postgres. Utworzoną bazę przypisać do projektu.
Podczas tego procesu powstanie szereg zmiennych środowiskowych opisujących bazę Postgres
Teraz czas na instalację
CLI
Vercel:
npm i -g vercel@latest
Gdy się wszystko zainstaluje ściągamy utworzone wcześniej zmienne środowiskowe do lokalnego pliku .env
,
ale przedtem linkujemy się do projektu
Czyli linkowanie:
vercel link
A potem ściągnięcie zmiennych środowiskowych
vercel env pull .env
Warto umieścić zapis
.env*
w pliku
.gitignore
Instalujemy pakiet Prisma:
npm install prisma --save-dev
Tworzymy folder
prisma
, a w nim plik
schema.prisma
mkdir prisma && touch prisma/schema.prisma
W pliku
schema.prisma
umieszczamy przykładowy kod
// schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("POSTGRES_PRISMA_URL") // uses connection pooling
directUrl = env("POSTGRES_URL_NON_POOLING") // uses a direct connection
}
model Post {
id String @default(cuid()) @id
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId String?
}
model User {
id String @default(cuid()) @id
name String?
email String? @unique
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @updatedAt @map(name: "updated_at")
posts Post[]
@@map(name: "users")
}
Zmienne POSTGRES_PRISMA_URL
i POSTGRES_URL_NON_POOLING
są nazwami wziętymi z pliku .env
ściągniętego z Vercel.
Tworzymy tabele w bazie danych, a właściwie wypychamy schemę do bazy danych:
npx prisma db push
Można sobie sprawdzić w panelu bazy danych na Vercel, czy obie tabele zostały poprawnie utworzone.
Teraz można uruchomić Prisma Studio:
npx prisma studio
Podczas uruchomiania Prisma Studio linia komend wskaże linka z portem, z którego można uruchomić Studio w przeglądarce.
Tworzymy rekordy dla User i Post w Prisma Stidio
Instalujemy Prisma CLient:
npm install @prisma/client
Za każdym razem, gdy plik
schema.prisma
zostaje zmieniony należy wykonać generowanie:
npx prisma generate
Teraz tworzymy folder
lib
, a w nim plik
prisma.ts
mkdir lib && touch lib/prisma.ts
Wypełniamy plik
prisma.ts
// lib/prisma.ts
import { PrismaClient } from '@prisma/client';
let prisma: PrismaClient;
if (process.env.NODE_ENV === 'production') {
prisma = new PrismaClient();
} else {
if (!global.prisma) {
global.prisma = new PrismaClient();
}
prisma = global.prisma;
}
export default prisma;
Może być problem z typem dla zmiennej
prisma
. Wtedy w katalogu głównym projektu utówrz plik
global.d.ts
touch global.d.ts
a w nim ten kod:
// /global.d.ts
import { PrismaClient } from '@prisma/client';
declare global {
// eslint-disable-next-line no-var
var prisma: PrismaClient;
}
Teraz w każdym miejscu, gdy potrzebujemy dostępu do bazy danych możemy wykorzystać zmienną
prisma
importując ją tak:
import prisma from '../lib/prisma';
Przykładowe wykorzystanie
W folderze
lib
tworzymy plik
actions.ts
touch lib/actions.ts
Do pliku
actions.ts
dodajemy funkcję
getPosts()
// lib/actions.ts
import prisma from './prisma';
export async function getPosts(isPublished: boolean = true) {
return prisma.post.findMany({
where: { published: isPublished },
include: {
author: {
select: { name: true },
},
},
});
}
Tworzymy route
posts
mkdir app/posts && touch app/posts/page.tsx
Do pliku
posts/page.tsx
dodajemy następujący kod, aby zobaczyć nnaniesione wcześniej w Prisma Studio posty:
// posts/page.tsx
import { getPosts } from "@/lib/actions";
import { Post } from "@prisma/client";
export default async function Posts() {
const posts: Post[] = await getPosts(false);
return (
{posts.map((post) => {
return <div key="{post.id}">{post.title}<div>;
})}
);
}
To już prawie wszystko.
Prawie, gdyż w tym stanie deploy na Vercel może pokazać błędy.
Jest to spowodawane tym, żę Prisma wymaga uruchomienia npx prism generate
po każdej zmianie.
Dodajemy więc "postinstall": "prisma generate"
do sekcji "scripts"
w pliku package.json
Cała więc sekcja "scripts"
powinna wyglądać mniej więcej tak:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"postinstall": "prisma generate"
}