GraphQL: Schema и типы
Schema — центральный артефакт GraphQL API, описывающий все доступные типы данных и операции в декларативном языке SDL (Schema Definition Language).
Зачем нужно
Schema служит контрактом между клиентом и сервером: клиент точно знает, какие поля доступны и какого типа. Статическая типизация позволяет валидировать запросы до выполнения, генерировать TypeScript-типы и документацию автоматически. Понимание схемы необходимо для проектирования GraphQL API.
Где используется
- Определение API на сервере (Apollo Server, graphql-yoga, Nexus)
- Автоматическая генерация TypeScript-типов (graphql-codegen)
- Introspection в GraphiQL и Playground для изучения API
- Code-first и Schema-first подходы в NestJS GraphQL
Скалярные типы
# Встроенные скаляры
String # строка UTF-8
Int # 32-битное целое
Float # число с плавающей точкой
Boolean # true/false
ID # уникальный идентификатор (строка или число)
# Кастомные скаляры
scalar Date
scalar JSON
scalar URL
Объектные типы
type User {
id: ID! # ! — обязательное поле (non-null)
name: String!
email: String!
age: Int # null — поле необязательно
role: UserRole! # ссылка на другой тип
posts: [Post!]! # массив Post, не может быть null и содержать null-элементы
createdAt: Date!
}
enum UserRole {
ADMIN
EDITOR
VIEWER
}
type Post {
id: ID!
title: String!
body: String!
author: User!
tags: [String!]!
}
Query, Mutation, Subscription
type Query {
user(id: ID!): User
users(role: UserRole, first: Int, after: String): UserConnection!
me: User
}
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
deleteUser(id: ID!): DeleteResult!
}
type Subscription {
userCreated: User!
messageAdded(roomId: ID!): Message!
}
Input-типы
# Input — только для аргументов мутаций, не объектных полей
input CreateUserInput {
name: String!
email: String!
role: UserRole = VIEWER # дефолтное значение
}
input UpdateUserInput {
name: String
email: String
role: UserRole
}
type DeleteResult {
success: Boolean!
message: String
}
Интерфейсы и Union
interface Node {
id: ID!
}
type User implements Node {
id: ID!
name: String!
}
type Post implements Node {
id: ID!
title: String!
}
union SearchResult = User | Post | Comment
Частые ошибки
- Путают
typeиinput—inputнельзя использовать как тип поля, только как аргумент - Забывают
!(non-null) — поле возвращаетnullтам, где этого не ожидают [Post]vs[Post!]!— важно понимать все комбинации nullable- Используют
IDкак число — GraphQL всегда сериализует ID как строку
Связанные темы
- _MOC Сеть
- GraphQL -- основы и отличия от REST
- GraphQL -- Query и Mutation
- GraphQL -- клиентские библиотеки