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

Что определяет GraphQL схема?

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

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

GraphQL схема: что она определяет

GraphQL схема — это контракт между клиентом и сервером, который определяет все возможные данные и операции, доступные в API. Это как документация и валидатор одновременно.

Основное назначение GraphQL схемы

GraphQL схема определяет:

  1. Все доступные типы данных (Type definitions)
  2. Структуру данных (fields и их типы)
  3. Возможные запросы (Queries)
  4. Возможные изменения данных (Mutations)
  5. Подписки на события (Subscriptions)
  6. Правила валидации (требуемые поля, скаляры)
  7. Возможности и ограничения API

Пример простой GraphQL схемы

# Определение типа User
type User {
  id: ID!              # ! означает обязательное поле
  name: String!
  email: String!
  age: Int
  posts: [Post!]!      # Массив обязательных Post
  createdAt: DateTime!
}

# Определение типа Post
type Post {
  id: ID!
  title: String!
  content: String
  author: User!        # Связь с User
  comments: [Comment!]!
}

type Comment {
  id: ID!
  text: String!
  author: User!
  post: Post!
}

# Определение возможных запросов (Queries)
type Query {
  user(id: ID!): User              # Получить пользователя по ID
  users(limit: Int = 10): [User!]! # Получить список пользователей
  post(id: ID!): Post
  posts(authorId: ID): [Post!]!
}

# Определение возможных мутаций (Mutations)
type Mutation {
  createUser(name: String!, email: String!): User!
  updateUser(id: ID!, name: String): User
  deleteUser(id: ID!): Boolean!
  createPost(title: String!, content: String!, authorId: ID!): Post!
}

# Подписки на события (Subscriptions)
type Subscription {
  userCreated: User!           # Событие при создании пользователя
  postCommented(postId: ID!): Comment!
}

Что определяет GraphQL схема (детально)

1. Типы данных

Схема определяет все типы данных, которые может вернуть API:

type User {
  id: ID!           # Скалярный тип ID
  name: String!     # Строка
  age: Int          # Целое число
  isActive: Boolean # Boolean
  joinedAt: DateTime # Custom скалярный тип
  email: String!
}

2. Обязательность полей

Восклицательный знак ! указывает, что поле обязательно (никогда не будет null):

# name всегда возвращает значение
name: String!  # OK: "Иван"
               # ОШИБКА: null

# age может быть null
age: Int       # OK: 25
               # OK: null

3. Массивы

Квадратные скобки обозначают массивы:

posts: [Post!]!        # Массив (обязателен), элементы обязательны
posts: [Post]!         # Массив (обязателен), элементы могут быть null
posts: [Post!]         # Массив может быть null, элементы обязательны
posts: [Post]          # Массив и элементы могут быть null

4. Операции (Queries, Mutations, Subscriptions)

Схема определяет, какие операции доступны:

# QUERY — получение данных (read)
query GetUser {
  user(id: "123") {
    id
    name
    email
  }
}

# MUTATION — изменение данных (write)
mutation CreatePost {
  createPost(
    title: "Новая статья"
    content: "Содержание..."
    authorId: "456"
  ) {
    id
    title
    author {
      name
    }
  }
}

# SUBSCRIPTION — подписка на события (real-time)
subscription OnNewPost {
  postCreated {
    id
    title
    author {
      name
    }
  }
}

Аргументы и фильтрация

Схема определяет, какие аргументы принимают запросы:

# Определение схемы
type Query {
  posts(
    limit: Int = 10          # Параметр с значением по умолчанию
    offset: Int = 0
    authorId: ID             # Опциональный параметр
    sortBy: String = "date"
  ): [Post!]!
}

# Пример запроса
query {
  posts(limit: 20, authorId: "456", sortBy: "title") {
    id
    title
    author { name }
  }
}

Интерфейсы и union типы

Схема поддерживает абстрактные типы:

# Interface — контракт для других типов
interface Node {
  id: ID!
}

type User implements Node {
  id: ID!
  name: String!
}

type Post implements Node {
  id: ID!
  title: String!
}

# Union — тип может быть одним из нескольких
union SearchResult = User | Post | Comment

type Query {
  search(query: String!): [SearchResult!]!
}

# Запрос к union типу
query {
  search(query: "иван") {
    ... on User {
      id
      name
      email
    }
    ... on Post {
      id
      title
    }
    ... on Comment {
      id
      text
    }
  }
}

Input типы для мутаций

Для сложных мутаций используются input типы:

# Определение input типа
input CreatePostInput {
  title: String!
  content: String!
  tags: [String!]
  published: Boolean = false
}

type Mutation {
  createPost(input: CreatePostInput!): Post!
}

# Запрос
mutation {
  createPost(input: {
    title: "Заголовок"
    content: "Текст"
    tags: ["javascript", "react"]
    published: true
  }) {
    id
    title
  }
}

Директивы

Схема определяет директивы для условного включения полей:

# Определение директивы
directive @deprecated(reason: String) on FIELD_DEFINITION

type User {
  id: ID!
  name: String!
  fullName: String @deprecated(reason: "Используй name вместо этого")
}

# Использование в запросе
query {
  user(id: "123") {
    name
    # Стандартные директивы: @skip и @include
    email @include(if: $includeEmail)
    phone @skip(if: $hidePhone)
  }
}

Практический пример: REST API vs GraphQL схема

REST API:

GET /api/users/123
GET /api/users/123/posts
GET /api/users/123/posts/456/comments

Вам нужно 3 запроса!

GraphQL:

query {
  user(id: "123") {
    name
    posts {           # Связанные данные в одном запросе
      title
      comments {      # Вложенные связи
        text
        author { name }
      }
    }
  }
}

Один запрос!

Использование схемы в приложении

На сервере:

// Apollo Server
const typeDefs = `
  type Query {
    user(id: ID!): User
    posts: [Post!]!
  }
  
  type User {
    id: ID!
    name: String!
    posts: [Post!]!
  }
  
  type Post {
    id: ID!
    title: String!
    author: User!
  }
`;

const resolvers = {
  Query: {
    user: (_, { id }) => fetchUser(id),
    posts: () => fetchPosts()
  },
  User: {
    posts: (user) => fetchUserPosts(user.id)
  }
};

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

На клиенте:

import { gql, useQuery } from '@apollo/client';

const GET_USER = gql`
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      name
      posts {
        id
        title
      }
    }
  }
`;

function UserProfile({ userId }) {
  const { loading, data } = useQuery(GET_USER, { variables: { id: userId } });
  // Данные будут соответствовать схеме
  return <div>{data?.user?.name}</div>;
}

Резюме

GraphQL схема определяет:

  1. Типы данных — какие данные доступны
  2. Структуру — как связаны данные между собой
  3. Операции — какие query, mutation, subscription доступны
  4. Валидацию — обязательные/опциональные поля, типы
  5. Аргументы — какие параметры принимают операции
  6. Контракт — договор между клиентом и сервером

ГрафQL схема — это сердце GraphQL API. Она гарантирует, что и клиент, и сервер понимают друг друга и работают с одинаковыми данными. IDE автоматически подсказывает доступные поля и типы благодаря схеме.