Реализация функций чтения (Query) и записи (Mutation)

На прошлом этапе вы создали таблицы в Dashboard. Сейчас они пусты. Чтобы превратить их в работающий стартап, нужно научить приложение читать и записывать данные.

В Convex за это отвечают Серверные функции. Это блоки кода на языке TypeScript, которые работают в облаке. Вам не нужно настраивать свои серверы — Convex берет это на себя, обеспечивая безопасность и скорость.

Query и Mutation: в чем разница?

Вся работа с данными в Convex делится на два типа:

  1. Query (Запрос) — только чтение. Вы просите: «Дай мне список задач» или «Покажи профиль юзера».
  2. Mutation (Мутация) — изменение. Вы приказываете: «Создай задачу», «Удали пост» или «Обнови статус».

Важное ограничение: Внутри Query нельзя менять данные. Это гарантирует, что запросы на чтение всегда будут работать молниеносно.


Пишем первую функцию Query

Все функции бэкенда лежат в папке convex/. Создайте там файл tasks.ts.

Как это выглядит в коде:

import { query } from "./_generated/server";

// Получаем список всех задач
export const getTasks = query({
  handler: async (ctx) => {
    // ctx.db — это ваш прямой доступ к базе данных
    return await ctx.db.query("tasks").collect();
  },
});

Здесь ctx (контекст) — ваш главный инструмент. Через ctx.db вы управляете таблицами.

Совет: Не используйте fetch или axios для работы со своей базой. Инструмент ctx.db встроен в Convex и работает в разы быстрее любых внешних запросов.


Создаем Mutation для записи

Чтобы сохранить данные, используем Mutation. Здесь в дело вступает TypeScript: мы строго описываем, какие данные ждем на вход.

import { mutation } from "./_generated/server";
import { v } from "convex/values";

export const createTask = mutation({
  // Проверяем, что на вход пришла именно строка
  args: { text: v.string() }, 
  handler: async (ctx, args) => {
    const newTaskId = await ctx.db.insert("tasks", { 
      text: args.text, 
      isCompleted: false 
    });
    return newTaskId;
  },
});

Валидация v.string() — это страховка вашего MVP. Если фронтенд случайно отправит число вместо текста, Convex выдаст ошибку еще до того, как «мусор» попадет в базу.


Магия реактивности

Реактивность — киллер-фича Convex.

Вам не нужно обновлять страницу или писать сложный код для синхронизации. Как только Mutation изменит данные в базе, все функции Query на экранах пользователей мгновенно «проснутся» и сами подтянут актуальные значения. Данные просто «текут» от сервера к клиенту без лишних настроек. ⚡️

Проверка в Dashboard

Вы можете протестировать логику, даже не приступая к верстке интерфейса:

  1. Откройте Convex Dashboard.
  2. Перейдите в раздел Functions.
  3. Выберите tasks:getTasks (увидите пустой список) или tasks:createTask.
  4. Введите текст задачи в поле параметров и нажмите Run.

Это самый быстрый способ убедиться, что «мозги» вашего стартапа работают правильно.


Теперь у вашего приложения есть логика, но нет лица. В следующем уроке мы разберем интеграцию функций Convex через React-хуки: соединим бэкенд с Next.js, чтобы пользователи увидели результат вашей работы.