← Назад к вопросам

В чем разница между GraphQL и REST?

2.0 Middle🔥 171 комментариев
#JavaScript Core#Архитектура и паттерны#Браузер и сетевые технологии

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В чем разница между GraphQL и REST

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

REST (Representational State Transfer)

REST основан на концепции ресурсов и HTTP методов:

┌──────────────────────────────┐
│   REST API Endpoints         │
├──────────────────────────────┤
│ GET    /users/1              │
│ POST   /users                │
│ PUT    /users/1              │
│ DELETE /users/1              │
│ GET    /posts/1              │
│ GET    /posts/1/comments     │
└──────────────────────────────┘

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

# Получить пользователя и его посты
GET /users/1
GET /posts?userId=1
GET /posts/1/comments

Ответ:

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "createdAt": "2025-01-01",
  "updatedAt": "2025-03-26",
  "role": "admin",
  "settings": { ... }
}

GraphQL

GraphQL даёт клиенту полный контроль над формой данных. Один endpoint для всех запросов:

┌──────────────────────────────┐
│     GraphQL Endpoint         │
├──────────────────────────────┤
│ POST /graphql                │
│                              │
│ Query, Mutation, Subscription│
└──────────────────────────────┘

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

query GetUserAndPosts {
  user(id: 1) {
    id
    name
    email
    posts {
      id
      title
      comments {
        id
        text
      }
    }
  }
}

Ответ (ровно то, что запросили):

{
  "data": {
    "user": {
      "id": "1",
      "name": "Alice",
      "email": "alice@example.com",
      "posts": [
        {
          "id": "101",
          "title": "My First Post",
          "comments": [
            { "id": "1", "text": "Great!" }
          ]
        }
      ]
    }
  }
}

Таблица сравнения

АспектRESTGraphQL
EndpointsМного (для каждого ресурса)Один /graphql
HTTP методыGET, POST, PUT, DELETEТолько POST (или GET)
Избыток данных❌ Часто избыток✅ Точно что нужно
Недостаток данных❌ Нужны N+1 запросов✅ Один запрос
Кеширование✅ Просто (HTTP кеш)❌ Сложнее
Инструментыcurl, PostmanGraphQL IDE (Apollo Sandbox)
Обучение✅ Просто❌ Кривая обучения
Type-safety❌ Нужна доп. типизация✅ Встроенная типизация
Реал-таймWebSocketsSubscriptions (встроены)
ВерсионированиеНужно v1, v2, v3Не нужно

Проблема Overfetching в REST

Сценарий: Нужна только фамилия пользователя

REST:

GET /users/1
{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "phone": "+7-999-123-45-67",
  "createdAt": "2025-01-01",
  "updatedAt": "2025-03-26",
  "role": "admin",
  "settings": { ... },
  "address": { ... }
  // Получили много лишнего!
}

GraphQL:

query {
  user(id: 1) {
    name
  }
}
{
  "data": {
    "user": {
      "name": "Alice"
    }
  }
}

Проблема N+1 в REST

Сценарий: Получить всех пользователей и их посты

REST:

// 1 запрос
const users = await fetch('/users').then(r => r.json());

// N запросов (N+1 проблема!)
const userWithPosts = await Promise.all(
  users.map(user => 
    fetch(`/posts?userId=${user.id}`).then(r => r.json())
  )
);

Всего: 1 + N запросов

GraphQL:

query {
  users {
    id
    name
    posts {
      id
      title
    }
  }
}

Всего: 1 запрос (сервер оптимизирует)

Пример: REST API

// Получение данных в REST
async function getUserData() {
  // 1. Получить пользователя
  const userRes = await fetch('/api/users/1');
  const user = await userRes.json();
  
  // 2. Получить посты пользователя
  const postsRes = await fetch(`/api/posts?userId=1`);
  const posts = await postsRes.json();
  
  // 3. Получить комментарии для каждого поста
  const postsWithComments = await Promise.all(
    posts.map(post => 
      fetch(`/api/posts/${post.id}/comments`)
        .then(r => r.json())
        .then(comments => ({ ...post, comments }))
    )
  );
  
  return { user, posts: postsWithComments };
}

Пример: GraphQL API

// Получение данных в GraphQL
const query = gql`
  query GetUserData {
    user(id: 1) {
      id
      name
      email
      posts {
        id
        title
        comments {
          id
          text
        }
      }
    }
  }
`;

const { data } = await client.query({ query });

Когда использовать REST

REST подходит когда:

  • Простой API с несколькими endpoints
  • Нужна встроенная поддержка кеширования (HTTP кеш)
  • Команда не знакома с GraphQL
  • Вся команда берёт одинаковые данные
  • Публичный API с простой структурой

Когда использовать GraphQL

GraphQL подходит когда:

  • Разные клиенты нуждаются в разных формах данных
  • Много related данных (N+1 проблема в REST)
  • Нужна strong типизация
  • Быстро меняющиеся требования к данным
  • Реал-тайм обновления (subscriptions)
  • Мобильное приложение (минимизация трафика)

Гибридный подход

Многие компании используют ОБА:

┌─────────────────────────────┐
│   GraphQL (основной)        │
│   - Базовые CRUD операции   │
│   - Related данные           │
├─────────────────────────────┤
│   REST (специальные)        │
│   - Файловые операции       │
│   - Платежи                 │
│   - Streaming/большие файлы │
└─────────────────────────────┘

Инструменты

REST:

  • curl, Postman, Insomnia
  • fetch(), axios

GraphQL:

  • Apollo GraphQL
  • GraphQL IDE (Apollo Sandbox, Insomnia)
  • apollo-client, urql
  • Relay

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