خلاصه سریع ↬
محبوبیت Jamstack در چند سال گذشته به عنوان رویکردی برای ساخت وب سایت ها افزایش یافته است. همانطور که توسعه دهندگان در حال ساخت سایت های Jamstack هستند، یافتن یک روش یکپارچه برای تعامل با پایگاه داده می تواند یک مانع بزرگ باشد. در این مقاله، Sam Poder به بررسی نحوه ادغام Prisma با Jamstack می پردازد و چرا راه حلی عالی برای پایگاه های داده بدون سرور در پروژه های جاوا اسکریپت یا تایپ اسکریپت است.

رویکرد Jamstack از سخنرانی مت بیلمان، مدیر عامل نتلیفای، در Smashing Conf مجله Smashing در سال 2016 سرچشمه گرفت.

سایت‌های Jamstack محتوای از پیش رندرشده ثابت را از طریق CDN ارائه می‌کنند و محتوای پویا را از طریق میکروسرویس‌ها، APIها و عملکردهای بدون سرور تولید می‌کنند. آنها معمولاً با استفاده از چارچوب های جاوا اسکریپت، مانند Next.js یا Gatsby، و مولدهای سایت استاتیک – برای مثال Hugo یا Jekyll ایجاد می شوند. سایت های Jamstack اغلب از یک گردش کار استقرار مبتنی بر Git از طریق ابزارهایی مانند Vercel و Netlify استفاده می کنند. این خدمات استقرار را می توان در کنار یک CMS بدون هد مانند Strapi استفاده کرد.

هدف از استفاده از Jamstack برای ساخت یک سایت، ایجاد سایتی است که کارایی بالایی داشته باشد و اجرا شود. این سایت‌ها با پیش‌رندر کردن هرچه بیشتر محتوا و با ذخیره کردن پاسخ‌ها روی لبه، به سرعت بالایی دست می‌یابند (AKA اجرا شدن روی سرورهایی که تا حد امکان نزدیک به کاربر هستند، به عنوان مثال به کاربر مستقر در بمبئی از سروری در سنگاپور به جای سرویس‌دهی سانفرانسیسکو).

سایت های Jamstack برای اجرا مقرون به صرفه تر هستند، زیرا نیازی به استفاده از سرور اختصاصی به عنوان میزبان ندارند. در عوض، آنها می توانند استفاده از سرویس های ابری (PAAS) / میزبان ها / CDN ها را با قیمت کمتر ارائه دهند. این خدمات همچنین به روشی مقرون به صرفه تنظیم می شوند، بدون اینکه توسعه دهندگان زیرساخت خود را تغییر دهند و حجم کاری خود را کاهش دهند.

ابزار دیگری که این ترکیب را تشکیل می دهد Prisma است – یک ORM منبع باز (نقشه برداری رابطه ای شی) که برای TypeScript و JavaScript ساخته شده است.

Prisma یک ابزار جاوا اسکریپت / تایپ اسکریپت است که طرحی نوشته شده در استانداردهای Prisma را تفسیر می کند و یک ماژول نوع ایمن تولید می کند که روش هایی را برای ایجاد رکوردها، خواندن رکوردها، به روز رسانی رکوردها و حذف رکوردها (CRUD) ارائه می دهد.

Prisma اتصالات به پایگاه داده (از جمله ادغام) و انتقال پایگاه داده را مدیریت می کند. می‌تواند با پایگاه‌های داده‌ای که از PostgreSQL، MySQL، SQL Server یا SQLite استفاده می‌کنند متصل شود (به‌علاوه پشتیبانی MongoDB در پیش‌نمایش است).

برای کمک به درک شما از Prisma، در اینجا چند نمونه کد اساسی برای مدیریت CRUD کاربران آورده شده است:

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

const user = await prisma.user.create({
  data: {
    name: Sam,
    email: 'sam@sampoder.com',
  },
})

const users = await prisma.user.findMany()

const updateUser = await prisma.user.update({
  where: {
    email: 'sam@sampoder.com',
  },
  data: {
    email: 'deleteme@sampoder.com',
  },
})

const deleteUser = await prisma.user.delete({
  where: {
    email: 'deleteme@sampoder.com',
  },
})

طرح Prisma پروژه مرتبط به این صورت خواهد بود:

datasource db {
  url      = env("DATABASE_URL")
  provider = "postgresql"
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
}
بیشتر بعد از پرش! ادامه مطلب زیر ↓

موارد استفاده برای پریسما

با آگاهی از نحوه عملکرد Prisma، بیایید اکنون کشف کنیم که کجا می توانیم از آن در پروژه های Jamstack استفاده کنیم. داده ها در دو جنبه از Jamstack مهم هستند: در هنگام پیش رندر کردن صفحات استاتیک و در مسیرهای API. اینها کارهایی هستند که اغلب با استفاده از ابزارهای جاوا اسکریپت، مانند Next.js برای صفحات استاتیک و Cloudfare Workers برای مسیرهای API به دست می آیند. مسلماً، اینها همیشه با جاوا اسکریپت به دست نمی آیند – برای مثال، جکیل از Ruby استفاده می کند! بنابراین، شاید باید عنوان مورد Prisma را در Jamstack مبتنی بر جاوا اسکریپت اصلاح کنم. به هر حال به بعد!

یک مورد بسیار رایج برای Jamstack یک وبلاگ است که در آن Prisma برای ایجاد یک سیستم واکنش برای وبلاگ مفید خواهد بود. می‌توانید از آن در مسیرهای API با یکی که تعداد واکنش را واکشی می‌کند و برمی‌گرداند و دیگری که می‌تواند واکنش جدیدی را ثبت کند، استفاده می‌کنید. برای رسیدن به این هدف می توانید از create و findMany روش های پریسما!

یکی دیگر از موارد استفاده رایج برای Jamstack یک صفحه فرود است، و هیچ چیز بهتر از فرود با برخی از آمارهای عالی نیست! در Jamstack، می‌توانیم این صفحات را با آماری که از پایگاه‌های داده‌مان استخراج شده است، از قبل رندر کنیم که می‌توانیم با استفاده از روش‌های خواندن Prisma به آن دست پیدا کنیم.

با این حال، گاهی اوقات، Prisma ممکن است برای کارهای خاص کمی بیش از حد باشد. من توصیه می کنم از استفاده از Prisma و پایگاه داده های رابطه ای به طور کلی برای راه حل هایی که فقط به یک جدول پایگاه داده نیاز دارند اجتناب کنید، زیرا در این موارد پیچیدگی توسعه اضافی و اغلب غیر ضروری را اضافه می کند. به عنوان مثال، استفاده از Prisma برای یک جعبه ثبت نام در خبرنامه ایمیل یا یک فرم تماس، بسیار زیاد است.

جایگزین های پریسما

بنابراین، ما می‌توانیم از Prisma برای این کارها استفاده کنیم، اما می‌توانیم از ابزارهای زیادی برای دستیابی به آنها استفاده کنیم. پس چرا پریسما؟ بیایید سه گزینه پریسما را مرور کنیم، و من سعی می کنم شما را متقاعد کنم که Prisma ارجحیت دارد.

پایگاه های داده / خدمات ابری

خدماتی مانند Airtable در فضای Jamstack بسیار محبوب هستند (من خودم خیلی از آن استفاده کرده ام)، آنها یک پایگاه داده (مانند پلت فرم) را در اختیار شما قرار می دهند که می توانید از طریق REST API به آن دسترسی داشته باشید. استفاده از آنها و نمونه سازی با آنها بسیار سرگرم کننده است، با این حال، Prisma مسلماً انتخاب بهتری برای پروژه های Jamstack است.

اولا، با توجه به اینکه هزینه عامل اصلی جذابیت Jamstack است، ممکن است بخواهید از برخی از این خدمات اجتناب کنید. به عنوان مثال، در هک کلاب، ماه گذشته 671.54 دلار برای اشتراک Airtable Pro برای تیم کوچک خود خرج کردیم.

از سوی دیگر، میزبانی یک پایگاه داده معادل PostgreSQL در پلتفرم Heroku ماهانه 9 دلار هزینه دارد. مطمئناً استدلالی برای این خدمات ابری بر اساس UI و API آنها وجود دارد، اما من به شما با اشاره به استودیو Prisma و کلاینت جاوا اسکریپت / TypeScript فوق الذکر پاسخ خواهم داد.

سرویس‌های ابری نیز از یک مشکل عملکرد رنج می‌برند، به ویژه با توجه به اینکه شما به عنوان کاربر توانایی تغییر/بهبود عملکرد را ندارید. سرویس‌های ابری که پایگاه داده را ارائه می‌کنند، واسطه‌ای را بین برنامه شما و پایگاه داده‌ای که از آن استفاده می‌کنند، قرار می‌دهند و سرعت رسیدن شما به پایگاه داده را کاهش می‌دهد. با این حال، با Prisma شما در حال برقراری تماس مستقیم با پایگاه داده خود از برنامه خود هستید که زمان درخواست / اصلاح پایگاه داده را کاهش می دهد.

نوشتن SQL خالص

بنابراین، اگر می‌خواهیم مستقیماً به پایگاه داده PostgreSQL خود دسترسی پیدا کنیم، چرا فقط از ماژول node-postgres یا – برای بسیاری از پایگاه‌های داده دیگر – از درایورهای معادل آن استفاده نکنیم؟ من استدلال می‌کنم که تجربه توسعه‌دهنده از استفاده از مشتری Prisma ارزش کمی افزایش بار را دارد.

جایی که پریسما با تایپ هایش می درخشد. ماژول تولید شده برای شما توسط Prisma کاملاً ایمن است – انواع طرحواره Prisma شما را تفسیر می کند – که به شما کمک می کند از خطاهای نوع در پایگاه داده خود جلوگیری کنید. علاوه بر این، برای پروژه هایی که از TypeScript استفاده می کنند، Prisma به طور خودکار تعاریف نوع را ایجاد می کند که ساختار مدل شما را منعکس می کند. Prisma از این انواع برای تایید پرس و جوهای پایگاه داده در زمان کامپایل استفاده می کند تا مطمئن شود که آنها از نظر نوع ایمن هستند.

حتی اگر از TypeScript استفاده نمی کنید، Prisma از طریق پسوند Visual Studio Code خود، تکمیل خودکار/حس هوشمند، لنتینگ و قالب بندی را نیز ارائه می دهد. همچنین افزونه‌های ساخته‌شده/نگهداری برای Emacs (حالت emacs-prisma)، neovim (coc-prisma)، Jetbrains IDE (پشتیبانی Prisma) و nova (افزونه Prisma) وجود دارند که سرور زبان Prisma را برای دستیابی به اعتبار کد پیاده‌سازی می‌کنند. برجسته سازی نحو نیز برای طیف وسیعی از ویرایشگران از طریق افزونه ها در دسترس است.

سایر ORM ها

البته Prisma تنها ORM موجود برای JavaScript / TypeScript نیست. به عنوان مثال، TypeORM یکی دیگر از ORM های با کیفیت بالا برای پروژه های جاوا اسکریپت است. و در این مورد، این به ترجیحات شخصی بستگی دارد، و من شما را تشویق می کنم که طیف وسیعی از ORM ها را امتحان کنید تا مورد علاقه خود را پیدا کنید. من شخصا Prisma را برای استفاده در پروژه خود به سه دلیل انتخاب می کنم: مستندات گسترده (به خصوص این صفحه CRUD، که یک نجات دهنده است)، ابزار اضافی در اکوسیستم Prisma (به عنوان مثال Prisma Migrate و Prisma Studio)، و جامعه فعال اطراف ابزار (به عنوان مثال Prisma Day و Prisma Slack).

استفاده از Prisma در پروژه های Jamstack

بنابراین، اگر من به دنبال استفاده از Prisma در یک پروژه Jamstack هستم، چگونه این کار را انجام دهم؟

Next.js

Next.js در حال تبدیل شدن به یک چارچوب بسیار محبوب در فضای Jamstack است و Prisma برای آن مناسب است. مثال‌های زیر به‌عنوان نمونه‌های بسیار استانداردی هستند که می‌توانید با استفاده از ابزارهای مختلف JavaScript / TypeScript Jamstack به پروژه‌های دیگر منتقل کنید.

قانون اصلی استفاده از Prisma در Next.js این است که باید در تنظیمات سمت سرور استفاده شود، به این معنی که می توان از آن در getStaticProps، getServerSidePropsو در مسیرهای API (مثلا api/emojis.js).

در کد، به این شکل است (مثال از یک برنامه آزمایشی گرفته شده است من برای سخنرانی در Prisma Day 2021 که یک دیوار برچسب مجازی بود، صحبت کردم):

import prisma from '../../../lib/prisma'
import { getSession } from 'next-auth/client'

function getRandomNum(min, max) {
  return Math.random() * (max - min) + min
}

export async function getRedemptions(username) {
  let allRedemptions = await prisma.user.findMany({
    where: {
      name: username,
    },
    select: {
      Redemptions: {
        select: {
          id: true,
          Stickers: {
            select: { nickname: true, imageurl: true, infourl: true },
          },
        },
        distinct: ['stickerId'],
      },
    },
  })
  allRedemptions = allRedemptions[0].Redemptions.map(x => ({
    number: getRandomNum(-30, 30),
    ...x.Stickers,
  }))
  return allRedemptions
}

export default async function RedeemCodeReq(req, res) {
  let data = await getRedemptions(req.query.username)
  res.send(data)
}

همانطور که می بینید، به خوبی با پروژه Next.js ادغام می شود. اما ممکن است متوجه چیز جالبی شوید: '../../../lib/prisma'. قبلاً پریسما را به این صورت وارد می کردیم:

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

متأسفانه، این به دلیل یک ابهام در سیستم تازه سازی زنده Next.js است. بنابراین، Prisma به شما توصیه می کند که چسب بزنید این قطعه کد در یک فایل و کد را در هر فایل وارد کنید.

ردوود

Redwood در این بخش کمی ناهنجار است، زیرا لزوماً یک چارچوب Jamstack نیست. زیر پرچم آوردن کامل استک به Jamstack شروع شد اما به الهام گرفتن از Jamstack تبدیل شد. با این حال، من تصمیم گرفتم آن را در اینجا قرار دهم، زیرا رویکرد جالبی برای گنجاندن Prisma در چارچوب دارد.

مانند همیشه، با ایجاد یک طرحواره Prisma، این بار در شروع می شود api/db/schema.prisma (Redwood این را به هر پروژه جدید اضافه می کند). با این حال، برای پرس و جو و اصلاح پایگاه داده، از مشتری پیش فرض Prisma استفاده نمی کنید. در عوض، در Redwood، از جهش‌ها و کوئری‌های GraphQL استفاده می‌شود. به عنوان مثال، در مثال برنامه Redwood todo، این جهش GraphQL است که برای ایجاد یک todo جدید استفاده می شود:

const CREATE_TODO = gql`
  mutation AddTodo_CreateTodo($body: String!) {
    createTodo(body: $body) {
      id
      __typename
      body
      status
    }
  }
`

و در این مورد، مدل Prisma برای یک todo به صورت زیر است:

model Todo {
  id     Int    @id @default(autoincrement())
  body   String
  status String @default("off")
}

برای ایجاد جهش GraphQL، از useMutation تابعی که مبتنی بر کلاینت GraphQL Apollo است که از آن وارد شده است @redwoodjs/web:

const [createTodo] = useMutation(CREATE_TODO, {
    //  Updates Apollo's cache, re-rendering affected components
    update: (cache, { data: { createTodo } }) => {
      const { todos } = cache.readQuery({ query: TODOS })
      cache.writeQuery({
        query: TODOS,
        data: { todos: todos.concat([createTodo]) },
      })
    },
  })

  const submitTodo = (body) => {
    createTodo({
      variables: { body },
      optimisticResponse: {
        __typename: 'Mutation',
        createTodo: { __typename: 'Todo', id: 0, body, status: 'loading' },
      },
    })
  }

با Redwood، پس از ایجاد طرح Prisma خود نیازی به تنظیم طرح GraphQL / SDL ندارید، زیرا می توانید از Redwood استفاده کنید. scaffold دستور تبدیل طرح Prisma به GraphQL SDL و سرویس – yarn rw g sdl Todo، مثلا.

کارگران Cloudfare

Cloudfare Workers یک پلت فرم محبوب برای میزبانی API های Jamstack است، زیرا کد شما را در لبه قرار می دهد. با این حال، این پلتفرم محدودیت‌هایی دارد، از جمله عدم پشتیبانی TCP، که کلاینت سنتی Prisma از آن استفاده می‌کند. اگرچه اکنون از طریق Prisma Data Proxy این امکان وجود دارد.

برای استفاده از آن، به یک پلتفرم ابری Prisma حساب کاربری که در حال حاضر رایگان است. هنگامی که فرآیند راه اندازی را دنبال کردید (اطمینان حاصل کنید که Prisma Data Proxy را فعال کرده اید)، یک رشته اتصال به شما ارائه می شود که با prisma://. می توانید از رشته اتصال Prisma در خود استفاده کنید .env فایل به جای URL پایگاه داده سنتی:

DATABASE_URL="prisma://aws-us-east-1.prisma-data.com/?api_key=•••••••••••••••••"

و سپس، به جای استفاده از npx prisma generate، از این دستور برای ایجاد یک مشتری Prisma استفاده کنید:

PRISMA_CLIENT_ENGINE_TYPE=dataproxy npx prisma generate

درخواست های پایگاه داده شما از طریق پروکسی انجام می شود و می توانید طبق معمول از Prisma Client استفاده کنید. این یک راه‌اندازی کامل نیست، اما برای کسانی که به دنبال اتصالات پایگاه داده در Cloudfare Workers هستند، راه‌حل نسبتا خوبی است.

نتیجه

برای جمع بندی، اگر به دنبال راهی برای اتصال برنامه های Jamstack با پایگاه داده هستید، من بیشتر از Prisma نگاه نمی کنم. تجربه توسعه‌دهنده، ابزارهای گسترده و عملکرد آن را به انتخابی عالی تبدیل کرده است. Next.js، Redwood و Cloudfare Workers – هر یک از آنها روش منحصر به فردی برای استفاده از Prisma دارند، اما هنوز در همه آنها بسیار خوب کار می کند.

امیدوارم از کاوش پریسما با من لذت برده باشید. متشکرم!

مطالعه بیشتر در مجله Smashing

سرمقاله Smashing
(vf، yk، il)