GraphQL API с JavaScript: пошаговый туториал для Node.js

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

GraphQL API с JavaScript: пошаговый туториал

GraphQL — это язык запросов для API, который позволяет клиентам запрашивать только те данные, которые им действительно нужны. В отличие от REST, где структура ответа фиксирована, GraphQL дает гибкость и контроль. В этом туториале мы создадим простой GraphQL API на Node.js с использованием популярной библиотеки Apollo Server.

Вы научитесь настраивать сервер, определять типы данных, писать резолверы и выполнять запросы и мутации. Все примеры кода можно запустить локально.

1. Настройка окружения и установка зависимостей

Прежде чем писать код, убедитесь, что у вас установлен Node.js (версия 14 или выше). Создайте новую папку для проекта и инициализируйте npm:

mkdir graphql-tutorial
cd graphql-tutorial
npm init -y

Теперь установите необходимые пакеты. Основные зависимости: express (веб-фреймворк), @apollo/server (сервер GraphQL), graphql (ядро GraphQL) и cors (для кросс-доменных запросов).

npm install express @apollo/server graphql cors

Создайте файл index.js — в нем будет весь код сервера.

2. Создание схемы GraphQL и резолверов

Схема — это описание типов данных и операций (запросы, мутации). Резолверы — функции, которые возвращают данные для каждого поля.

Добавим простую модель данных — список книг. Каждая книга имеет id, title, author и year.

Откройте index.js и напишите следующий код:

const { ApolloServer } = require('@apollo/server');
const { startStandaloneServer } = require('@apollo/server/standalone');
const express = require('express');
const cors = require('cors');

// Имитация базы данных
let books = [
  { id: '1', title: 'Война и мир', author: 'Лев Толстой', year: 1869 },
  { id: '2', title: 'Преступление и наказание', author: 'Федор Достоевский', year: 1866 },
  { id: '3', title: 'Мастер и Маргарита', author: 'Михаил Булгаков', year: 1967 }
];

// Определение схемы (Type Definitions)
const typeDefs = `#graphql
  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
  }
`;

// Резолверы
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;
    }
  }
};

// Запуск сервера
async function startServer() {
  const app = express();
  app.use(cors());

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

  const { url } = await startStandaloneServer(server, {
    listen: { port: 4000 },
  });

  console.log(`Сервер GraphQL запущен на ${url}`);
}

startServer();

Разберем код:

  • typeDefs — определяет типы Book, Query (запросы) и Mutation (изменения).
  • resolvers — содержит функции для каждого поля. Для books возвращается весь массив, для book — фильтрация по id.
  • startStandaloneServer — запускает сервер на порту 4000.

3. Тестирование API через GraphQL Playground

Запустите сервер командой node index.js. Откройте браузер и перейдите по адресу http://localhost:4000. Вы увидите интерфейс Apollo Sandbox (современная версия Playground).

Теперь можно выполнять запросы. Пример запроса на получение всех книг:

query {
  books {
    id
    title
    author
  }
}

Ответ будет содержать только запрошенные поля:

{
  "data": {
    "books": [
      { "id": "1", "title": "Война и мир", "author": "Лев Толстой" },
      { "id": "2", "title": "Преступление и наказание", "author": "Федор Достоевский" },
      { "id": "3", "title": "Мастер и Маргарита", "author": "Михаил Булгаков" }
    ]
  }
}

Попробуйте мутацию для добавления книги:

mutation {
  addBook(title: "Анна Каренина", author: "Лев Толстой", year: 1877) {
    id
    title
  }
}

Если мутация выполнена успешно, вы увидите новую книгу в ответе.

4. Расширение API: аргументы, вложенные запросы и обработка ошибок

GraphQL поддерживает вложенные запросы и сложные типы. Добавим тип Author и свяжем его с книгами.

Обновите typeDefs:

const typeDefs = `#graphql
  type Author {
    id: ID!
    name: String!
    books: [Book]
  }

  type Book {
    id: ID!
    title: String!
    author: Author!
    year: Int
  }

  type Query {
    books: [Book]
    book(id: ID!): Book
    authors: [Author]
    author(id: ID!): Author
  }

  type Mutation {
    addBook(title: String!, authorId: ID!, year: Int): Book
    deleteBook(id: ID!): Book
  }
`;

Добавим массив авторов и изменим резолверы:

let authors = [
  { id: '1', name: 'Лев Толстой' },
  { id: '2', name: 'Федор Достоевский' },
  { id: '3', name                

Блоги

Рекомендаций по книгам