Что такое GraphQL?

GraphQL — это язык запросов и среда выполнения для API (интерфейсов прикладного программирования), разработанный Facebook в 2012 году и открытый в 2015 году. Он обеспечивает более эффективную и гибкую альтернативу традиционным API-интерфейсам RESTful для получения данных с серверов и манипулирования ими. популярность в последние годы благодаря своей гибкости и эффективности, особенно в сценариях, где у клиентов разные требования к данным, или при создании современных веб-приложений и мобильных приложений. Он был принят многими организациями и имеет растущую экосистему инструментов и библиотек для поддержки его использования на различных языках программирования.

Ключевые особенности и концепции GraphQL включают в себя:

  • Декларативная выборка данных. GraphQL позволяет клиентам запрашивать только те данные, которые им нужны, исключая чрезмерную или недостаточную выборку данных. Клиенты могут указать форму и структуру требуемого ответа, что уменьшает чрезмерную выборку данных, распространенную в API RESTful.
  • Единая конечная точка. В отличие от REST, который часто включает в себя несколько конечных точек для разных ресурсов, GraphQL обычно предоставляет одну конечную точку для всех взаимодействий. Клиенты отправляют запросы и изменения (для получения и изменения данных соответственно) в эту конечную точку.
  • Строго типизированная схема. API-интерфейсы GraphQL определяются схемой, которая описывает типы доступных данных и связи между ними. Эта схема служит контрактом между клиентом и сервером, гарантируя, что запросы и ответы соответствуют определенной структуре.
  • Данные в реальном времени. GraphQL можно использовать с такими технологиями, как WebSockets, для обеспечения обновления данных и подписок в реальном времени. Это делает его подходящим для создания интерактивных приложений, таких как чат-приложения или живые уведомления.
  • Пакетирование и кеширование. GraphQL позволяет клиентам группировать несколько запросов в один запрос, что может быть более эффективным, чем выполнение нескольких HTTP-запросов. Кроме того, поскольку клиенты явно запрашивают необходимые им данные, кэширование может быть более детальным и эффективным.
  • Интроспекция. API-интерфейсы GraphQL являются интроспективными, что означает, что клиенты могут запрашивать саму схему, чтобы обнаружить доступные типы и операции. Это упрощает изучение и документирование API.
  • Безопасность. API-интерфейсы GraphQL требуют тщательного проектирования и проверки, чтобы предотвратить чрезмерную или недостаточную выборку, а также потенциальные проблемы безопасности, такие как атаки вложенными запросами. Правильные механизмы аутентификации и авторизации имеют важное значение.

В чем разница между GraphQL и Rest API?

  1. Извлечение данных:
    . GraphQL:
    В GraphQL клиенты могут запрашивать именно те данные, которые им нужны, с помощью одного запроса. Клиенты могут указать структуру ответа, и сервер возвращает именно эти данные, что уменьшает избыточную или недостаточную выборку данных.
    .REST: В REST клиенты обычно извлекают данные. из предопределенных конечных точек, а структуру ответа определяет сервер. Может произойти чрезмерная или недостаточная выборка данных, поскольку конечные точки часто возвращают фиксированные структуры данных.
  2. Количество конечных точек:
    . GraphQL:
    GraphQL обычно предоставляет одну конечную точку для всех взаимодействий. Клиенты отправляют запросы и изменения в эту конечную точку, что обеспечивает большую гибкость при получении данных.
    . REST: REST API обычно имеет несколько конечных точек для разных ресурсов (например, /users, /products). Клиенты должны отправлять отдельные запросы к этим конечным точкам для получения данных для разных частей приложения.
  3. Версии:
    . GraphQL:
    GraphQL часто устраняет необходимость управления версиями, поскольку клиенты могут указать точные данные, которые им нужны. Изменения в схеме могут быть дополнительными, не нарушая работу существующих клиентов.
    . REST: API REST может потребовать создания версий для обеспечения обратной совместимости при внесении изменений. В новых версиях API могут появиться новые конечные точки, адаптироваться к которым может быть затруднительно для клиентов.
  4. Структура ответа:
    . GraphQL:
    Ответы в GraphQL соответствуют форме и структуре запроса, что может уменьшить необходимость манипулирования данными на стороне клиента.
    . REST: Ответы в REST часто заранее определяются сервером и могут включать больше или меньше данных, чем нужно клиенту. Клиентам может потребоваться проанализировать и отфильтровать данные на своей стороне.
  5. Кэширование:
    . GraphQL:
    Кэширование в GraphQL может быть более детальным, поскольку клиенты запрашивают определенные данные. Клиенты также могут включать в свои запросы директивы управления кэшем.
    . REST:Стратегии кэширования в REST могут быть менее эффективными из-за фиксированной структуры ответов, что может привести к кэшированию большего количества данных, чем необходимо.
  6. Сложность и кривая обучения:
    . GraphQL:
    GraphQL может потребовать более сложного обучения как для серверных, так и для клиентских разработчиков из-за определения схемы и языка запросов. Однако он обеспечивает большую гибкость.
    REST:REST проще понять, поскольку он следует четко определенным принципам HTTP. Каждая конечная точка представляет собой ресурс, а взаимодействие основано на стандартных методах HTTP (GET, POST, PUT, DELETE).
  7. Инструменты и экосистема:
    . GraphQL:
    GraphQL имеет растущую экосистему инструментов, библиотек и расширений IDE для поддержки разработки, самоанализа и документирования.
    . REST: REST существует уже давно и имеет зрелый набор инструментов и соглашений, но ему может не хватать некоторых более специализированных инструментов GraphQL.

Что я выбираю?

Выбор между GraphQL и REST зависит от конкретных требований проекта. GraphQL часто предпочитают для современных приложений, где гибкость в получении данных и возможности работы в реальном времени имеют решающее значение. REST по-прежнему широко используется, особенно в тех случаях, когда достаточно простого и понятного подхода или когда существуют устаревшие системы. В конечном итоге выбор должен соответствовать потребностям приложения и опыту команды разработчиков.

Давайте сравним реальный пример того, как API GraphQL и REST обрабатывают сложные запросы с вложенными данными.

Сценарий:
Предположим, вы создаете приложение, отображающее информацию о книгах и их авторах.

Пример GraphQL:
С помощью GraphQL клиент может запросить именно те данные, которые ему нужны, включая вложенные данные, в одном запросе. Вот пример запроса для книги и ее автора:

query {
  book(id: "123") {
    title
    publicationYear
    author {
      name
      biography
    }
  }
}

В этом запросе GraphQL:
.
Мы запрашиваем title и publicationYear книги с идентификатором «123.»:
. Мы также запрашиваем информацию о author книги, включая name и biography автора.
Сервер ответит именно этой структурой данных, упрощая клиентский код, поскольку он получает только необходимые данные.

Пример REST API:
В REST API вам может потребоваться выполнить несколько запросов для получения одних и тех же данных. Обычно у вас есть конечные точки, такие как /books/:id и /authors/:authorId, для отдельного получения сведений о книге и авторе.

Чтобы получить ту же информацию, что и в примере GraphQL, вам может потребоваться сделать два отдельных запроса:

  1. Получить информацию о книге:
GET /books/123

Ответ:

{
  "id": "123",
  "title": "Sample Book",
  "publicationYear": 2022,
  "authorId": "456"
}

2. Получить данные об авторе:

GET /authors/456

Ответ:

{
  "id": "456",
  "name": "Author Name",
  "biography": "Author's Biography..."
}

С помощью REST вам необходимо управлять этими двумя отдельными запросами и обрабатывать слияние и вложение данных на стороне клиента, что может привести к более сложному клиентскому коду по сравнению с подходом GraphQL.

Подводя итог, GraphQL упрощает код на стороне клиента, позволяя клиентам запрашивать сложные вложенные структуры данных в одном запросе, в то время как в REST API клиентам может потребоваться выполнять несколько запросов и самостоятельно управлять объединением данных, что может привести к более сложному коду. .

Чтобы использовать GraphQL в проекте MERN (MongoDB, Express.js, React, Node.js):

вам нужно будет настроить необходимые пакеты и конфигурации. Вот шаги по установке GraphQL в ваш проект MERN:

мы настроим сервер GraphQL в приложении Express.js для запроса и получения информации о книгах и их авторах.

Шаг 1. Установите зависимости и настройте проект
Создайте новый каталог для своего проекта, перейдите в него и установите необходимые пакеты:

mkdir graphql-express-book-example
cd graphql-express-book-example
npm init -y
npm install express express-graphql graphql mongoose
  • graphql: Основная библиотека GraphQL.
  • express-graphql: Промежуточное ПО для интеграции GraphQL с Express.js.
  • mongoose: Если вы используете MongoDB в качестве базы данных, этот пакет поможет вам взаимодействовать с базой данных с помощью объектов JavaScript.

Шаг 2. Настройка сервера Express.js и схемы GraphQL
Создайте файл app.js и настройте сервер Express.js и схему GraphQL:

// app.js

const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLList } = require('graphql');

const app = express();

// Sample data
const authors = [
  { id: '1', name: 'Author 1' },
  { id: '2', name: 'Author 2' },
];

const books = [
  { id: '1', title: 'Book 1', authorId: '1' },
  { id: '2', title: 'Book 2', authorId: '1' },
  { id: '3', title: 'Book 3', authorId: '2' },
];

const AuthorType = new GraphQLObjectType({
  name: 'Author',
  fields: {
    id: { type: GraphQLString },
    name: { type: GraphQLString },
  },
});

const BookType = new GraphQLObjectType({
  name: 'Book',
  fields: {
    id: { type: GraphQLString },
    title: { type: GraphQLString },
    authorId: { type: GraphQLString },
    author: {
      type: AuthorType,
      resolve(parent) {
        return authors.find((author) => author.id === parent.authorId);
      },
    },
  },
});

const RootQuery = new GraphQLObjectType({
  name: 'RootQuery',
  fields: {
    book: {
      type: BookType,
      args: { id: { type: GraphQLString } },
      resolve(_, args) {
        return books.find((book) => book.id === args.id);
      },
    },
    books: {
      type: new GraphQLList(BookType),
      resolve() {
        return books;
      },
    },
    author: {
      type: AuthorType,
      args: { id: { type: GraphQLString } },
      resolve(_, args) {
        return authors.find((author) => author.id === args.id);
      },
    },
    authors: {
      type: new GraphQLList(AuthorType),
      resolve() {
        return authors;
      },
    },
  },
});

const schema = new GraphQLSchema({
  query: RootQuery,
});

app.use('/graphql', graphqlHTTP({ schema, graphiql: true }));

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server started on port ${PORT}`);
});

В этом коде мы определяем схему с типами Author и Book, настраиваем образцы данных для авторов и книг и создаем запросы для получения книг и авторов.

Шаг 3. Запустите сервер
Запустите сервер Express.js:

node app.js

Ваш GraphQL API должен работать в http://localhost:3000/graphql. Вы можете получить доступ к интерфейсу GraphiQL для интерактивного тестирования запросов.

Шаг 4. Тестирование запросов GraphQL
Вот несколько примеров запросов GraphQL, которые вы можете выполнить в GraphiQL:

. Получите список всех книг и их авторов:

{
  books {
    title
    author {
      name
    }
  }
}

. Получить информацию о конкретной книге по ее идентификатору:

{
  book(id: "1") {
    title
    author {
      name
    }
  }
}

. Получите список всех авторов и их книг:

{
  authors {
    name
    books {
      title
    }
  }
}

Эти запросы будут возвращать ответы JSON с запрошенными данными, демонстрируя, как запросить схему GraphQL для получения информации о книгах и авторах в приложении Express.js.

6. Интегрируйте GraphQL со своим интерфейсом:
В коде React (или другого интерфейса) вам нужно будет отправлять HTTP-запросы к конечной точке GraphQL для получения и обновления данных. Для этой цели вы можете использовать такие библиотеки, как Apollo Client или Relay.

7. Шаг 7. Создайте приложение React
Если у вас еще нет приложения React.js, вы можете создать его с помощью Create React App или предпочитаемого вами метода:

npx create-react-app my-graphql-app
cd my-graphql-app
npm start

Шаг 8. Установите клиент Apollo
В каталоге проекта установите клиент Apollo и необходимые зависимости:

npm install @apollo/client graphql

Шаг 9. Настройка клиента Apollo
Создайте экземпляр клиента Apollo и предоставьте его своему приложению React. Обычно это делается в файле index.js или App.js:

// src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
import App from './App';

const client = new ApolloClient({
  uri: 'YOUR_GRAPHQL_API_ENDPOINT', // Replace with your GraphQL API endpoint
  cache: new InMemoryCache(),
});

ReactDOM.render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,
  document.getElementById('root')
);

Шаг 10. Создайте запрос GraphQL
Определите запрос GraphQL, используя литеральный тег шаблона gql из пакета graphql. Вы можете сделать это в отдельном файле или непосредственно в файле компонента:

// src/queries.js

import { gql } from '@apollo/client';

export const GET_BOOKS = gql`
  query {
    books {
      title
      author
    }
  }
`;

Шаг 11. Используйте запрос в компоненте React
Теперь вы можете использовать запрос GraphQL в компоненте React. Вот пример того, как использовать запрос и отображать данные:

// src/BookList.js

import React from 'react';
import { useQuery } from '@apollo/client';
import { GET_BOOKS } from './queries';

function BookList() {
  const { loading, error, data } = useQuery(GET_BOOKS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      <h2>Book List</h2>
      <ul>
        {data.books.map((book, index) => (
          <li key={index}>
            <strong>Title:</strong> {book.title}, <strong>Author:</strong> {book.author}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default BookList;

Шаг 12. Используйте компонент в своем приложении
Импортируйте и используйте компонент BookList в своем основном App.js или там, где он необходим:

// src/App.js

import React from 'react';
import './App.css';
import BookList from './BookList';

function App() {
  return (
    <div className="App">
      <h1>My GraphQL App</h1>
      <BookList />
    </div>
  );
}

export default App;

Теперь, когда вы запускаете приложение React (npm start), оно будет получать данные из вашего GraphQL API и отображать их в компоненте BookList 💪

Не забудьте заменить 'YOUR_GRAPHQL_API_ENDPOINT' фактическим URL-адресом вашего GraphQL API. В этом примере показано, как создать простой запрос GraphQL в приложении React.js с использованием клиента Apollo. Вы можете расширить это, создавая более сложные запросы и мутации, необходимые для вашего проекта.

«Спасибо, что прочитали эту статью. До скорой встречи!"

GraphQL приобрел популярность в последние годы благодаря своей гибкости и эффективности, особенно в сценариях, где у клиентов разные требования к данным, или при создании современных веб-приложений и мобильных приложений. Он был принят многими организациями и имеет растущую экосистему инструментов и библиотек для поддержки его использования на различных языках программирования.