Гид по технологиям

GraphQL с MongoDB: пошаговое руководство по созданию API на Apollo Server

8 min read API Обновлено 29 Dec 2025
GraphQL + MongoDB: Apollo Server шаги
GraphQL + MongoDB: Apollo Server шаги

Открытый ноутбук, на экране которого кто-то печатает код в текстовом редакторе

О чём этот материал

Этот текст объясняет, почему GraphQL часто эффективнее чем REST, и подробно показывает, как шаг за шагом настроить локальный сервер GraphQL с использованием Apollo Server и MongoDB. Включены готовые файлы кода, рекомендации по безопасности, варианты тестирования и список типичных ошибок.

Почему выбор архитектуры API важен

При проектировании приложения тип архитектуры API — один из ключевых факторов. От него зависит производительность, масштабируемость и простота развития приложения. В REST у вас обычно много конечных точек и фиксированные ответы, что иногда приводит к избыточной передаче данных. GraphQL предлагает единый вход и позволяет клиенту запрашивать ровно те поля, которые нужны.

Что такое GraphQL API?

GraphQL — это язык запросов и спецификация для построения API. В отличие от REST, где много эндпойнтов, GraphQL предоставляет одну точку входа. Клиент указывает, какие именно данные ему нужны, а сервер возвращает только запрошенные поля.

Иллюстрация двух веб-серверов, развернутых в сети

Кратко: GraphQL API реализует архитектуру, описанную спецификацией GraphQL — вы определяете схему, операции Query и Mutation, а также резолверы, которые выполняют логику получения и изменения данных.

Основные компоненты GraphQL API:

  • Схема (Schema): описание типов данных и операций, которые предоставляет API. Схема определяет структуру доступных данных и набор запросов и мутаций.
  • Query: операции чтения данных. Клиент формирует запрос, указывая структуру возвращаемых данных.
  • Mutation: операции изменения данных (создание, обновление, удаление).
  • Резолверы (Resolvers): функции, которые получают запросы и возвращают реальные данные из источника (БД, внешние API и т.д.).

Подготовка MongoDB

Перед началом создайте базу данных MongoDB локально или в облаке (например, MongoDB Atlas предоставляет бесплатный уровень). Скопируйте строку подключения (connection URI) — она понадобится для подключения приложения.

Если вы используете локальную установку, стандартный URI выглядит примерно так: mongodb://localhost:27017. Для облачного кластера URI будет включать имя пользователя, пароль и параметры подключения.

Важно: храните чувствительные строки подключения в переменных окружения, а не в коде.

Структура проекта — что мы создадим

Рекомендуемая структура проекта:

  • /graphql
    • typeDefs.js
    • resolvers.js
  • /models
    • employeeModel.js
  • index.js
  • package.json

Эта структура простая и подходит для небольших сервисов и учебных приложений.

Создание сервера Apollo

Apollo Server — популярная реализация GraphQL-сервера для Node.js. Ниже шаги по созданию проекта.

Откройте терминал и создайте директорию проекта, затем перейдите в неё:

mkdir graphql-API-mongoDB
cd graphql-API-mongoDB

Инициализируйте новый проект Node.js:

npm init --yes

Установите зависимости:

npm install apollo-server graphql mongoose

Создайте файл index.js в корне проекта.

Настройка Apollo Server и подключения к MongoDB

Откройте index.js и добавьте следующий код (убедитесь, что вы правильно настроили пути к typeDefs и resolvers в проекте):

const { ApolloServer } = require('apollo-server');
const mongoose = require('mongoose');
const typeDefs = require("./graphql/typeDefs");
const resolvers = require("./graphql/resolvers");

const server = new ApolloServer({
  typeDefs,
  resolvers
});

const MONGO_URI = 'mongodb://localhost:27017';

mongoose
  .connect(MONGO_URI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
  .then(() => {
    console.log(`Db Connected`);
    return server.listen({ port: 5000 });
  })
  .then((res) => {
    console.log(`Server running at ${res.url}`);
  })
  .catch(err => {
    console.log(err.message);
  });

Этот код инициализирует Apollo Server и подключается к MongoDB. После успешного подключения сервер начнёт слушать порт 5000.

Совет: в production указывайте порт и MONGO_URI через переменные окружения (process.env).

Определение модели данных (Mongoose)

Создайте папку models и файл employeeModel.js (в исходном материале файл назывался dataModel.js; здесь используем более явное имя).

В файле добавьте:

const { model, Schema } = require('mongoose');

const employeeSchema = new Schema({
  name: String,
  department: String,
  salary: String,
});

module.exports = model('Employee', employeeSchema);

Объяснение: это простая модель сотрудника с полями name, department и salary. При необходимости расширяйте схему — добавляйте валидацию, индексирование, таймстемпы.

Определение схемы GraphQL

Схема описывает типы данных, входные типы, запросы и мутации. Создайте папку graphql и файлы typeDefs.js и resolvers.js.

В typeDefs.js добавьте:

const { gql } = require("apollo-server");

const typeDefs = gql`
  type Employee {
    id: ID!
    name: String
    department: String
    salary: String
  }
  input EmployeeInput {
    name: String
    department: String
    salary: String
  }
  type Query {
    getEmployee(id: ID): Employee
    employees: [Employee]
  }
  type Mutation {
    createEmployee(employeeInput: EmployeeInput): Employee
    updateEmployee(id: ID, employeeInput: EmployeeInput): Boolean
    deleteEmployee(id: ID): Boolean
  }
`;

module.exports = typeDefs;

Пояснение: Query возвращает список сотрудников или одного сотрудника по id. Mutation позволяет создать, обновить или удалить сотрудника.

Реализация резолверов

Резолверы — функции, которые выполняют операции чтения/записи в базе данных. Создайте или откройте файл resolvers.js и добавьте следующий код:

const Employee = require("../models/employeeModel");

const resolvers = {
  Query: {
    employees: async () => {
      try {
        const employees = await Employee.find({});
        return employees;
      } catch (error) {
        console.error(error);
        throw new Error('Failed to fetch employees');
      }
    },
    getEmployee: async (parent, args) => {
      try {
        const employee = await Employee.findById(args.id);
        return employee;
      } catch (error) {
        console.error(error);
        throw new Error('Failed to fetch employee by ID');
      }
    },
  },

  Mutation: {
    async createEmployee(_, { employeeInput: { name, department, salary } }) {
      const newEmployee = new Employee({
        name: name,
        department: department,
        salary: salary
      });

      const response = await newEmployee.save();
      console.log(newEmployee);

      return {
        id: response._id,
        ...response._doc
      };
    },

    async updateEmployee(_, { id, employeeInput: { name, department, salary } }) {
      const updatedEmployee = await Employee.updateOne(
        { _id: id },
        { name, department, salary }
      );

      if (!updatedEmployee) {
        throw new Error(`Employee with ID: ${id} not found`);
      }

      return true;
    },

    async deleteEmployee(_, { id }) {
      const deletedEmployee = await Employee.deleteOne({ _id: id });

      if (!deletedEmployee || deletedEmployee.deletedCount === 0) {
        throw new Error(`Employee with ID ${id} not found`);
      }

      return true;
    },
  },
};

module.exports = resolvers;

Пояснение: резолверы используют Mongoose для операций с MongoDB. Обработку ошибок можно расширить, в частности логирование и разграничение типов ошибок (валидация, авторизация, не найдено).

Запуск сервера и проверка

Запустите сервер командой:

node index.js

После установления соединения с базой вы увидите вывод о запуске сервера и сможете открыть GraphQL Playground по адресу, указанному в консоли (обычно http://localhost:5000/).

В Playground можно выполнять запросы и мутации. Примеры:

Пример мутации createEmployee:

mutation {
  createEmployee(employeeInput: { name: "Иван Иванов", department: "Разработка", salary: "100000" }) {
    id
    name
    department
  }
}

Пример запроса employees:

query {
  employees {
    id
    name
    department
    salary
  }
}

Реализация GraphQL API в браузере с клиентом GraphQL Playground

Лучшие практики и рекомендации

  • Храните конфиденциальные данные (URI, пароли) в переменных окружения.
  • Разделяйте логику резолверов и бизнес-логику — используйте сервисный слой для сложных операций.
  • Добавляйте валидацию входных данных до сохранения в БД.
  • Настройте лимиты и защита от перегрузки: depth limit (ограничение глубины запросов), rate limiting, кеширование.
  • Используйте инструменты мониторинга (логирование, APM) для отслеживания производительности.

Когда GraphQL может не подойти

  • Простые CRUD-приложения с небольшим количеством клиентов и данными — REST может быть проще и понятнее.
  • Если у вас строгие требования к кэшированию на уровне HTTP-ответов (REST + CDN) — GraphQL требует дополнительных настроек для эффективного кэширования.
  • Очень сложное разрешение прав в поле/строке: если нужна детальная авторизация на уровне каждого поля, реализация может усложниться.

Альтернативы и гибридные подходы

  • REST: простота, зрелый экосистема, нативное HTTP-кеширование.
  • gRPC: эффективен для микросервисов и двоичных форматов, низкая латентность.
  • GraphQL + REST: использовать GraphQL как аггрегатор для нескольких REST-сервисов.
  • Использовать BFF (Backend for Frontend) — когда нужен отдельный адаптированный API для разных клиентских приложений.

Ментальные модели и эвристики

  • Single Source of Truth: GraphQL-схема — договор между фронтом и бэком.
  • Запрашивай только нужные поля: чем меньше данных — тем быстрее и дешевле операция.
  • Избегай N+1: при запросах связанных данных используйте DataLoader или агрегации на уровне БД.

Чек-листы по ролям

Разработчик бэкенда:

  • Создана схема GraphQL и резолверы.
  • Добавлена валидация входных данных.
  • Подключено логирование ошибок.
  • Переменные окружения настроены.

Разработчик фронтенда:

  • Согласованы поля схемы с требуемыми данными.
  • Проверены примеры запросов в Playground.
  • Обработаны ошибки и состояния загрузки.

DevOps / SRE:

  • Настроен деплой и мониторинг.
  • Обеспечено резервное копирование БД.
  • Настроено автоматическое масштабирование и лимиты.

QA инженер:

  • Тесты для запросов и мутаций.
  • Проверка ошибки при недопустимом вводе.
  • Проверка поведения при недоступной БД.

Мини-методология развертывания

  1. Локальная разработка: сборка и тестирование в локальной среде с тестовой БД.
  2. CI: настройка тестов (юнит/интеграция) и линтинга в пайплайне.
  3. Staging: деплой в staging с конфигурацией, близкой к продакшену.
  4. Production: постепенный выпуск, мониторинг и откат при инцидентах.

Критерии приёмки

  • Сервер успешно стартует и подключается к базе.
  • Запрос employees возвращает корректные данные.
  • Мутация createEmployee создаёт запись в БД и возвращает ID.
  • Мутации updateEmployee и deleteEmployee корректно изменяют и удаляют записи.

Безопасность и приватность

  • Аутентификация: используйте JWT или другой механизм для идентификации пользователя.
  • Авторизация: проверяйте права доступа в резолверах или в отдельном middleware.
  • Защита от чрезмерных запросов: ограничение глубины запросов и сложных выборок.
  • Логирование: не записывайте чувствительные данные в логи.
  • GDPR/локальные законы: если вы храните личные данные, следуйте требованиям локального законодательства и минимизируйте объём собираемых данных.

Тестовые случаи и приёмка

  • Юнит-тесты для резолверов: мокируйте модель Employee и проверяйте, что резолверы корректно обрабатывают ответы и ошибки.
  • Интеграционные тесты: поднимите тестовую БД и выполняйте реальные запросы через Apollo Server.
  • Нагрузочное тестирование: проверьте поведение при пиковых нагрузках и убедитесь в наличии таймаутов и лимитов.

Ошибки, которые встречаются чаще всего

  • Неправильные пути require (особенно при переименовании файлов).
  • Отсутствующие переменные окружения (MONGO_URI, PORT).
  • N+1 запросы при выборке связанных данных.
  • Сохранение истиных паролей или секретов в репозитории.

Глоссарий в одну строку

  • GraphQL: язык запросов для API, позволяющий клиентам запрашивать только нужные поля.
  • Resolver: функция, которая возвращает данные для поля схемы.
  • Schema: описание типов и операций GraphQL.
  • Mutation: операция изменения данных.
  • Query: операция чтения данных.

Краткое завершение

GraphQL вместе с MongoDB и Apollo Server даёт гибкий и эластичный способ построения API, особенно когда у вас разные клиенты и потребности в данных различаются. Начните с простой схемы и моделей, постепенно добавляя уровни безопасности, оптимизации и тестирования.

Важно помнить: GraphQL — не панацея. Подходите к выбору архитектуры прагматично, учитывая требования проекта и командные компетенции.

Summary:

  • GraphQL уменьшает передачу лишних данных и даёт один вход для разных клиентов.
  • Apollo Server + Mongoose — быстрый способ получить рабочее GraphQL API.
  • Добавляйте валидацию, авторизацию и защиту от злоупотреблений перед релизом.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как удалить резервные копии Time Machine на Mac
macOS

Как удалить резервные копии Time Machine на Mac

Исправить Inaccessible Boot Device в Windows 10
Windows

Исправить Inaccessible Boot Device в Windows 10

Блокировка и разблокировка контактов в Gmail
Электронная почта

Блокировка и разблокировка контактов в Gmail

Импорт дней рождения Facebook в Google Календарь
Инструкции

Импорт дней рождения Facebook в Google Календарь

Как избежать боли в спине при работе из дома
Здоровье

Как избежать боли в спине при работе из дома

Как создать торрент из прямой ссылки — Burnbit
Файлообмен

Как создать торрент из прямой ссылки — Burnbit