Prisma Tutorial
Einleitung
Prisma ist ein Open-Source-ORM für Node.js und TypeScript. Es besteht aus drei Hauptwerkzeugen:
- Prisma Client: Ein automatisch generierter und typsicherer Query-Builder.
- Prisma Migrate: Ein leistungsstarkes Datenmodellierungs- und Migrationssystem.
- Prisma Studio: Eine GUI zur Ansicht und Bearbeitung von Daten in Ihrer Datenbank.
Diese Werkzeuge sollen die Produktivität von Anwendungsentwicklern in ihren Datenbank-Workflows erhöhen. Einer der Hauptvorteile von Prisma ist das Abstraktionsniveau, das es bietet: Anstatt komplexe SQL-Abfragen oder Schema-Migrationen zu verstehen, können Anwendungsentwickler ihre Daten auf eine intuitivere Weise betrachten, wenn sie Prisma verwenden.
In diesem Tutorial erstellen Sie eine REST-API für eine kleine Blogging-Anwendung in TypeScript unter Verwendung von Prisma und einer PostgreSQL-Datenbank. Sie richten Ihre PostgreSQL-Datenbank lokal mit Docker ein und implementieren die REST-API-Routen mit Express. Am Ende des Tutorials haben Sie einen lokal auf Ihrem Computer laufenden Webserver, der auf verschiedene HTTP-Anfragen reagieren und Daten in der Datenbank lesen und schreiben kann.
Voraussetzungen
Dieses Tutorial setzt Folgendes voraus:
- Node.js Version 14 oder höher auf Ihrem Computer installiert. Sie können eine der Anleitungen zur Installation von Node.js und zur Erstellung einer lokalen Entwicklungsumgebung für Ihr Betriebssystem verwenden.
- Docker auf Ihrem Computer installiert (zum Ausführen der PostgreSQL-Datenbank). Sie können Docker über die Docker-Website für macOS und Windows installieren oder Anleitungen zur Installation und Verwendung von Docker für Linux-Distributionen folgen.
- Grundlegende Kenntnisse in TypeScript und REST-APIs sind hilfreich, aber nicht erforderlich für dieses Tutorial.
Schritt 1 – Erstellen Ihres TypeScript-Projekts
In diesem Schritt richten Sie ein einfaches TypeScript-Projekt mit npm ein. Dieses Projekt wird die Grundlage für die REST-API sein, die Sie in diesem Tutorial erstellen werden.
Erstellen Sie zuerst ein neues Verzeichnis für Ihr Projekt:
mkdir my-blog
Wechseln Sie anschließend in das Verzeichnis und initialisieren Sie ein leeres npm-Projekt. Beachten Sie, dass die Option -y bedeutet, dass Sie die interaktiven Eingabeaufforderungen des Befehls überspringen. Um die Eingabeaufforderungen durchzugehen, entfernen Sie -y aus dem Befehl:
cd my-blog
npm init -y
Für weitere Details zu diesen Eingabeaufforderungen können Sie Schritt 1 in der Anleitung zur Verwendung von Node.js-Modulen mit npm und package.json folgen.
Sie erhalten eine Ausgabe ähnlich der folgenden mit den Standardantworten:
Output
Wrote to /.../my-blog/package.json:
{
"name": "my-blog",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Dieser Befehl erstellt eine minimale package.json-Datei, die Sie als Konfigurationsdatei für Ihr npm-Projekt verwenden. Sie können jetzt TypeScript in Ihrem Projekt konfigurieren.
Führen Sie den folgenden Befehl für eine einfache TypeScript-Einrichtung aus:
npm install typescript ts-node @types/node --save-dev
Dies installiert drei Pakete als Entwicklungsabhängigkeiten in Ihrem Projekt:
- typescript: Die TypeScript-Toolchain.
- ts-node: Ein Paket zum Ausführen von TypeScript-Anwendungen ohne vorherige Kompilierung zu JavaScript.
- @types/node: Die TypeScript-Typdefinitionen für Node.js.
Der letzte Schritt besteht darin, eine tsconfig.json-Datei hinzuzufügen, um sicherzustellen, dass TypeScript für die Anwendung, die Sie erstellen werden, ordnungsgemäß konfiguriert ist.
Führen Sie zuerst den folgenden Befehl aus, um die Datei zu erstellen:
nano tsconfig.json
Fügen Sie den folgenden JSON-Code in die Datei ein:
my-blog/tsconfig.json
{
"compilerOptions": {
"sourceMap": true,
"outDir": "dist",
"strict": true,
"lib": ["esnext"],
"esModuleInterop": true
}
}
Speichern und schließen Sie die Datei.
Schritt 2 – Einrichtung von Prisma mit PostgreSQL
In diesem Schritt installieren Sie die Prisma CLI, erstellen Ihre initiale Prisma-Schema-Datei und richten PostgreSQL mit Docker ein. Danach verbinden Sie Prisma mit der Datenbank. Die Prisma-Schema-Datei ist die Hauptkonfigurationsdatei für Ihre Prisma-Einrichtung und enthält Ihr Datenbankschema.
Prisma CLI installieren
Beginnen Sie mit der Installation der Prisma CLI mit folgendem Befehl:
npm install prisma --save-dev
Als Best Practice wird empfohlen, die Prisma CLI lokal in Ihrem Projekt zu installieren (anstatt global). Dies hilft, Versionskonflikte zu vermeiden, falls Sie mehrere Prisma-Projekte auf Ihrem Computer haben.
PostgreSQL mit Docker einrichten
Erstellen Sie eine neue Docker-Compose-Datei mit folgendem Befehl:
nano docker-compose.yml
Fügen Sie dann den folgenden Code in die neu erstellte Datei ein:
version: '3.8'
services:
postgres:
image: postgres:10.3
restart: always
environment:
- POSTGRES_USER=sammy
- POSTGRES_PASSWORD=your_password
volumes:
- postgres:/var/lib/postgresql/data
ports:
- '5432:5432'
volumes:
postgres:
Diese Docker-Compose-Datei konfiguriert eine PostgreSQL-Datenbank, die über Port 5432 des Docker-Containers zugänglich ist. Die Datenbankanmeldedaten sind aktuell als Benutzer sammy
und Passwort your_password
eingestellt. Passen Sie diese Anmeldedaten nach Belieben an. Speichern und schließen Sie die Datei.
Datenbankserver starten
Starten Sie den PostgreSQL-Datenbankserver mit folgendem Befehl:
docker-compose up -d
Die Ausgabe dieses Befehls wird ähnlich aussehen:
Output
Pulling postgres (postgres:10.3)...
10.3: Pulling from library/postgres
f2aa67a397c4: Pull complete
6de83ca23e55: Pull complete
. . .
Status: Downloaded newer image for postgres:10.3
Creating my-blog_postgres_1 ... done
Sie können überprüfen, ob der Datenbankserver läuft, indem Sie den folgenden Befehl ausführen:
docker ps
Dieser Befehl wird eine Ausgabe ähnlich der folgenden anzeigen:
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8547f8e007ba postgres:10.3 "docker-entrypoint.s…" 3 seconds ago Up 2 seconds 0.0.0.0:5432->5432/tcp my-blog_postgres_1
Prisma-Setup erstellen
Mit dem laufenden Datenbankserver können Sie jetzt Ihre Prisma-Einrichtung erstellen. Führen Sie den folgenden Befehl aus:
npx prisma init
Dieser Befehl gibt folgende Ausgabe aus:
Output
✔ Your Prisma schema was created at prisma/schema.prisma.
You can now open it in your favorite editor.
Als Best Practice sollten Sie alle Aufrufe der Prisma CLI mit npx
voranstellen, um sicherzustellen, dass Ihre lokale Installation verwendet wird.
Nach dem Ausführen des Befehls erstellt die Prisma CLI einen neuen Ordner namens prisma
in Ihrem Projekt. Darin finden Sie eine Datei namens schema.prisma
, die die Hauptkonfigurationsdatei für Ihr Prisma-Projekt ist (einschließlich Ihres Datenmodells). Der Befehl erstellt außerdem eine Datei .env
, in der Sie die Verbindungs-URL für Ihre Datenbank definieren.
Datenbankverbindung einrichten
Um sicherzustellen, dass Prisma den Standort Ihrer Datenbank kennt, öffnen Sie die Datei .env
und passen die Umgebungsvariable DATABASE_URL
an:
nano .env
Ändern Sie die Variable wie folgt:
DATABASE_URL="postgresql://sammy:your_password@localhost:5432/my-blog?schema=public"
Stellen Sie sicher, dass Sie die Anmeldedaten an die in der Docker-Compose-Datei angegebenen Anmeldeinformationen anpassen. Speichern und schließen Sie die Datei.
Schritt 3 – Definition Ihres Datenmodells und Erstellen von Datenbanktabellen
In diesem Schritt definieren Sie Ihr Datenmodell in der Prisma-Schema-Datei. Dieses Datenmodell wird dann mithilfe von Prisma Migrate auf die Datenbank abgebildet, das die SQL-Anweisungen für die Erstellung der Tabellen generiert und an die Datenbank sendet. Da Sie eine Blogging-Anwendung erstellen, werden die Haupteinheiten der Anwendung Benutzer und Beiträge sein.
Datenmodell definieren
Prisma verwendet seine eigene Datenmodellierungssprache, um die Struktur Ihrer Anwendungsdaten zu definieren.
Öffnen Sie zuerst Ihre Datei schema.prisma
mit folgendem Befehl:
nano prisma/schema.prisma
Fügen Sie nun die folgenden Modelldefinitionen hinzu. Platzieren Sie die Modelle am unteren Ende der Datei, direkt nach dem Generator-Client-Block:
model User {
id Int @default(autoincrement()) @id
email String @unique
name String?
posts Post[]
}
model Post {
id Int @default(autoincrement()) @id
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
Sie definieren zwei Modelle: User
und Post
. Jedes davon hat eine Anzahl von Feldern, die die Eigenschaften des Modells darstellen. Die Modelle werden auf Datenbanktabellen abgebildet, wobei die Felder die einzelnen Spalten darstellen.
Es besteht eine Eins-zu-Viele-Beziehung zwischen den beiden Modellen, die durch die Felder posts
und author
auf User
bzw. Post
angegeben ist. Das bedeutet, dass ein Benutzer mit vielen Beiträgen verknüpft sein kann.
Speichern und schließen Sie die Datei.
Datenbanktabellen mit Prisma Migrate erstellen
Mit diesen Modellen können Sie jetzt die entsprechenden Tabellen in der Datenbank mithilfe von Prisma Migrate erstellen. Führen Sie den folgenden Befehl in Ihrem Terminal aus:
npx prisma migrate dev --name init
Dieser Befehl erstellt eine neue SQL-Migration auf Ihrem Dateisystem und sendet sie an die Datenbank. Die Option --name init
gibt den Namen der Migration an und wird verwendet, um den Namen des erstellten Migrationsordners auf Ihrem Dateisystem zu definieren.
Die Ausgabe dieses Befehls wird ähnlich aussehen:
Output
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "my-blog", schema "public" at "localhost:5432"
PostgreSQL database my-blog created at localhost:5432
The following migration(s) have been created and applied from new schema changes:
migrations/
└─ 20201209084626_init/
└─ migration.sql
Running generate... (Use --skip-generate to skip the generators)
✔ Generated Prisma Client (2.13.0) to ./node_modules/@prisma/client in 75ms
Die SQL-Migrationsdatei im Verzeichnis prisma/migrations/20201209084626_init/migration.sql
enthält die folgenden Anweisungen, die gegen die Datenbank ausgeführt wurden (der hervorgehobene Teil des Dateinamens kann in Ihrer Einrichtung unterschiedlich sein):
-- CreateTable
CREATE TABLE "User" (
"id" SERIAL,
"email" TEXT NOT NULL,
"name" TEXT,
PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Post" (
"id" SERIAL,
"title" TEXT NOT NULL,
"content" TEXT,
"published" BOOLEAN NOT NULL DEFAULT false,
"authorId" INTEGER,
PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "User.email_unique" ON "User"("email");
-- AddForeignKey
ALTER TABLE "Post" ADD FOREIGN KEY("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
In diesem Schritt haben Sie Ihr Datenmodell in Ihrer Prisma-Schema-Datei definiert und die entsprechenden Datenbanktabellen mithilfe von Prisma Migrate erstellt.
Schritt 4 – Erkundung von Prisma-Client-Abfragen in einem einfachen Skript
Der Prisma-Client ist ein automatisch generierter und typsicherer Abfrage-Builder, mit dem Sie programmgesteuert Daten in einer Datenbank auslesen und schreiben können, sei es von einer Node.js- oder TypeScript-Anwendung aus. Sie verwenden ihn, um innerhalb Ihrer REST-API-Routen auf die Datenbank zuzugreifen und dabei traditionelle ORMs, SQL-Abfragen oder benutzerdefinierte Datenzugriffsschichten zu ersetzen.
Prisma-Client installieren
In diesem Schritt installieren Sie den Prisma-Client und machen sich mit den Abfragen vertraut, die Sie damit senden können. Bevor Sie die Routen für Ihre REST-API implementieren, erkunden Sie die Abfragen in einem einfachen ausführbaren Skript.
Installieren Sie den Prisma-Client in Ihrem Projektordner mit folgendem Befehl:
npm install @prisma/client
Ein einfaches Skript erstellen
Erstellen Sie ein neues Verzeichnis namens src
, das Ihre Quelldateien enthält:
mkdir src
Erstellen Sie dann eine TypeScript-Datei in diesem neuen Verzeichnis:
nano src/index.ts
Fügen Sie in die Datei folgenden Boilerplate-Code ein, der eine asynchrone Funktion enthält, die in Ihrem Skript ausgeführt wird:
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
// ... Ihre Prisma-Client-Abfragen kommen hierhin
}
main()
.catch((e) => console.error(e))
.finally(async () => await prisma.$disconnect());
Speichern und schließen Sie die Datei.
Beispielabfragen hinzufügen
Erweitern Sie die Datei index.ts
, indem Sie folgende Abfragen in der asynchronen Funktion main
hinzufügen:
async function main() {
const newUser = await prisma.user.create({
data: {
name: 'Alice',
email: 'alice@prisma.io',
posts: {
create: {
title: 'Hello World',
},
},
},
});
console.log('Erstellter Benutzer: ', newUser);
const allUsers = await prisma.user.findMany({
include: { posts: true },
});
console.log('Alle Benutzer: ');
console.dir(allUsers, { depth: null });
}
In diesem Code verwenden Sie zwei Prisma-Client-Abfragen:
- create: Erstellt einen neuen Benutzer-Datensatz. Sie verwenden eine geschachtelte Schreibabfrage, um sowohl einen Benutzer- als auch einen Beitrags-Datensatz in derselben Abfrage zu erstellen.
- findMany: Liest alle vorhandenen Benutzer-Datensätze aus der Datenbank. Sie geben die Option
include
an, die zusätzlich die zugehörigen Beitrags-Datensätze für jeden Benutzer-Datensatz lädt.
Das Skript ausführen
Führen Sie das Skript mit folgendem Befehl aus:
npx ts-node src/index.ts
Die Ausgabe in Ihrem Terminal wird wie folgt aussehen:
Output
Erstellter Benutzer: { id: 1, email: 'alice@prisma.io', name: 'Alice' }
Alle Benutzer:
[
{
id: 1,
email: 'alice@prisma.io',
name: 'Alice',
posts: [
{
id: 1,
title: 'Hello World',
content: null,
published: false,
authorId: 1
}
]
}
]
In diesem Schritt haben Sie den Prisma-Client verwendet, um Daten in Ihrer Datenbank zu lesen und zu schreiben. In den nächsten Schritten implementieren Sie diese Abfragen in REST-API-Routen.
Schritt 5 – Implementierung Ihrer ersten REST-API-Route
In diesem Schritt installieren Sie Express in Ihrer Anwendung. Express ist ein beliebtes Webframework für Node.js, das Sie verwenden, um die REST-API-Routen in diesem Projekt zu implementieren. Die erste Route, die Sie implementieren, ermöglicht es Ihnen, alle Benutzer über eine GET-Anfrage von der API abzurufen. Die Benutzerdaten werden mithilfe des Prisma-Clients aus der Datenbank abgerufen.
Express installieren
Installieren Sie Express mit folgendem Befehl:
npm install express
Da Sie TypeScript verwenden, installieren Sie auch die entsprechenden Typen als Entwicklungsabhängigkeiten:
npm install @types/express --save-dev
Express-Anwendung einrichten
Mit den installierten Abhängigkeiten können Sie Ihre Express-Anwendung einrichten. Öffnen Sie Ihre Hauptdatei:
nano src/index.ts
Löschen Sie den bisherigen Code in index.ts
und ersetzen Sie ihn durch Folgendes, um Ihre REST-API zu starten:
import { PrismaClient } from '@prisma/client';
import express from 'express';
const prisma = new PrismaClient();
const app = express();
app.use(express.json());
// ... Ihre REST-API-Routen kommen hierhin
app.listen(3000, () =>
console.log('REST-API-Server bereit unter: http://localhost:3000'),
);
Erste Route implementieren
Fügen Sie zwischen den Aufrufen von app.use
und app.listen
die folgende app.get
-Route hinzu:
app.use(express.json());
app.get('/users', async (req, res) => {
const users = await prisma.user.findMany();
res.json(users);
});
app.listen(3000, () =>
console.log('REST-API-Server bereit unter: http://localhost:3000'),
);
Route testen
Speichern und schließen Sie Ihre Datei. Starten Sie anschließend Ihren lokalen Webserver mit folgendem Befehl:
npx ts-node src/index.ts
Die Ausgabe wird wie folgt aussehen:
Output
REST-API-Server bereit unter: http://localhost:3000
Um die Route /users
aufzurufen, öffnen Sie Ihren Browser und navigieren zu http://localhost:3000/users
oder verwenden einen beliebigen HTTP-Client.
Testen Sie die Route mit curl
, indem Sie folgendes ausführen:
curl http://localhost:3000/users
Die Ausgabe enthält die Benutzerdaten, die Sie zuvor erstellt haben:
Output
[{"id":1,"email":"alice@prisma.io","name":"Alice"}]
Das Feld posts
ist diesmal nicht enthalten, da Sie die Option include
bei der Implementierung der findMany
-Abfrage für die Route /users
nicht verwendet haben.
Sie haben erfolgreich Ihre erste REST-API-Route unter /users
implementiert. Im nächsten Schritt implementieren Sie die restlichen REST-API-Routen, um Ihrer API weitere Funktionalität hinzuzufügen.
Schritt 6 – Implementierung der restlichen REST-API-Routen
In diesem Schritt implementieren Sie die restlichen REST-API-Routen für Ihre Blogging-Anwendung. Am Ende wird Ihr Webserver verschiedene GET-, POST-, PUT- und DELETE-Anfragen unterstützen.
Zusätzliche Routen definieren
Die Routen, die Sie implementieren, umfassen die folgenden Optionen:
HTTP-Methode | Route | Beschreibung |
---|---|---|
GET | /feed | Holt alle veröffentlichten Beiträge ab. |
GET | /post/:id | Holt einen bestimmten Beitrag anhand seiner ID ab. |
POST | /user | Erstellt einen neuen Benutzer. |
POST | /post | Erstellt einen neuen Beitrag (als Entwurf). |
PUT | /post/publish/:id | Setzt das published -Feld eines Beitrags auf true . |
DELETE | /post/:id | Löscht einen Beitrag anhand seiner ID. |
GET-Routen implementieren
Stoppen Sie den Server mit CTRL+C
und öffnen Sie Ihre index.ts
-Datei zur Bearbeitung:
nano src/index.ts
Fügen Sie folgende Routen hinzu:
app.get('/feed', async (req, res) => {
const posts = await prisma.post.findMany({
where: { published: true },
include: { author: true },
});
res.json(posts);
});
app.get('/post/:id', async (req, res) => {
const { id } = req.params;
const post = await prisma.post.findUnique({
where: { id: Number(id) },
});
res.json(post);
});
Speichern Sie die Datei und starten Sie den Server neu:
npx ts-node src/index.ts
Testen Sie die Route /feed
mit curl
:
curl http://localhost:3000/feed
Da bisher keine Beiträge veröffentlicht wurden, ist die Antwort ein leeres Array:
[]
Testen Sie die Route /post/:id
mit folgendem Befehl:
curl http://localhost:3000/post/1
Die Antwort enthält den zuvor erstellten Beitrag:
{"id":1,"title":"Hello World","content":null,"published":false,"authorId":1}
POST-Routen implementieren
Stoppen Sie den Server und fügen Sie die folgenden POST-Routen hinzu:
app.post('/user', async (req, res) => {
const result = await prisma.user.create({
data: { ...req.body },
});
res.json(result);
});
app.post('/post', async (req, res) => {
const { title, content, authorEmail } = req.body;
const result = await prisma.post.create({
data: {
title,
content,
published: false,
author: { connect: { email: authorEmail } },
},
});
res.json(result);
});
PUT- und DELETE-Routen implementieren
Fügen Sie die folgenden Routen für das Aktualisieren und Löschen von Daten hinzu:
app.put('/post/publish/:id', async (req, res) => {
const { id } = req.params;
const post = await prisma.post.update({
where: { id: Number(id) },
data: { published: true },
});
res.json(post);
});
app.delete('/post/:id', async (req, res) => {
const { id } = req.params;
const post = await prisma.post.delete({
where: { id: Number(id) },
});
res.json(post);
});
Speichern Sie Ihre Änderungen, starten Sie den Server neu und testen Sie die Routen mit curl
oder einem anderen HTTP-Client. Ihre REST-API unterstützt jetzt GET-, POST-, PUT- und DELETE-Anfragen.
Fazit
In diesem Artikel haben Sie einen REST-API-Server mit mehreren Routen erstellt, um Benutzer- und Beitragsdaten für eine Beispiel-Blogging-Anwendung zu erstellen, auszulesen, zu aktualisieren und zu löschen. Innerhalb der API-Routen haben Sie den Prisma-Client verwendet, um die entsprechenden Abfragen an Ihre Datenbank zu senden.
Als nächste Schritte können Sie zusätzliche API-Routen implementieren oder Ihr Datenbankschema mithilfe von Prisma Migrate erweitern. Besuchen Sie die Prisma-Dokumentation, um mehr über verschiedene Aspekte von Prisma zu erfahren, und erkunden Sie einige sofort einsatzbereite Beispielprojekte, die Tools wie GraphQL oder gRPC-APIs in der prisma-examples-Repository verwenden.