در دنیای دائماً در حال توسعه توسعه وب، انتخاب ابزارها و فریمورکهای مناسب میتواند تغییرات مفید بسیار زیادی را ایجاد کند. یکی از ابزارهایی که مدتی است مورد توجه توسعهدهندگان قرار گرفته است، Prisma میباشد. Prisma یک ORM و جعبه ابزار دیتابیس مدرن متن باز است که کار با دیتابیس را برای توسعهدهندگان آسانتر میکند. نحوه کار Prisma شبیه به نحوه کار مواردی مانند Sequelize یا Mongoose برای MongoDB است. ما میتوانیم از Prisma تقریباً برای هر چیزی، از REST API گرفته تا GraphQL API و CLI و برنامههای Full-Stack استفاده نماییم.
Prisma مفهوم type safety را فراهم میکند و خطاهای مربوط به دادهها را در زمان اجرا میگیرد. این بدان معناست که ما میتوانیم مشکلات احتمالی را قبل از اجرای کد شناسایی کرده و به آن رسیدگی کنیم و در نتیجه برنامههای مطمئنتر و بدون خطا ایجاد نماییم. میتوانیم از Prisma همراه با جاوااسکریپت یا تایپ اسکریپت استفاده کنیم.
با توجه به ویژگیهای پروژهای که داریم میتوانیم از دیتابیسهای مختلفی استفاده کنیم. Prisma معمولاً با دیتابیسهای relational مانند Postgres، MySQL، SQLite و غیره مورد استفاده قرار میگیرید، اما میتوانیم از آن همراه با دیتابیسهای NoSQL مانند MongoDB نیز بهرهمند شویم. نکته جالب این است که کد و مدل ما بر اساس دیتابیس تغییر نخواهد کرد. بنابراین از نظر فنی میتوانیم با ویرایش فایل .env
و credentialهای دیتابیس خود، یکی را با دیگری تعویض نماییم.
در نهایت Prisma به طور خودکار براساس طرح دیتابیس ما، کد تولید میکند. بنابراین اگر تا به حال از مواردی مانند Sequelize یا Mongoose برای MongoDB استفاده کرده باشیم، ایجاد یک schema مشابه کاری است که با آن ابزار انجام میدهیم. معمولاً هنگام کار با یک دیتابیس relational، قبل از شروع کدنویسی، باید تمام فیلدهای خود را با تایپها و جداول در سطح دیتابیس ایجاد کنیم. اما با Prisma میتوانیم به سادگی کدهایی را اجرا کنیم که به مدلهای ما نگاه میکند و جداول، ردیفها و ستونها و هر محدودیتی را که مشخص میکنیم، ایجاد مینمایند.
Prisma دارای سه کامپوننت اصلی است که عبارتند از:
میتوانیم از Prisma Client با هر برنامه Node.js یا تایپ اسکریپتی استفاده کنیم. این مورد شامل برنامههای Full Stack، REST API، GraphQL API، CLI و موارد دیگر میشود. از تکمیل خودکار و بررسی تایپ در IDE پشتیبانی میکند. اگر در حال ساخت یک برنامه تک صفحهای (SPA) هستیم، معمولاً از Prisma client روی سرور استفاده میکنیم و سپس مسیرهای خود را میسازیم تا endpointهای API را برای رابط کاربری خود ایجاد نماییم تا با آنها تعامل داشته باشد.
Prisma Migrate برای سادهسازی و خودکارسازی فرآیند مدیریت schema دیتابیس در تکمیل برنامه طراحی شده است. این بخش در طول migrationهای schema، دادههای ما را حفظ میکند. به این صورت که، statementهای SQL را میسازد تا تغییرات لازم را در دیتابیس ایجاد نماید و در عین حال از دست دادن داده یا خرابی را به حداقل برساند.
Prisma Studio تنها بخشی از Prisma است که متن باز نیست. این یک رابط کاربری گرافیکی میباشد که به ما این امکان را میدهد تا دادهها را در دیتابیس خود مشاهده و ویرایش کنیم. استفاده از Prisma الزامی نیست.
در ابتدا کار یک فولدر جدید میسازیم. آن فایل را در ویرایشگر یا IDE خود باز میکنیم که ما از VS Code استفاده خواهیم کرد.
قصد داریم یک پروژه جدید Node.js را مقداردهی اولیه کنیم. میتوانیم این کار را با اجرای npm init -y
انجام دهیم. با این کار یک فایل package.json
جدید برای ما ایجاد میشود.
ما یک پروژه تایپ اسکریپت ایجاد خواهیم کرد، بنابراین TypeScript، ts-node و type را برای Node.js نصب میکنیم. با اجرای دستور زیر میتوانیم این کار را انجام دهیم:
npm install typescript ts-node @types/node -D
ts-node یک محیط اجرای تایپ اسکریپت برای Node.js است. این محیط به ما اجازه میدهد تا فایلهای .ts
را مستقیماً بدون نیاز به کامپایل اجرا کنیم.
@types/node
تعاریف تایپ تایپ اسکریپت را برای ماژولهای اصلی Node.js و کتابخانه استاندارد ارائه میدهد.
اکنون، با اجرای دستور زیر یک پروژه تایپ اسکریپت جدید را راهاندازی میکنیم:
npx tsc --init
با این کار یک فایل tsconfig.json
برای ما ایجاد میشود. ما در این مقاله از تایپ اسکریپت فقط برای اجرای کوئریهای Prisma استفاده میکنیم. اگر قصد یادگیری زبان برنامه نویسی تایپ اسکریپت را دارید، ویدیو آموزش TypeScript – دوره فشرده کانال یوتیوب فرانت کست را پیشنهاد میکنیم.
اکنون میتوانیم Prisma CLI را نصب کنیم. این کار را با اجرای دستور زیر انجام میدهیم:
npm install prisma -D
حالا میخواهیم یک پروژه جدید Prisma را مقداردهی اولیه کنیم. میتوانیم از دیتابیسی مانند Postres، MySQL یا MongoDB استفاده کنیم، اما مطمئناً باید هر چیزی را که استفاده میکنیم روی سیستم خود نصب داشته باشیم. ما در این آموزش از SQLite استفاده میکنیم. نحوه استفاده از Prisma و تنظیم مدلهای داده، صرف نظر از نوع دیتابیسی که استفاده میکنیم، یکسان است.
میتوانیم با اجرای دستور زیر یک پروژه جدید Prisma را راهاندازی کرده و از SQLite به عنوان provider استفاده نماییم:
npx prisma init --datasource-provider sqlite
با این کار یک پوشه prisma
جدید برای ما ایجاد میشود. در داخل آن پوشه، یک فایل schema.prisma
خواهیم داشت. این فایل، جایی است که مدل داده خود را تعریف میکنیم. یک فایل env
نیز وجود دارد که اتصال دیتابیس خود را در آن تعریف خواهیم کرد. اگر از مواردی مانند PostgreSQL استفاده کنیم، باید اتصال دیتابیس خود را در فایل .env
تعریف نماییم. از آنجایی که ما از SQLite استفاده میکنیم، باید موارد زیر را در فایل .env
خود داشته باشیم:
DATABASE_URL = 'file:./dev.db';
نیازی نیست که ما این فایل را بسازیم. وقتی migration را اجرا کنیم، Prisma این فایل را برای ما ایجاد خواهد کرد.
مدلسازی داده فرآیند تعریف الزامات دادهها و ساختارهای یک سیستم است. ما از مدلسازی برای تعریف مدل داده برای دیتابیس استفاده میکنیم.
در Prisma، مدلسازی داده معمولاً شامل توصیف schema دیتابیس از جمله جداول، فیلدها، تایپهای دادهها و روابط بین آنها میباشد. مدلسازی دادههای موثر در Prisma بسیار مهم است. زیرا پایه و اساس ساخت عملیات دیتابیس و کوئریها را تشکیل میدهد و تضمین میکند که دادهها به طور کارآمد، دقیق و به گونهای که با نیازهای برنامه هماهنگ باشند، ساخته شوند.
Prisma schema جایی است که ما مدل داده خود را تعریف میکنیم. این به زبان Prisma schema نوشته شده است. زبان Prisma schema یک زبان declarative است که به ما این امکان را میدهد که مدل داده و روابط بین مدلهای خود را تعریف کنیم.
فایل schema.prisma
را باز میکنیم. باید چیزی شبیه به مقادیر زیر را در آن ببینیم:
datasource db { provider = "sqlite" url = env("DATABASE_URL") } generator client { provider = "prisma-client-js" }
Prisma schema دارای سه قسمت میباشد که عبارتند از:
در ادامه مدلهای داده User
و Article
را تعریف میکنیم:
model User { id Int @id @default(autoincrement()) email String @unique name String? articles Article[] } model Article { id Int @id @default(autoincrement()) title String body String? author User @relation(fields: [authorId], references: [id]) authorId Int }
برای مدل User
یک فیلد id
داریم که یک Int است و کلید اصلی میباشد. همچنین یک فیلد email
داریم که هم تایپ رشته دارد و منحصربهفرد است. پس از آن یک فیلد name
داریم که تایپ آن هم رشته میباشد و یک ?
دارد تا آن را به عنوان یک فیلد اختیاری علامتگذاری میکند. همچنین یک فیلد articles
هم داریم که آرایهای از مدلهای Article
را شامل میشود.
برای مدل Article
یک فیلد id
داریم که یک Int است و کلید اصلی میباشد. پس از آن یک فیلد title
داریم که تایپ آن رشته میباشد. همینطور یک فیلد body
داریم که تایپ آن رشته میباشد و یک ?
دارد تا آن را به عنوان یک فیلد اختیاری علامت گذاری میکند. سپس فیلد author
را داریم که یک مدل User
است. در نهایت هم فیلد authorId
را داریم که تایپ آن هم Int میباشد.
همچنین روابط بین مدلهای خود را این گونه تنظیم کردهایم که یک کاربر میتواند دارای چندین تعداد مقاله باشد اما هر مقاله فقط میتواند یک نویسنده داشته باشد. همینطور، فیلد autorId
در مدل Article
به فیلد id
در مدل User
رفرنس دارد.
اکنون که مدل داده خود را تعریف کردیم، باید migration را اجرا کنیم. migration راهی است که schema دیتابیس را بهروزرسانی میکند و در نتیجه این کار، میتوانیم schema دیتابیس خود را با Prisma schema هماهنگ کنیم.
migration را با دستور زیر اجرا میکنیم:
npx prisma migrate dev --name init
این دستور یک migration جدید ایجاد کرده و آن را اجرا میکند. flag --name
به ما اجازه میدهد تا یک نام به migration خود اختصاص بدهیم، که گزینه اختیاری است. زیرا، اگر نامی ارائه نکنیم Prisma یک نام برای آن ایجاد خواهد کرد.
اگر از PostgreSQL یا چیز دیگری هم استفاده میکردیم، همین کار را انجام میدادیم. تنها تفاوت این است که باید اتصال دیتابیس خود را در فایل env.
تعریف کنیم.
ما میتوانیم یک فایل تایپ اسکریپت جدید برای ارسال کوئری از طریق Prisma Client ایجاد کنیم. برای این کار، یک فایل جدید به نام index.ts
در root پروژه ساخته و کد زیر را به آن اضافه میکنیم:
import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); async function main() { // Prisma Queries } main() .then(async () => { await prisma.$disconnect(); }) .catch(async (e) => { console.error(e); await prisma.$disconnect(); process.exit(1); });
در این کد، ما PrismaClient را از @prisma/client
import میکنیم و یک نمونه جدید از PrismaClient میسازیم. همچنین یک تابع async به نام main
را هم ایجاد میکنیم. در داخل تابع main
، کوئریهای Prisma Client خود را مینویسیم.
تابع main
را فراخوانی میکنیم و در نمونه prisma که ساختیم، متد $disconnect
را فراخوانی مینماییم. این متد برای قطع ارتباط با دیتابیس پس از اتمام کار است. همچنین هر گونه خطا را شناسایی کرده و آنها را در کنسول ثبت میکنیم.
اکنون قصد داریم که یک کوئری بنویسیم تا یک کاربر جدید بسازیم. این کد را بعد از کامنت // Prisma Queries
اضافه میکنیم:
const user = await prisma.user.create({ data: { name: 'John Doe', email: 'john@gmail.com', }, }); console.log(user);
با استفاده از دستور زیر، فایل را اجرا میکنیم:
npx ts-node index.ts
با این کد یک کاربر جدید میسازیم و آن را در کنسول نمایش میدهیم.
برای این که لیست همه کاربران را بدست بیاوریم، میتوانیم از کد زیر استفاده کنیم:
const users = await prisma.user.findMany(); console.log(users);
اکنون اگر فایل را دوباره اجرا کنیم میتوانیم لیست کاربرانی که وارد آرایه شدهاند را در کنسول ببینیم.
یک article جدید میسازیم و یک ارتباط بین آن مقاله و یک کاربر ایجاد میکنیم:
const article = await prisma.article.create({ data: { title: 'Johns First Article', body: 'This is Johns first article', author: { connect: { id: 1, }, }, }, }); console.log(article);
ما میتوانیم لیست تمام مقالات را با کمک دستور زیر دریافت نماییم:
const articles = await prisma.article.findMany(); console.log(articles);
اکنون، یک کاربر جدید میسازیم و آن را با یک مقاله مرتبط میکنیم:
const user = await prisma.user.create({ data: { name: 'Sara Smith', email: 'sara@gmail.com', articles: { create: { title: 'Saras First Article', body: 'This is my first article', }, }, }, });
دوباره لیست همه مقالات را دریافت میکنیم:
const articles = await prisma.article.findMany(); console.log(articles);
فایل را اجرا کرده و مقالات ثبت شده در کنسول را میبینیم.
اگر برای دریافت لیست کاربران کد زیر را اجرا کنیم:
const users = await prisma.user.findMany(); console.log(users);
در این حالت ما فقط فیلدهای اسکالر را خواهیم دید و فیلد مقالات را مشاهده نخواهیم کرد. دلیل این اتفاق این است که فیلد articles
یک فیلد relation است. برای بدست آوردن فیلدهای relation باید از گزینه include استفاده کنیم. کوئری را بهروزرسانی میکنیم تا کاربران فیلد articles
را هم داشته باشیم:
const users = await prisma.user.findMany({ include: { articles: true, }, }); console.log(users);
اکنون میتوانیم فیلد articles
را در کنسول را مشاهده نماییم. فیلد articles
آرایهای از آبجکتها میباشد.
در ادامه بر روی users
یک loop ایجاد میکنیم تا دادههای user
و article
را در کنسول نمایش دهیم:
users.forEach((user) => { console.log(`User: ${user.name}, Email: ${user.email}`); console.log('Articles:'); user.articles.forEach((article) => { console.log(`- Title: ${article.title}, Body: ${article.body}`); }); console.log('\n'); });
در نتیجه میتوانیم ببینیم که Prisma Client کار کردن با relationshipها را آسانتر میکند.
در این بخش قصد داریم تا نام کاربر را ویرایش کنیم:
const user = await prisma.user.update({ where: { id: 1, }, data: { name: 'John Doe Jr.', }, }); console.log(user);
در این قسمت هم میخواهیم مقاله اول را حذف کنیم:
const article = await prisma.article.delete({ where: { id: 1, }, });
اکنون اگر مقالات و یا کاربران همراه با مقاله را در کنسول نمایش دهیم، میبینیم که این مقاله دیگر وجود ندارد.
console.log(articles); console.log(users);
Prisma Studio یک رابط کاربری گرافیکی (GUI) است که به ما این امکان را میدهد تا دادهها را در دیتابیس خود مشاهده و ویرایش کنیم. استفاده از Prisma الزامی نیست، اما داشتن آن ابزار خوبی است. برای راهاندازی Prisma Studio، میتوانیم دستور زیر را اجرا کنیم:
npx prisma studio
پس از اجرای دستور، Prisma Studio در مرورگر ما باز میشود. از این طریق میتوانیم دادههای خود را مشاهده و ویرایش نماییم. همچنین میتوانیم مدل دادههای خود را هم ببینیم و کوئریها را اجرا کنیم.
همانطور که در این مقاله دیدیم، Prisma کار با دیتابیس را سادهتر میکند. برای کسب اطلاعات بیشتر درمورد Prisma مطالعه مستندات میتواند مفید باشد.
۵۰ درصد تخفیف ویژه پاییز فرانت کست تا پایان هفته
کد تخفیف: atm