Как стать автором
Поиск
Написать публикацию
Обновить

Переоценка API-стратегий: почему компании мигрируют с GraphQL на REST

Уровень сложностиПростой
Время на прочтение7 мин
Количество просмотров10K
Всего голосов 8: ↑5 и ↓3+2
Комментарии28

Комментарии 28

В REST API никто не мешает запрашивать те данные, которые нужны в данный момент. Довольно удобно сделано в Yii2 с его fields и extraFields. Для меня основная причина использовать GraphQL — это возможность сделать несколько запросов к БД/моделям за один запрос к серверу. При использовании REST API таких запросов часто бывает много, что подразумевает множество запросов к серверу.

Для решения такой проблемы есть JsonRpc, он позволяет делат batch запросы. А вообще странно, если данные не нужны, то зачем разработчику добавлять их в endpoint? Если параметры должны задаваться пользователем, то тут бэк тоже может принимать extra поля, но требуется это обычно не часто

"если данные не нужны, то зачем разработчику добавлять их в endpoint" - переиспользование эндпоинтов. Проще и быстрее использовать готовый урл, который вернёт больше данных, чем писать новый

Для решения проблем с производительностью в hot chocolate (сервер graphQl для c#) добавили фичу 'цены' Запроса которая считается через сложение и умножение цен запрашиваемых объектов, которые может настроить разработчик. Это может быть удобно для отказа от выполнения сложных или слишком ресурсоемких Запросов, что как раз решает проблему с 'бомбой' так как сервер посчитает цену запроса, увидит превышение ограничения и откажет в ответе.

Так же можно хранить хеши всех разрешенных запросов и валидировать их по такому признаку. Правда надо поддерживать актуальность этот списка. Зато максимально безопасно

ну да хорошая идея, это даже быстрее будет 👍

На самом деле зависит от задачи. Под каждые задачи свой инструмент

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

А в чем проблема сделать фильтрацию? Она делается точно так же, как на rest через корректный запрос к бд

А в чем сложность? На сервере под каждый объект генерируется резолвер. Перед тем, как вернуть объект из резолвера, можно взять данные авторизации и проверить, можно ли пользователю показать объект. В противном случае вернуть 403. Что тут сложного?

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

Как с мутациями дела обстоят? Я правильно понял что транзакции не поддерживаются?

Какие-то данные это филды? То есть как сделать так чтобы при запросе user поле name возврачалось всем, а email только админу? Просто на резолвер email устанавливаете другие валидации. Если ты не админ и запросил поле email получаешь 403. Хотите пример кода с GraphQL.Net?

https://github.com/graphql-dotnet/server/blob/master/samples/Samples.Authorization/Schema/Query.cs#L15

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

Любой фреймворк нужно учить. К любой технологии нужно привыкать. Сложнее всего сменить технологию которой пользовалься много лет.

Rest и gql требуют принципиально разный подход к планированию апишки. Обратно переходят потому что логика "query это типа get а mutation это типа post" в корне ошибочна и не работает, только создаёт лишние проблемы.

В терминах GraphQL, мутация - это изменение данных, что может быть созданием, обновлением и удалением данных. Query - это исключительно получение данных. При чем тут аналогия с get и post - не понятно.

Когда люди начинают читать про graphql это первое что им говорят. Пытаются привести от знакомого (rest) к новому, так сказать. Даже в этой статье приводятся именно такие аналогии. Ну и собственно народ начинает писать как писал бы rest api, что выходит боком как только проект выходит из стадии mvp

С этим не соглашусь. Пришел к выводу, что graphql лучше использовать как аналог rest api. Так сильно проще код на бэкенде и меньше проблем типа N+1 из-за резольверов полей. Контроллер принимает DTO, возвращает DTO, это можно замапить как на graphql интерфейс, так и на rest.

Вложенная пагинация в graphql не поддерживается. Ну то есть запросить 3-ю страницу order items у всех orders с 4-й страницы конечно можно, только практической пользы от этого нет. А cursor based pagination вообще работать не будет.

N+1 это не проблема. Просто делаете data loader поверх репа и всё. Даже удобнее - в крупном проекте можно легко начать насиловать базу и дата лоадер это предотвратит. И почему пагинация не работает? Ей вообще пофиг на каком она уровне. Может какой аполло это не умеет из коробки, хз, спек не заставляет делать её именно на первом уровне.

Вообще хорошо сделанный gql апи в разы короче, красивее и проще rest. Директивы офигенны, аргументы вложенных полей офигенны, отдельные резолверы на поля офигенны, федерация вообще збс - можно объединить сразу тонну приложений в одну апиху и не париться с написанием оркестратора.

Писать gql как rest тупо нет смысла, проще писать rest.

Не одна пагинация на каком-то уровне, а одна внешняя и одна внутренняя.
Так можно, но практического сценария использования для этого нет.

query {
  users(page: $pageA) {
    orders(page: $pageB) {
    }
  }
}

А так вообще работать не будет, потому что последние order.id на предыдущей странице заказов у всех users разные.

query {
  users(lastId: $idA, limit: 10) {
    orders(lastId: $idB, limit: 10) {
    }
  }
}

А можно узнать, какие именно компании переходят с GQL на Rest? А то такой яркий заголовок без конкретных примеров.

Выводы тоже странные.

Компании переходят с GQL на Рест в простых сервисах? Может, они его изначально для простых систем не берут?

Ограничение сложности запроса - это буквально первое, что стоит сделать с GQL сервисом. Для этого уже есть куча готовых инструментов, где нужно просто поиграться с одним параметром.

Что касается оптимизации - тут все точно так же, как с РЕСТом - начинаем с эффективных запросов в базу, дальше обмазываем кешом и т.д.

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

Максимально поверхностная статья, к сожалению

Какой-то сборник дешёвых пугалок про GraphQL из времён, когда его только выпустили

Graphql мощная вещь, которую к сожалению нужно уметь правильно готовить. Основания проблема, с которой сталкиваются - это думать что это тоже самое что и rest. Что в итоге выливается в REST QL какой-то.

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

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

А вот что касается авторизации - тут да, не все так просто и есть вероятность что придётся что-то придумывать. Или же заиспользовать директивы из федерации.

У всех есть свои плюсы и минусы, все можно сделать по красоте. Но все надо правильно готовить и использовать.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий