برنامه نویسی

🛠 نحوه ساخت مسیرها در یک Node.js API با Fastify و Prisma

در ادامه از پست قبلی 🚀 نحوه راه اندازی یک Node.js API با Fastify و Prisma ، بیایید اولین مسیر خود را کدگذاری کنیم.

تنظیم مشتری Prisma

اول ، ما باید یک مشتری PRISMA ایجاد کنیم که برای تعامل با پایگاه داده ما استفاده شود. در داخل /src/lib دایرکتوری ، یک پرونده به نام ایجاد کنید prisma.ts و کد زیر را اضافه کنید:

import { PrismaClient } from "@prisma/client";

export const prisma = new PrismaClient();
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

سازماندهی مسیرها

بعد ، پوشه ای به نام ایجاد کنید routes درون /srcبشر در داخل /routes، یک پوشه دیگر به نام ایجاد کنید users، جایی که ما تمام عملکردهای مرتبط با کاربر را ذخیره خواهیم کرد.

اولین پرونده ما در داخل این پوشه خواهد بود create.tsبشر واردات مورد نیاز برای این پرونده عبارتند از:

import bcrypt from "bcrypt";
import type { FastifyInstance } from "fastify";
import { ZodTypeProvider } from "fastify-type-provider-zod";
import z from "zod";
import { prisma } from "../../lib/prisma"; // our newly defined client
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

از bcrypt، تمام مسیرهای ما این کتابخانه های اصلی را از Fastify ، Zod و Prisma وارد می کنند.

تعریف مسیر

تعریف عملکرد شامل مسیر مسیر HTTP ، برخی از جزئیات مستندات و یک طرحواره ZOD برای اعتبارسنجی ورودی است. در اینجا به نظر می رسد:

export async function createAccount(app: FastifyInstance) {
  app.withTypeProvider<ZodTypeProvider>().post(
    "/users",
    {
      schema: {
        summary: "Create account",
        tags: ["users"],
        body: z.object({
          name: z.string(),
          username: z.string().min(4),
          email: z.string().email(),
          password: z.string().min(8).max(32),
          bio: z.string().optional(),
        }),
      },
    },
    async (request, reply) => {
      // The next part will be placed here
    }
  );
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ZOD ابزارهای قدرتمندی را برای تعیین قوانین اعتبار سنجی فراهم می کند ، و اطمینان می دهد که API ما فقط داده های فرمت شده درست را می پذیرد.

اجرای منطق مسیر

در داخل عملکرد ، ما باید داده های درخواست را بازیابی کنیم ، رمز عبور را هش دهیم و کاربر را در پایگاه داده ذخیره کنیم:

const { name, username, email, password, bio } = request.body;

const hashedPassword = await bcrypt.hash(password, 10);
const user = await prisma.user.create({
  data: {
    name,
    username,
    email,
    password: hashedPassword,
    bio,
  },
});

return reply.status(201).send({ userId: user.id });
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ثبت مسیر در سرور

اکنون که مسیر ما ایجاد شده است ، ما باید آن را وارد کنیم server.ts بنابراین می توان از آن استفاده کرد.

در آغاز server.ts پرونده ، اضافه کنید:

import { createAccount } from "./routes/users/create";
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

سپس مسیر را قبل از app.listen تماس:

app.register(createAccount);
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون ، صفحه Swagger را بارگیری مجدد کنید و مسیر باید به طور خودکار فهرست بندی شود. علاوه بر مستندات ، می توانید مسیر خود را با کلیک بر روی “امتحان کن” دکمه و ویرایش بدن. اگر مراحل را به درستی دنبال کردید ، مسیر شما باید کار کند!


ایجاد مسیر برای لیست کاربران

برای لیست همه کاربران ثبت شده ، یک فایل جدید به نام ایجاد کنید list.ts در داخل /src/routes/users پوشه و کد زیر را اضافه کنید:

import type { FastifyInstance } from "fastify";
import { ZodTypeProvider } from "fastify-type-provider-zod";
import { prisma } from "../../lib/prisma";

export async function listAllUsers(app: FastifyInstance) {
  app.withTypeProvider<ZodTypeProvider>().get(
    "/users",
    {
      schema: {
        summary: "List all the registered users",
        tags: ["users"],
      },
    },
    async (request, reply) => {
      const users = await prisma.user.findMany({
        select: {
          id: true,
          name: true,
          username: true,
          email: true,
          bio: true,
          createdAt: true,
        },
      });
      return reply.send({ users });
    }
  );
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

توجه:

این طرح در اینجا شبیه به یکی برای ایجاد یک حساب است ، اما ساده تر است. ما از Prisma استفاده می کنیم findMany() روش با select گزینه ای برای بازیابی فقط زمینه های خاص از پایگاه داده. می توانید این مورد را در صورت لزوم فیلتر یا قالب بندی کنید.

این مسیر را در خود ثبت کنید server.ts و آن را بر روی UI swagger آزمایش کنید.


به روزرسانی یک کاربر

بعد ، پرونده ای به نام ایجاد کنید update.ts در همان پوشه (/src/routes/users) با کد زیر:

import bcrypt from "bcrypt";
import type { FastifyInstance } from "fastify";
import { ZodTypeProvider } from "fastify-type-provider-zod";
import z from "zod";
import { prisma } from "../../lib/prisma";

export async function updateUser(app: FastifyInstance) {
  app.withTypeProvider<ZodTypeProvider>().put(
    "/users/:userId",
    {
      schema: {
        summary: "Update user",
        tags: ["users"],
        params: z.object({
          userId: z.string().uuid(),
        }),
        body: z.object({
          name: z.string().optional(),
          username: z.string().min(4).optional(),
          email: z.string().email().optional(),
          password: z.string().min(8).max(32).optional(),
          bio: z.string().optional(),
        }),
      },
    },
    async (request, reply) => {
      const { userId } = request.params;
      let { password } = request.body;

      if (password) {
        password = await bcrypt.hash(password, 10);
      }
      const user = await prisma.user.update({
        where: { id: userId },
        data: {
          ...request.body,
          password, // will be undefined if not provided
        },
      });

      return reply.status(200).send({ userId: user.id });
    }
  );
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

نکات کلیدی:

  1. روش HTTP و پارامترهای URL:
    ما از روش PUT استفاده می کنیم و یک پارامتر URL را درج می کنیم (:userId) ، که توسط ZOD در params طرحواره
  2. زمینه های اختیاری:
    همه قسمت های بدن اختیاری هستند زیرا کاربر ممکن است فقط زیر مجموعه ای از قسمت ها را به روز کند.
  3. رمزگذاری رمز عبور:
    اگر یک رمز عبور جدید ارائه شود ، قبل از به روزرسانی رکورد هشدار داده می شود.
  4. اپراتور گسترش:
    اپراتور گسترش (...request.body) به استثنای رمز عبور که به طور جداگانه اداره می شود ، برای عبور از تمام قسمت ها استفاده می شود.

این مسیر را در خود ثبت کنید server.ts و آن را از طریق swagger آزمایش کنید.


حذف کاربر

سرانجام ، برای تکمیل عملیات CRUD ، پرونده ای به نام ایجاد کنید delete.ts در /src/routes/users پوشه با کد زیر:

import type { FastifyInstance } from "fastify";
import { ZodTypeProvider } from "fastify-type-provider-zod";
import { prisma } from "../../lib/prisma";
import z from "zod";

export async function deleteUser(app: FastifyInstance) {
  app.withTypeProvider<ZodTypeProvider>().delete(
    "/users/:userId",
    {
      schema: {
        summary: "Delete user by id",
        tags: ["users"],
        params: z.object({
          userId: z.string().uuid(),
        }),
      },
    },
    async (request, reply) => {
      const { userId } = request.params;
      const user = await prisma.user.delete({
        where: { id: userId },
      });

      return reply.send({ user });
    }
  );
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

توجه:

این مسیر از همان الگوی دیگر پیروی می کند – تنها تفاوت روش حذف HTTP. آن را در سرور خود ثبت کنید و آن را در Swagger تست کنید.


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

به عنوان شما server.ts پرونده رشد می کند ، وارد کردن هر مسیر به صورت جداگانه می تواند آن را کثیف جلوه دهد. برای بهبود سازمان ، ایجاد یک index.ts پرونده در داخل /src/routes/users پوشه:

import type { FastifyInstance } from "fastify";
import { ZodTypeProvider } from "fastify-type-provider-zod";
import { createAccount } from "./create";
import { listAllUsers } from "./list";
import { updateUser } from "./update";
import { deleteUser } from "./delete";

export async function userRoutes(app: FastifyInstance) {
  const typedApp = app.withTypeProvider<ZodTypeProvider>();
  typedApp.register(createAccount);
  typedApp.register(listAllUsers);
  typedApp.register(updateUser);
  typedApp.register(deleteUser);
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون ، در خود server.ts، به جای ثبت هر مسیر به طور جداگانه ، ادغام شده را وارد و ثبت کنید userRoutes عملکرد:

import { userRoutes } from "./routes/users";

app.register(userRoutes);
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این تنظیم به سازماندهی کد شما و شما کمک می کند server.ts پرونده تمیز


با وجود همه این مسیرها و ثبت نام ، API شما اکنون از ایجاد ، لیست ، به روزرسانی و حذف کاربران پشتیبانی می کند. تمام مسیرها را از طریق UI Swagger در http: // localhost: 3333/docs آزمایش کنید.


پایان

اکنون ما مهمترین ویژگی ها را پوشش داده ایم ، عملکردهای CRUD و برخی از بهترین شیوه ها را پوشش داده ایم. با این حال ، پیشرفت های احتمالی بسیاری وجود دارد که می تواند در نسخه های آینده انجام شود. به روزرسانی ها را در اینجا و در مخزن پروژه دنبال کنید: GitHub – Micaelmi/blog.Next مرحله اجرای احراز هویت و حفاظت از مسیر است ، با ما همراه باشید!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا