Новое:Talanto осенью: фильтры с числами, отклик по шагам и каталог компаний

+1 183новые вакансии за сутки·93 833вакансии открыты сейчас·Новое:Talanto осенью: фильтры с числами, отклик по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании7 273
РезюмеAIПодготовкаСтатьи
BoostТарифыBoost
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: фильтры с числами, отклик по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 409 кандидатов открыты к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python17 230
  • Облачные технологии14 171
  • QA вакансии3 456
  • Backend вакансии2 115
  • Инженер данных1 801
  • Продакт-менеджер1 247

Разработка

  • Android1 858
  • iOS1 698
  • Fullstack вакансии996
  • AI вакансии955
  • Frontend вакансии755
  • Mobile вакансии44

По стеку

  • Go8 752
  • Java6 593
  • Node.js2 036
  • .NET1 739
  • Kotlin1 618
  • Rust1 472
  • C#717
  • PHP690
  • C++579

DevOps и инфраструктура

  • Kubernetes7 787
  • DevOps вакансии6 095
  • Linux-инфраструктура5 508
  • Terraform / IaC4 287
  • CI/CD3 272
  • Мониторинг и Observability1 792
  • SRE566
  • Кибербезопасность454

Аналитика и данные

  • Data Scientist1 138
  • Бизнес-аналитик921
  • Аналитик данных858
  • Системный аналитик154

Другие направления

  • Проджект-менеджер624
  • UI/UX дизайн149
  • Ручное тестирование14

По регионам

  • Вакансии в США44 166
  • Вакансии в Европе24 014
  • Вакансии в Канаде4 535
  • Работа в России3 867

По формату

  • Удалённые вакансии75 005
  • Релокация в США44 166
  • Гибридная работа12 485
  • Офисная работа7 090

По уровню

  • Senior вакансии42 643
  • Middle вакансии20 960
  • Junior вакансии6 708

Сейчас нанимают

Все компании
  • Wise190 вакансий
  • Rakuten189 вакансий
  • ASML166 вакансий
  • Grab137 вакансий
  • Celonis38 вакансий
  • Spotify37 вакансий
  • Adyen29 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace17 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме PrismaВсе вопросы
PrismaSeniorТеория

Что такое middleware Prisma (устаревший) и расширения Prisma Client (Prisma Client extensions)? Что такое $extends?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

$use (deprecated) перехватывал все запросы через middleware-цепочку. $extends (актуальный, Prisma 4.16+) создаёт новый типобезопасный клиент с расширениями query, result, model и client — поддерживает вычисляемые поля, кастомные методы и перехват операций.

Prisma Middleware ($use) — устаревший подход

До Prisma 4.16 для перехвата запросов использовался prisma.$use() — middleware-функция, получающая params (модель, action, аргументы) и next для вызова следующего обработчика. Начиная с Prisma 5 этот API помечен как deprecated.

// УСТАРЕВШИЙ подход — $use (Prisma 4.x и ниже)
const prisma = new PrismaClient();

prisma.$use(async (params, next) => {
  const before = Date.now();
  const result = await next(params);
  const after = Date.now();
  console.log(`${params.model}.${params.action} took ${after - before}ms`);
  return result;
});

// Soft delete через middleware
prisma.$use(async (params, next) => {
  if (params.model === 'Post' && params.action === 'delete') {
    params.action = 'update';
    params.args.data = { deletedAt: new Date() };
  }
  return next(params);
});

Prisma Client Extensions ($extends) — актуальный подход

$extends — это новый API (GA с Prisma 4.16), который заменяет middleware. Он создаёт новый экземпляр клиента с расширенным поведением и полностью типобезопасен. Поддерживает четыре компонента расширений: model, client, query, result.

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

const prisma = new PrismaClient().$extends({
  // query — перехват запросов (аналог middleware)
  query: {
    post: {
      async delete({ args, query }) {
        // Soft delete вместо физического удаления
        return prisma.post.update({
          where: args.where,
          data: { deletedAt: new Date() },
        });
      },
    },
  },

  // result — вычисляемые поля на уровне типов
  result: {
    user: {
      fullName: {
        needs: { firstName: true, lastName: true },
        compute(user) {
          return `${user.firstName} ${user.lastName}`;
        },
      },
    },
  },

  // model — дополнительные методы к моделям
  model: {
    user: {
      async findByEmail(email: string) {
        return prisma.user.findUnique({ where: { email } });
      },
    },
  },

  // client — методы на уровне самого клиента
  client: {
    async healthCheck() {
      await prisma.$queryRaw`SELECT 1`;
      return true;
    },
  },
});

// Использование вычисляемого поля — fullName типизирован
const user = await prisma.user.findUnique({ where: { id: 1 } });
console.log(user?.fullName); // string | undefined — всё типобезопасно

// Вызов кастомного метода модели
const found = await prisma.user.findByEmail('alice@example.com');

Композиция расширений

// Расширения можно комбинировать цепочкой
const extendedPrisma = new PrismaClient()
  .$extends(loggingExtension)
  .$extends(softDeleteExtension)
  .$extends(tenantExtension);

// Или выносить в отдельные модули и реиспользовать
const loggingExtension = Prisma.defineExtension({
  query: {
    $allModels: {
      async $allOperations({ operation, model, args, query }) {
        const start = performance.now();
        const result = await query(args);
        console.log(`${model}.${operation}: ${performance.now() - start}ms`);
        return result;
      },
    },
  },
});

Подводные камни

  • $extends создаёт новый экземпляр клиента — переменная prisma после .$extends() это не тот же объект, нужно переприсваивать результат.
  • Внутри query расширения нельзя использовать исходный prisma для рекурсивных вызовов — нужно либо использовать query(args), либо аккуратно управлять ссылками.
  • Расширения типа result добавляют поля только в TypeScript-типы, не в БД — данные вычисляются в рантайме на Node.js стороне.
  • Middleware ($use) и $extends нельзя смешивать в одном клиенте — при миграции на расширения нужно полностью переписать middleware.
  • Расширения model не видны в транзакциях ($transaction) — кастомные методы нужно вызывать до входа в транзакцию или передавать клиент отдельно.
  • Prisma.defineExtension нужен для создания реиспользуемых расширений — иначе TypeScript не может правильно вывести тип расширенного клиента в другом файле.
  • Расширения не заменяют database-level триггеры: если нужна атомарность soft delete, лучше использовать базу данных или явные транзакции.

Типичные ошибки

  • Путает Prisma Client API с гарантиями базы данных: индексы, блокировки и isolation level не создаются магически.
  • Не объясняет, где в lifecycle находится устаревший middleware и Client extensions.
  • Не разделяет validation, authorization, business logic и persistence.
  • Игнорирует ошибки, лимиты входных данных, observability и тестирование.

Что проверяет интервьюер

  • Может объяснить устаревший middleware и Client extensions на примере кода.
  • Называет ключевые API: $extends(), $use.
  • Отделяет ORM/query builder поведение от реального поведения СУБД.
  • Видит production-риски: безопасность, отказоустойчивость, логирование и тесты.

Как вы знаете этот вопрос?

Проверить себя по теме Prisma →

Источники

  • https://www.prisma.io/docs/orm/prisma-client/client-extensions
  • https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-to-prisma-7
←Предыдущий вопросВ чём разница между `findUnique`, `findFirst` и `findFirstOrThrow`?Следующий вопрос→Какие типы полей существуют в Prisma и как они маппируются на типы базы данных?

Связанные темы

Prismaapi-designmaintainability

Частые вопросы на собеседовании

  • Как Prisma Client обеспечивает типобезопасность? Как генерируются типы?
  • Что такое транзакции в Prisma? Как использовать prisma.$transaction() для интерактивных и batch-транзакций?
  • Что такое Prisma Migrate? Чем отличаются prisma migrate dev и prisma migrate deploy?
  • Как определить связи один-к-одному, один-ко-многим и многие-ко-многим в Prisma?