GraphQL библиотека для Node.js: Apollo Server и инструменты разработки
GraphQL — это язык запросов для API, который позволяет клиентам запрашивать только те данные, которые им необходимы. Для разработки на Node.js самой популярной библиотекой является Apollo Server. Она предоставляет полный набор инструментов для создания, тестирования и развертывания GraphQL API. В этой статье мы подробно разберем ключевые компоненты, подходы и примеры кода.
Что такое Apollo Server?
Apollo Server — это библиотека с открытым исходным кодом, которая позволяет быстро создать GraphQL сервер на Node.js. Она поддерживает множество транспортов (HTTP, WebSocket) и легко интегрируется с фреймворками (Express, Koa, Fastify). Основные возможности:
- Автоматическая генерация документации через GraphQL Playground.
- Поддержка подписок (subscriptions) через WebSocket.
- Механизм кэширования и объединения данных (data loaders).
- Гибкая система middleware для аутентификации и авторизации.
Установка и базовая настройка
Для начала работы установите пакеты apollo-server и graphql:
npm install apollo-server graphql
Создайте простой сервер, который возвращает приветствие:
const { ApolloServer, gql } = require('apollo-server');
// Определяем схему (SDL)
const typeDefs = gql`
type Query {
hello: String
}
`;
// Резолверы — функции, которые возвращают данные
const resolvers = {
Query: {
hello: () => 'Hello, GraphQL!',
},
};
// Запускаем сервер
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Сервер запущен на ${url}`);
});
Типы данных и схемы
В GraphQL схема определяет все доступные типы и операции. Основные типы:
String,Int,Float,Boolean,ID— скалярные типы.[Type]— список объектов.type— пользовательский объект.input— тип для входных параметров мутаций.
Пример схемы для блога:
type User {
id: ID!
name: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
}
type Query {
user(id: ID!): User
posts(limit: Int): [Post!]!
}
type Mutation {
createUser(name: String!): User!
}
Резолверы: связь схемы с данными
Каждое поле схемы должно иметь соответствующий резолвер. Резолверы могут получать данные из базы (MongoDB, PostgreSQL), внешних API или статических массивов.
const users = [
{ id: '1', name: 'Анна' },
{ id: '2', name: 'Борис' },
];
const posts = [
{ id: '10', title: 'GraphQL для начинающих', content: '...', authorId: '1' },
{ id: '20', title: 'Node.js советы', content: '...', authorId: '2' },
];
const resolvers = {
Query: {
user: (_, { id }) => users.find(u => u.id === id),
posts: (_, { limit }) => limit ? posts.slice(0, limit) : posts,
},
Mutation: {
createUser: (_, { name }) => {
const newUser = { id: String(users.length + 1), name };
users.push(newUser);
return newUser;
},
},
User: {
posts: (parent) => posts.filter(p => p.authorId === parent.id),
},
};
Code-first подход с TypeGraphQL
Для больших проектов удобнее использовать code-first подход, когда схема генерируется из TypeScript классов. Библиотека type-graphql позволяет писать код, который одновременно является и типом, и резолвером.
npm install type-graphql reflect-metadata class-validator
Пример класса-сущности:
import { ObjectType, Field, ID } from 'type-graphql';
@ObjectType()
class User {
@Field(() => ID)
id: string;
@Field()
name: string;
@Field(() => [Post])
posts: Post[];
}
Резолвер с декораторами:
import { Resolver, Query, Arg } from 'type-graphql';
@Resolver(User)
class UserResolver {
@Query(() => User, { nullable: true })
async user(@Arg('id') id: string) {
// Логика получения пользователя
}
}
Работа с подписками (Subscriptions)
Подписки позволяют клиентам получать обновления в реальном времени