Как создать простое API? Express + Prisma

от автора

Инициализация проекта на express и установка требуемых библиотек::

npm init -y npm i express body-parser jsonwebtoken nodemon dotenv pg argon2 cookie-parser

Меняем в package.json: нужно добавить type и скрипт dev

  "main": "index.js",   "type": "module",   "scripts": {     "dev": "nodemon app.js"   },

Создаем app.js в корневой папке

Базовая структура проекта

Базовая структура проекта

Скачиваем Prisma и инициализируем её через консоль:

npm i prisma @prisma/client npx prisma init 

Далее нужно заполнить schema.prisma моделями сущностей. Для этого вы можете изучить статью Обзор Prisma ORM: как забыть об SQL и сосредоточиться на данных. Вот мой пример:

generator client {   provider = "prisma-client-js"   // Тут будет output, его нужно удалить }  datasource db {   provider = "postgresql"   url      = env("DATABASE_URL") }  model Users {   id Int @id @default(autoincrement())   phone String @unique //УНИКАЛЬНОЕ ХНАЧЕНИЕ(КОГДА НЕ МОЖЕТ ПОВТОРЯТЬСЯ)   name String      applications Applications[] }  model Doctors{   id Int @id @default(autoincrement())   name String   surname String   patronymic String? //опционально, если не обязательное значение    specialization String    applications  Applications[] // привязка к другой модели (даём "разрешение") }  model Applications { // для записей с интервалом 30 мин с 10 до 20   id Int @id @default(autoincrement())   doctorid Int    date DateTime   date DateTime   userid Int?    doctor Doctors @relation(fields: [doctorid], references: [id]) //делаем связь   user Users? @relation(fields: [userid], references: [id])//делаем опциональную связь }

После этого нужно добавить изменения в файл .env:

DATABASE_URL="postgresql://postgres:1234@localhost:5432/cat?schema=public"

Теперь у нас готова базовая настройка Prisma, поэтому нам нужно создать миграции. Миграции — это контролируемый набор изменений, которые изменяют структуру базы данных. Они помогают переводить схему базы данных из одного состояния в другое, например, создавать или удалять таблицы и столбцы, разделять поля в таблице или добавлять типы и ограничения.

npx prisma migrate dev --name init npx prisma db push

Если в schema.prisma были добавлены изменения, то нужно сделать ряд функций:

npx prisma migrate reset // Удаление данных в бд npx prisma migrate dev // Создание миграции npx prisma db push // Добавление таблиц в бд

(Если нужно отслеживать изменения в бд, можно использовать prisma studio)

Итоговая структура проекта

Итоговая структура проекта

Создаём client.js и пишем там подключение к бд:

// Связь с бд, для получения, добавления, изменения и удаления данных в бд import { PrismaClient } from "../generated/prisma/index.js";  const prisma = new PrismaClient();   export default prisma;

Теперь заполняем app.js:

//создаем приложение import express from "express"; import router from './route/index.js'  const app = express() //сохранения экспресс переменную app.use(express.json()) //подключение джисон вывода  BigInt.prototype.toJSON = function() { return this.toString() } // Конвертирует bigint в строку  app.use('/api', router); // Нужно добавить позже  app.listen(3000, () => { //ОТВЕЧАЕТ ЗА ЗАПУСК СЕРВЕРА     console.log('http://localhost:3000') //вывод пути сервера  })  process.on('SIGINT', async () => {   await prisma.$disconnect()   process.exit(0) }) //останавливает работу бд, когда отключаешься от сервера

Для запуска сервера пишем npm run dev. Заполняем файлы для каждой модели по очередности: сервис, контролер, роутер.

Пишем сервис для доктора (doctor.service.js). Подробнее можно прочитать в статье Prisma ORM: полное руководство для начинающих (и не только). Часть 1:

import prisma from '../../prisma/clinet.js' // импортируем призму  class DoctorService { //создание класса, где хранятся методы, которые изменяют бд     async getAll() {         return await prisma.doctors.findMany(); //возвращает всех докторов     }     async getOneById(id) {         return await prisma.doctors.findUnique({             where: {                 id             }         }); //возвращает одного доктора по ID     }     async create(name, surname, patronymic, specialization) {         return await prisma.doctors.create({             data:{                 name,                  surname,                  patronymic,                  specialization             }         }); //cоздание докторов     }     async update(id, name, surname, patronymic, specialization) {         const doctor = this.getOneById(id);         if (!doctor)             return "такого доктора нет"          return await prisma.doctors.update({             data: {                 name: name ? name : doctor.name,                 surname,                 patronymic,                  specialization             },             where:{                  id             }         }); //обновление докторов     }     async delete(id) {         return await prisma.doctors.delete({             where:{                 id             }         }); //удаляет доктора по айди     }      }  export default new DoctorService();

Далее заполняет контролер доктора (doctor.controller.js):

import DoctorService from "./doctor.service.js";  class DoctorController {     async getAllDoctors(req, res) {         try {             const doctors = await DoctorService.getAll();              return res.json(doctors);         } catch (err) {             console.error(err);             return res.status(500).json({ error: err.message });         }     }      async getOneDoctors(req, res) {         try {             const id = req.params.id;             const doctors = await DoctorService.getOneById(id);              return res.json(doctors);         } catch (err) {             console.error(err);             return res.status(500).json({ error: err.message });         }     }      async createDoctor(req, res) {         try {             const {name, surname, patronymic, specialization} = req.body;             const doctors = await DoctorService.create(name, surname, patronymic, specialization);              return res.json(doctors);         } catch (err) {             console.error(err);             return res.status(500).json({ error: err.message });         }     }      async updateDoctor(req, res) {         try {             const id = req.params.id;             const {name, surname, patronymic, specialization} = req.body;             const doctors = await DoctorService.update(id, name, surname, patronymic, specialization);              return res.json(doctors);         } catch (err) {             console.error(err);             return res.status(500).json({ error: err.message });         }     }       async deleteDoctor(req, res) {         try {             const id = req.params.id;             const doctors = await DoctorService.update(id);              return res.json(doctors);         } catch (err) {             console.error(err);             return res.status(500).json({ error: err.message });         }     }           }  export default new DoctorController();

Дальше заполняем маршрут доктора (doctor.router.js):

import express from 'express' import DoctorController from './doctor.conroller.js';  const doctorRouter = express.Router() //сохранение метода роутер в переменную  doctorRouter.get('/getall', DoctorController.getAllDoctors) doctorRouter.get('/get/:id', DoctorController.getOneDoctors) doctorRouter.post('/post', DoctorController.createDoctor) doctorRouter.put('/put/:id', DoctorController.updateDoctor) doctorRouter.delete('/delete/:id', DoctorController.deleteDoctor)  // doctorRouter.post('/create')  export default doctorRouter;

Также заполняем остальные модели.

И после того, как мы все заполнили, мы идем в route, а там в index.js:

import express from 'express' import doctorRouter from '../models/doctor/doctor.router.js'; // импортитуем маршруты доктора import userRouter from '../models/user/user.router.js'; // испортируем маршруты пользователей import apllicationsRouter from '../models/applications/applications.router.js';  const router = express.Router() // объявление переменной маршрута  router.use('/doctor', doctorRouter); // маршруты доктора router.use('/user', userRouter); // маршруты пользователя router.use('/apllication', apllicationsRouter); // маршруты заявок  export default router;

После этого мы добавляем app.use(‘/api’, router)  (это было выше)

После всех манипуляция наша структура может выглядеть вот так:

Вот ещё примеры сервиса, контроллера и роутера:

В application.service.js мы пишем:

import prisma from '../../prisma/clinet.js' // импортируем призму import doctorService from '../doctor/doctor.service.js';  class ApplicationsService { //создание класса, где хранятся методы, которые изменяют бд     async createApplication(userId, doctorId, day, month, year, time) {         const doctor = doctorService.getOneById(userId);         if (!doctor)             return "Такого доктора нет";          return prisma.applications.create({             data: {                 userid: userId,                 doctorid: doctorId,                 date: new Date(year, month, day)             }         })     } }  export default new ApplicationsService();

В application.controller.js контролер:

import applicationsService from "./applications.service.js";  class ApllicationsController {           async createApplications(req, res) {         try {             const {userid, doctorid, day, month, year, time} = req.body;             const application = await applicationsService.create(userid, doctorid, day, month, year, time);              return res.json(application);         } catch (err) {             console.error(err);             return res.status(500).json({ error: err.message });         }        }      } export default new ApllicationsController();

В application.router.js:

import express from 'express' import applicationsController from './applications.controller.js';  const apllicationsRouter = express.Router() //сохранение метода роутер в переменную  apllicationsRouter.post('/post', applicationsController.createApplications)  export default apllicationsRouter;

Наше API готово! Если остались вопросы по оформлению, то можете почитать следующие статьи:

Understanding Express Routes, Controllers, and Services — DEV Community

Building REST APIs with Prisma ORM | Prisma Documentation


ссылка на оригинал статьи https://habr.com/ru/articles/920606/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *