GraphQL API с JavaScript: пошаговый туториал для Node.js
GraphQL — это мощный язык запросов для API, разработанный Facebook. В отличие от REST, где вы получаете фиксированные структуры данных, GraphQL позволяет клиенту запрашивать только то, что ему нужно. В этом туториале мы создадим полноценный GraphQL API на JavaScript с использованием Node.js и Apollo Server. Вы узнаете, как настроить сервер, определить схему, написать резолверы и выполнять запросы и мутации.
Что такое GraphQL и зачем он нужен?
GraphQL решает несколько проблем REST API:
- Избыточность данных: клиент получает только те поля, которые запросил.
- Несколько запросов: один GraphQL-запрос может заменить несколько REST-эндпоинтов.
- Строгая типизация: схема определяет типы данных и связи между ними.
JavaScript (Node.js) — идеальный выбор для создания GraphQL API благодаря огромной экосистеме пакетов и асинхронной природе.
Шаг 1: Установка и настройка проекта
Создайте новую директорию и инициализируйте проект:
mkdir graphql-api-tutorial
cd graphql-api-tutorial
npm init -y
Установите необходимые зависимости:
npm install apollo-server graphql
Создайте файл index.js — это будет точка входа в наше приложение.
Шаг 2: Определение схемы GraphQL
Схема — это ядро GraphQL API. Она описывает типы данных и доступные операции (запросы, мутации, подписки). Создадим простую схему для управления книгами.
const { ApolloServer, gql } = require('apollo-server');
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
deleteBook(id: ID!): Book
}
`;
Здесь мы определили:
- Book — объектный тип с полями id, title, author, year.
- Query — точка входа для чтения данных (список книг и книга по ID).
- Mutation — операции изменения данных (добавление и удаление книги).
Шаг 3: Написание резолверов
Резолверы — это функции, которые возвращают данные для каждого поля схемы. Создадим фиктивную базу данных (массив объектов) и реализуем резолверы.
let books = [
{ id: '1', title: '1984', author: 'George Orwell', year: 1949 },
{ id: '2', title: 'To Kill a Mockingbird', author: 'Harper Lee', year: 1960 },
];
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;
},
deleteBook: (parent, args) => {
const index = books.findIndex(book => book.id === args.id);
if (index === -1) return null;
const deletedBook = books.splice(index, 1)[0];
return deletedBook;
},
},
};
Обратите внимание на структуру: Query и Mutation — это объекты, содержащие методы-резолверы. Каждый резолвер принимает три аргумента: parent (результат родительского резолвера), args (аргументы запроса) и context (объект контекста, например, для аутентификации).
Шаг 4: Запуск сервера и тестирование
Теперь соединим схему и резолверы в Apollo Server:
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Запустите приложение:
node index.js
После запуска откройте в браузере http://localhost:4000 — вы попадете в Apollo Studio (GraphQL Playground). Здесь можно тестировать запросы.
Пример запроса Query:
query {
books {
id
title
author
}
}
Ответ:
{
"data": {
"books": [
{ "id": "1", "title": "1984", "author": "George Orwell" },
{ "id": "2", "title": "To Kill a Mockingbird", "author": "Harper Lee" }
]
}
}
Пример мутации (добавление книги):
mutation {
addBook(title: "Brave New World", author: "Aldous Huxley", year: 1932) {
id
title
author
}
}
После выполнения мутации книга появится в списке.
Советы по оптимизации и безопасности
- Валидация входных данных: используйте библиотеки (например, Joi) для проверки аргументов мутаций.
- Аутентификация: передавайте токены через HTTP-заголовки и проверяйте их в контексте Apollo Server.
- База данных: замените фиктивный массив на MongoDB, PostgreSQL или другую БД с помощью ORM (Mongoose, Prisma).
- Пагинация: для больших списков используйте аргументы
firstиafter(Cursor-based pagination).
Заключение
Вы создали полноценный GraphQL API на JavaScript (Node.js) с использованием Apollo Server. Мы рассмотрели ключевые концепции: схему, резолверы, запросы и мутации. GraphQL даёт гибкость и эффективность, которых часто не хватает в REST. Теперь вы можете расширить проект: добавить подписки (real-time), подключить базу данных и реализовать сложные связи между типами. Удачи в разработке!