Случалось ли вам когда-нибудь, чтобы при разработке API ответ оказывался очень большим json с несколькими вложенными объектами?

С одной стороны, это полезно, потому что вы получаете полный ответ в одном запросе. С другой стороны, если вам требуется только небольшая его часть, это неэффективно, потому что обычно включение вложенного объекта подразумевает более медленные запросы к базе данных, в основном из-за использования операторов JOIN.

Это также требует использования сериализаторов для построения ответа json как для основного, так и для вложенного объекта, чтобы мы могли создать полный json.

Здесь и появляется GraphQL, потому что это язык запросов, который использует схему для описания формы графа данных и позволяет запрашивать только те данные, которые вам нужны.

Не могли бы вы привести мне пример?

Если вы раньше не использовали GraphQL, я рекомендую вам прочитать эту документацию и ознакомиться с этой библиотекой.

Предположим, мы используем реляционную базу данных, в которой есть таблица компаний:

И у нас есть еще одна таблица сотрудников:

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

Итак, мы бы определили два типа: один для компании (GraphQLCompany) и другой для сотрудников (GraphQLEmployee).

Как сделать запрос к нашему API?

Мы могли бы создать запрос GraphQL, который выбирает компанию со всеми ее атрибутами, как показано ниже:

У нас может быть другой запрос, который выбирает только компанию с некоторыми ее атрибутами. В этом случае, если не получить сотрудников, дополнительный запрос не выполняется.

Мы можем сделать HTTP-запрос POST к нашему API, используя этот запрос в качестве тела, или использовать клиентскую библиотеку, такую ​​как Apollo client, что упрощает задачу.

Давайте реализуем запрос GraphQL

Мы определяем запрос getCompanyById, который действует как контроллер в нашем API. Этот запрос GraphQL имеет функцию разрешения, которая получает идентификатор в качестве аргумента и возвращает тип GraphQLCompany.

Мы видим, что у нас есть объект репозитория для доступа к базе данных, получения информации о компании и возврата модели компании в функции разрешения запроса. Мы не сериализуем ответ, потому что GraphQLCompanytype отвечает за сериализацию, обращаясь к полям возвращаемого объекта.

Как определить тип GraphQL?

Когда мы определяем запрос в нашем API, мы указываем тип ответа, поэтому объект, который возвращает запрос, должен соответствовать определению типа. Каждое поле в определении типа соответствует возвращаемому объекту.

Так что в случае сотрудников требуется дополнительный запрос. В этом случае мы используем преобразователи настраиваемых полей. Это функции, которые выполняются, если поле запрашивается в запросе, что позволяет нам выполнять дополнительный запрос к базе данных только тогда, когда это необходимо.

Давайте определим тип GraphQL компании, в котором мы укажем его атрибуты:

Мы видим, что у нас есть модель компании, которую мы определяем с помощью нашего объектно-реляционного сопоставления (ORM), и каждое поле является столбцом в модели, но где же сотрудники? Мы знаем, что для того, чтобы получить ассоциацию, мы должны выполнить дополнительные запросы к базе данных, но только тогда, когда поле запрошено, так что именно здесь решатели полей вступают в игру.

Давайте сначала определим тип GraphQL сотрудника:

Затем мы можем добавить поле «Сотрудники» к типу «Компания».

Наконец, мы видим, что модель Company из нашего ORM связана с моделью Employee, где мы можем выполнить дополнительный запрос с помощью простого company.getEmployees()method, и операция выполняется только в том случае, если поле запрошено, потому что функция разрешения будет выполняться только в том случае, если поле является частью запроса, который получает наш API.

Заключение

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

Теперь ваша очередь отправиться в путешествие по GraphQL!