3. Schema Definition Language

Схема — это сердце GraphQL. Она определяет все типы данных и операции, которые доступны в API. Это контракт между клиентом и сервером.
Что такое SDL?
Заголовок раздела «Что такое SDL?»SDL (Schema Definition Language) — специальный синтаксис для описания схемы GraphQL.
type User { id: ID! name: String! email: String! age: Int posts: [Post!]!}
type Post { id: ID! title: String! body: String! author: User! createdAt: String!}
type Query { user(id: ID!): User users: [User!]! post(id: ID!): Post posts: [Post!]!}Встроенные скалярные типы
Заголовок раздела «Встроенные скалярные типы»| Тип | Описание | Пример |
|---|---|---|
String | Строка UTF-8 | "Привет" |
Int | 32-битное целое | 42 |
Float | Число с плавающей точкой | 3.14 |
Boolean | Булево значение | true |
ID | Уникальный идентификатор | "user-123" |
Обязательные поля: восклицательный знак !
Заголовок раздела «Обязательные поля: восклицательный знак !»type Product { id: ID! # Обязательное поле — никогда не null name: String! # Обязательное price: Float! # Обязательное description: String # Необязательное — может быть null discount: Float # Необязательное}Комбинации с массивами
Заголовок раздела «Комбинации с массивами»posts: [Post] # Может быть null, элементы могут быть nullposts: [Post!] # Может быть null, но элементы — нетposts: [Post]! # Не null, но элементы могут быть nullposts: [Post!]! # Ни массив ни элементы не могут быть nullКорневые типы
Заголовок раздела «Корневые типы»GraphQL имеет три корневых типа:
type Query { # Все операции чтения user(id: ID!): User product(slug: String!): Product}
type Mutation { # Все операции изменения createUser(input: CreateUserInput!): User! deletePost(id: ID!): Boolean!}
type Subscription { # Real-time операции messageAdded(chatId: ID!): Message! userOnline: User!}Аргументы
Заголовок раздела «Аргументы»Любое поле может принимать аргументы:
type Query { # Обязательный аргумент user(id: ID!): User
# Несколько аргументов posts( limit: Int = 10 # С дефолтным значением offset: Int = 0 orderBy: String ): [Post!]!
# Поиск searchUsers(query: String!): [User!]!}Input типы
Заголовок раздела «Input типы»Для мутаций используй input типы — специальные типы только для входных данных:
input CreateUserInput { name: String! email: String! password: String! age: Int}
input UpdateUserInput { name: String email: String age: Int}
type Mutation { createUser(input: CreateUserInput!): User! updateUser(id: ID!, input: UpdateUserInput!): User!}Почему input, а не type? Типы type могут содержать поля, ссылающиеся на другие объектные типы — это создаёт сложности при сериализации входных данных.
Enum типы
Заголовок раздела «Enum типы»enum UserRole { ADMIN EDITOR VIEWER}
enum PostStatus { DRAFT PUBLISHED ARCHIVED}
type User { id: ID! name: String! role: UserRole!}
type Post { id: ID! title: String! status: PostStatus!}Использование в запросе:
query { users { name role # Вернёт "ADMIN", "EDITOR" или "VIEWER" }}Комментарии и документация
Заголовок раздела «Комментарии и документация»"""Пользователь системы.Может быть администратором, редактором или читателем."""type User { "Уникальный идентификатор пользователя" id: ID!
"Полное имя пользователя" name: String!
""" Email адрес. Используется для авторизации. """ email: String!}Эти комментарии отображаются в GraphiQL и Apollo Studio как документация.
Директивы в схеме
Заголовок раздела «Директивы в схеме»type User { id: ID! name: String! password: String! @deprecated(reason: "Use passwordHash instead") passwordHash: String!}Пример полной схемы: блог
Заголовок раздела «Пример полной схемы: блог»"""Пользователь блога"""type User { id: ID! name: String! email: String! role: UserRole! posts: [Post!]! comments: [Comment!]! createdAt: String!}
enum UserRole { ADMIN AUTHOR READER}
"""Пост в блоге"""type Post { id: ID! title: String! slug: String! body: String! excerpt: String status: PostStatus! author: User! tags: [String!]! comments: [Comment!]! likesCount: Int! createdAt: String! updatedAt: String!}
enum PostStatus { DRAFT PUBLISHED ARCHIVED}
type Comment { id: ID! body: String! author: User! post: Post! createdAt: String!}
type Query { me: User user(id: ID!): User users(role: UserRole): [User!]! post(slug: String!): Post posts( status: PostStatus limit: Int = 20 offset: Int = 0 ): [Post!]! searchPosts(query: String!): [Post!]!}
input CreatePostInput { title: String! body: String! tags: [String!] status: PostStatus = DRAFT}
input CreateCommentInput { postId: ID! body: String!}
type Mutation { createPost(input: CreatePostInput!): Post! updatePost(id: ID!, input: CreatePostInput!): Post! deletePost(id: ID!): Boolean! publishPost(id: ID!): Post!
createComment(input: CreateCommentInput!): Comment! deleteComment(id: ID!): Boolean!
likePost(postId: ID!): Post!}
type Subscription { postPublished: Post! commentAdded(postId: ID!): Comment!}Практика
Заголовок раздела «Практика»- Создай схему для интернет-магазина (Product, Category, Order, User)
- Добавь enum
OrderStatusсо статусами: PENDING, PROCESSING, SHIPPED, DELIVERED, CANCELLED - Создай
inputтипы для создания и обновления продукта - Добавь аргументы пагинации к запросу
products - Добавь описание (
"""...""") к каждому типу
- SDL — декларативный язык описания схемы
!— поле обязательное (не null)inputтипы — только для аргументов мутацийenum— перечисления- Документация прямо в схеме через
"""..."""
Следующий урок → Типы GraphQL →