До сих пор мы описывали схему и писали запросы, но выполнять их было негде: нужен настоящий сервер. Представьте ресторан. Схема — это меню: что можно заказать. Резолверы — повара, и каждый умеет готовить своё блюдо. А Apollo Server — старший официант: он принимает заказ (запрос), сверяет его с меню, раздаёт задания поварам и приносит клиенту готовые блюда. В этом уроке вы запустите такого «официанта» на Node.js, подключите схему блога и откроете Apollo Sandbox — песочницу для запросов.

Что понадобится

Apollo Server — самый популярный сервер GraphQL для Node.js; нужна версия 5 и Node.js 20+. Пакет @apollo/server — сам сервер, graphql — «движок» (GraphQL.js), который разбирает и выполняет запросы. Apollo Server 5 работает с graphql 16, а npm по умолчанию поставил бы 17 и остановился с ошибкой ERESOLVE, поэтому версию указываем явно: graphql@16. Для TypeScript добавим typescript, tsx (запускает .ts без сборки) и @types/node:

bash
mkdir blog-api && cd blog-api
npm init --yes && npm pkg set type="module"
npm install @apollo/server graphql@16
npm install -D typescript tsx @types/node

Команда npm pkg set type="module" включает ES-модули: можно писать import и await на верхнем уровне. В package.json добавьте скрипты "dev": "tsx watch src/index.ts" (перезапуск при каждом сохранении) и "typecheck": "tsc --noEmit". В tsconfig.json включите strict, module: "nodenext", verbatimModuleSyntax, а также allowImportingTsExtensions с noEmit: так свои файлы импортируются с расширением .ts, как ./generated/prisma/client.ts в темах про Prisma. tsx типы не проверяет — это делает tsc --noEmit.

Первый сервер за 20 строк

ts
// src/index.ts
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';

const typeDefs = `#graphql
  type Query {
    hello: String!
  }
`;

const resolvers = {
  Query: {
    hello: () => 'Hello, GraphQL!',
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

const { url } = await startStandaloneServer(server, {
  listen: { port: 4000 },
});
console.log(`Server ready at ${url}`);
  • typeDefs — схема строкой на языке SDL. Комментарий #graphql не влияет на сервер, но подсказывает редактору подсветить синтаксис.
  • resolvers — объект-«карта»: имя типа (Query), имя поля (hello) и функция, которая возвращает данные. Эту функцию называют резолвером.
  • new ApolloServer({ typeDefs, resolvers }) собирает сервер, а startStandaloneServer запускает вокруг него HTTP-сервер — Express не нужен — и возвращает url.

Выполните npm run dev — в консоли появится Server ready at http://localhost:4000/. Откройте адрес в браузере: это Apollo Sandbox. Введите в панели операций { hello } и запустите — в ответе придёт { "data": { "hello": "Hello, GraphQL!" } }. Документация и автодополнение в Sandbox строятся из вашей схемы сами — это introspection из первого урока.

Путь запроса: HTTP-сервер, Apollo Server, ваши резолверы, данные и ответ обратно
Путь запроса: HTTP-сервер, Apollo Server, ваши резолверы, данные и ответ обратно

💡 Sandbox виден, пока NODE_ENV не равен production; в продакшене вместо него простая страница, а introspection по умолчанию выключен (подробнее — в уроке про безопасность).

typeDefs и resolvers: имена должны совпадать