Определение схемы в GraphQL (SDL)
SDL (Schema Definition Language) — это декларативный язык описания GraphQL-схем.
Он задаёт структуру данных и операций, доступных клиенту.
SDL не содержит логики — это контракт, который определяет «форму» API: какие типы есть, какие поля у них доступны, какие аргументы принимаются.
GraphQL-сервер использует SDL как единый источник правды для валидации запросов и построения выполнения.
1. Основные виды типов в SDL
GraphQL предоставляет несколько видов типов, каждый из которых отвечает за свою роль.
1. type — объектный тип (основа схемы)
Используется для описания сущностей:
2. input — тип вводимых данных
Используется для аргументов мутаций или сложных параметров запросов.
Отличается от type тем, что не может содержать резолверов и нельзя ссылаться на type с циклом.
3. enum — перечисления
Хороший способ ограничить варианты.
4. interface — абстрактный тип
Позволяет описывать общий контракт нескольких типов.
5. union — объединение разных типов
Не имеет общих полей.
Используется, когда ответ может быть разным по структуре.
2. Как выглядит схема GraphQL
В GraphQL схема определяется набором корневых операций:
Query — чтение
Mutation — изменение
Subscription — события/стриминг
Пример минимальной структуры:
На практике «schema {}» часто опускают — сервер выводит её автоматически.
3. Полный пример схемы: пользователи, посты и комментарии
Ниже — типичная схема блог-платформы, написанная в чистом SDL.
#Java #middle #GraphQL
SDL (Schema Definition Language) — это декларативный язык описания GraphQL-схем.
Он задаёт структуру данных и операций, доступных клиенту.
SDL не содержит логики — это контракт, который определяет «форму» API: какие типы есть, какие поля у них доступны, какие аргументы принимаются.
GraphQL-сервер использует SDL как единый источник правды для валидации запросов и построения выполнения.
1. Основные виды типов в SDL
GraphQL предоставляет несколько видов типов, каждый из которых отвечает за свою роль.
1. type — объектный тип (основа схемы)
Используется для описания сущностей:
type User {
id: ID!
name: String!
posts: [Post!]!
}
Типы описывают структуру данных — аналог классов/DTO.2. input — тип вводимых данных
Используется для аргументов мутаций или сложных параметров запросов.
Отличается от type тем, что не может содержать резолверов и нельзя ссылаться на type с циклом.
input CreateUserInput {
name: String!
age: Int
}3. enum — перечисления
Хороший способ ограничить варианты.
enum Role {
ADMIN
USER
GUEST
}4. interface — абстрактный тип
Позволяет описывать общий контракт нескольких типов.
interface Entity {
id: ID!
}
type User implements Entity {
id: ID!
name: String!
}
type Post implements Entity {
id: ID!
title: String!
}
Клиент может запросить id для любого, кто реализует Entity.5. union — объединение разных типов
Не имеет общих полей.
Используется, когда ответ может быть разным по структуре.
union SearchResult = User | Post | Comment
2. Как выглядит схема GraphQL
В GraphQL схема определяется набором корневых операций:
Query — чтение
Mutation — изменение
Subscription — события/стриминг
Пример минимальной структуры:
schema {
query: Query
mutation: Mutation
}На практике «schema {}» часто опускают — сервер выводит её автоматически.
3. Полный пример схемы: пользователи, посты и комментарии
Ниже — типичная схема блог-платформы, написанная в чистом SDL.
Сущности
type User {
id: ID!
name: String!
role: Role!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String
author: User!
comments: [Comment!]!
}
type Comment {
id: ID!
text: String!
author: User!
}
Перечисления
enum Role {
ADMIN
USER
GUEST
}
Входные данные
input CreatePostInput {
title: String!
content: String
}
Запросы
type Query {
user(id: ID!): User
users: [User!]!
post(id: ID!): Post
posts(limit: Int, authorId: ID): [Post!]!
}
Мутации
type Mutation {
createPost(input: CreatePostInput!): Post!
deletePost(id: ID!): Boolean!
}
Подписки
type Subscription {
postCreated: Post!
}
#Java #middle #GraphQL
👍3
4. Как схема связана с кодом
SDL — декларация.
Сервер должен сопоставить поля типам данных и резолверам.
Java (graphql-java, Spring for GraphQL)
SDL:
Резолвер:
GraphQL автоматически соединяет:
поле user → метод user класса UserResolver
аргумент id → параметр метода
На что важно смотреть в связке схема - код
SDL описывает только форму данных, не логику.
Все поля объектных типов должны иметь резолверы (кроме простых полей, которые GraphQL просто читает из объекта).
input использует DTO-классы.
enum маппится на Enum-класс.
union и interface требуют регистрации type resolver-а.
5. Эволюция схемы: изменение и поддержка версий
GraphQL спроектирован так, чтобы обеспечивать обратную совместимость.
Важный принцип: старые клиенты должны продолжать работать после обновлений.
1. Добавление полей — безопасная операция
Можно безболезненно добавлять:
новые поля в типы
новые аргументы с default value
новые типы
новые enum-значения (если клиенты готовы к неизвестным значениям)
Пример:
2. Деприкация полей
Поле нельзя удалить сразу — сначала его помечают как @deprecated.
Клиентский код и инструменты разработчика (GraphiQL, GraphQL Codegen) предупредят о деприкации.
3. Удаление полей
Удалять поле можно только после:
уведомления клиентов,
завершения миграции SDK/фронта,
истечения grace-period'a.
4. Эволюция enum-ов
Добавлять значения — безопасно.
Удалять — нет.
5. Миграции input-типов
Если нужно изменить входные данные:
#Java #middle #GraphQL
SDL — декларация.
Сервер должен сопоставить поля типам данных и резолверам.
Java (graphql-java, Spring for GraphQL)
SDL:
type Query {
user(id: ID!): User
}Резолвер:
@Component
public class UserResolver implements GraphQLQueryResolver {
private final UserService service;
public UserResolver(UserService service) {
this.service = service;
}
public User user(Long id) {
return service.findById(id);
}
}
GraphQL автоматически соединяет:
поле user → метод user класса UserResolver
аргумент id → параметр метода
На что важно смотреть в связке схема - код
SDL описывает только форму данных, не логику.
Все поля объектных типов должны иметь резолверы (кроме простых полей, которые GraphQL просто читает из объекта).
input использует DTO-классы.
enum маппится на Enum-класс.
union и interface требуют регистрации type resolver-а.
5. Эволюция схемы: изменение и поддержка версий
GraphQL спроектирован так, чтобы обеспечивать обратную совместимость.
Важный принцип: старые клиенты должны продолжать работать после обновлений.
1. Добавление полей — безопасная операция
Можно безболезненно добавлять:
новые поля в типы
новые аргументы с default value
новые типы
новые enum-значения (если клиенты готовы к неизвестным значениям)
Пример:
type User {
id: ID!
name: String!
email: String # новое поле
}2. Деприкация полей
Поле нельзя удалить сразу — сначала его помечают как @deprecated.
type User {
id: ID!
name: String!
# старое поле
username: String @deprecated(reason: "Use 'name' instead")
}Клиентский код и инструменты разработчика (GraphiQL, GraphQL Codegen) предупредят о деприкации.
3. Удаление полей
Удалять поле можно только после:
уведомления клиентов,
завершения миграции SDK/фронта,
истечения grace-period'a.
4. Эволюция enum-ов
Добавлять значения — безопасно.
Удалять — нет.
5. Миграции input-типов
Если нужно изменить входные данные:
Старое:
input CreatePostInput {
title: String!
}
Новое:
input CreatePostInput {
title: String!
content: String @deprecated(reason: "Use body instead")
body: String
}
#Java #middle #GraphQL
👍2