Введение в GraphQL и его преимущества
GraphQL — это язык запросов для API, разработанный Facebook. В отличие от REST, где каждый эндпоинт возвращает фиксированную структуру данных, GraphQL позволяет клиенту запрашивать только нужные поля. Это делает API более гибким и эффективным.
В этом туториале мы создадим простой GraphQL сервер на Node.js с использованием библиотеки Apollo Server, настроим схему, реализуем запросы и мутации. Вы узнаете:
- Как установить и настроить Apollo Server
- Как определить схему с типами данных
- Как написать резолверы для запросов и мутаций
- Как протестировать API через GraphQL Playground
Для работы вам понадобится Node.js (версия 16+) и базовое понимание JavaScript. Начнём!
Шаг 1: Настройка проекта и установка зависимостей
Создайте новую директорию для проекта и инициализируйте package.json:
mkdir graphql-tutorial
cd graphql-tutorial
npm init -y
Установите необходимые пакеты:
npm install apollo-server graphql
Пакет apollo-server предоставляет готовый HTTP-сервер для GraphQL, а graphql — ядро для работы со схемами и запросами.
Шаг 2: Создание базовой схемы и резолверов
Создайте файл index.js и импортируйте Apollo Server:
const { ApolloServer, gql } = require('apollo-server');
// Данные в памяти (имитация базы данных)
const books = [
{ id: '1', title: 'Война и мир', author: 'Лев Толстой', year: 1869 },
{ id: '2', title: 'Преступление и наказание', author: 'Фёдор Достоевский', year: 1866 },
{ id: '3', title: 'Мастер и Маргарита', author: 'Михаил Булгаков', year: 1967 }
];
Теперь определим схему с помощью тега gql:
const typeDefs = gql`
type Book {
id: ID!
title: String!
author: String!
year: Int
}
type Query {
books: [Book]
book(id: ID!): Book
}
type Mutation {
addBook(title: String!, author: String!, year: Int): Book
}
`;
Создайте резолверы — функции, которые возвращают данные для каждого поля запроса:
const resolvers = {
Query: {
books: () => books,
book: (parent, args) => books.find(book => book.id === args.id)
},
Mutation: {
addBook: (parent, args) => {
const newBook = {
id: String(books.length + 1),
title: args.title,
author: args.author,
year: args.year
};
books.push(newBook);
return newBook;
}
}
};
Шаг 3: Запуск сервера и тестирование
Создайте экземпляр сервера и запустите его:
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Сервер готов по адресу: ${url}`);
});
Запустите сервер командой node index.js. По умолчанию Apollo Server запускается на порту 4000 и открывает GraphQL Playground — интерактивную среду для тестирования запросов.
Попробуйте выполнить простой запрос:
query {
books {
title
author
}
}
Ответ должен содержать массив книг с выбранными полями:
{
"data": {
"books": [
{ "title": "Война и мир", "author": "Лев Толстой" },
{ "title": "Преступление и наказание", "author": "Фёдор Достоевский" },
{ "title": "Мастер и Маргарита", "author": "Михаил Булгаков" }
]
}
}
Теперь протестируем мутацию для добавления новой книги:
mutation {
addBook(title: "Анна Каренина", author: "Лев Толстой", year: 1877) {
id
title
author
}
}
После выполнения мутации сервер вернёт объект новой книги с присвоенным ID.
Шаг 4: Расширение схемы — связи между типами
GraphQL позволяет создавать сложные связи между сущностями. Добавим авторов как отдельный тип:
const typeDefs = gql`
type Author {
id: ID!
name: String!
books: [Book]
}
type Book {
id: ID!
title: String!
author: Author!
year: Int
}
type Query {
books: [Book]
authors: [Author]
}
`;
Обновим данные и резолверы:
const authors = [
{ id: '1', name: 'Лев Толстой' },
{ id: '2', name: 'Фёдор Достоевский' },
{ id: '3', name: 'Михаил Булгаков' }
];
const books = [
{ id: '1', title: 'Война и мир', authorId: '1', year: 1869 },
{ id: '2', title: 'Преступление и наказание', authorId: '2', year: 1866 },
{ id: '3', title: 'Мастер и Маргарита', authorId: '3', year: 1967 }
];
const resolvers = {
Query: {
books: () => books,
authors: () => authors
},
Book: {
author: (parent) => authors.find(a => a.id === parent.authorId)
},
Author: {
books: (parent) => books.filter(b => b.authorId === parent.id)
}
};
Теперь можно запрашивать авторов с их книгами:
query {
authors {
name
books {
title
year
}
}
}
Заключение
Мы создали полноценный GraphQL API на Node.js с помощью Apollo Server. Вы научились:
- Определять схему с типами, запросами и мутациями
- Писать резолверы для обработки данных
- Устанавливать связи между типами
- Тестировать API через GraphQL Playground
GraphQL даёт разработчикам мощный инструмент для создания гибких и производительных API. Для дальнейшего изучения рекомендую:
- Добавить валидацию входных данных
- Подключить реальную базу