Схема - контракт API: які типи є, які поля в них і що можна запитати. Пишеться мовою SDL:
type User {
id: ID!
name: String!
email: String
posts: [Post!]!
}
type Post {
id: ID!
title: String!
author: User!
}
type Query {
user(id: ID!): User
posts(first: Int = 10): [Post!]!
}
type Mutation {
createPost(title: String!, body: String!): Post!
}
! - поле не може бути null. [Post!]! - список, який сам не null і не містить null.
Запит (query) - читання. Клієнт вибирає лише потрібні поля, включно з вкладеними:
query {
user(id: 7) {
name
posts { title }
}
}
Відповідь повторює форму запиту: { "data": { "user": { "name": "Оля", "posts": [...] } } }.
Мутація (mutation) - зміна даних. Синтаксис як у запиту, але виконується послідовно, а результат - змінений об'єкт:
mutation {
createPost(title: "Привіт", body: "...") { id title }
}
Підписка (subscription) - потік подій у реальному часі, зазвичай через WebSocket.
Резолвер - функція на сервері, що повертає значення поля. Для кожного поля в запиті сервер викликає його резолвер. Простим полям (name) достатньо значення з батьківського об'єкта, а для зв'язків (posts) резолвер іде в базу.
Відмінності від REST, які варто пам'ятати:
- одна адреса (
/graphql) і зазвичай методPOST; - помилки не через коди HTTP: відповідь часто має статус 200, а помилки лежать у масиві
errorsпоряд із частковими даними вdata; - інтроспекція: схему можна запитати через сам API - на цьому побудовані автодоповнення в GraphiQL і генератори типів для клієнтів.
У Laravel найпоширеніший пакет - Lighthouse: схема описується в .graphql-файлі, а директиви (@all, @find, @paginate, @create) прив'язують поля до моделей Eloquent без ручних резолверів.