Comments 14
Как по мне, не увидел никаких преимуществ GraphQL, кроме возможности менять запросы на стороне клиента, не переписывая сервер. Впрочем, не такой это и плюс.
Сдается мне, это придумали фронтедщики, чтоб не пинать бэкендщиков по каждому чиху.
Вот только мне кажется при такой свободе и отсутствии кеширования такие запросы, особенно сложные, сильно просаживают быстродействие.
Плюсы GraphQL:
Единая нотация
Возможность указания только тех полей, что нужно
Можно за один запрос получить данные с разных backend-ов
Можно получать связанные данные (пользователь + его заказы, например)
Запросы к бекендам могут параллелиться без изменения логики в клиенте
Но есть и минусы:
Секурити, точнее отсутствие
Своя нотация запросов
Нельзя указать * для полей - обязательно перечислять
Скорость ниже, чем прямой вызов (но может быть быстрее за счёт параллелизма)
Вообще для UI подход GraphQL оказался очень удобным даже не смотря на минусы.
Единая нотация
А в чем плюс? Только возня с ее описанием. В случае простых рест запросов можно вообще забить на нотации и трафик и слать объекты целиком, с посылом - все что есть в ответе есть и в объекте. В случае сложных запросов десять раз подумаешь, а не проще ли было сделать конкретный ендпоинт для этого запроса, который бы слал конкретные объекты предстваления, не завязанные на схему, а нужные только для представления.
Возможность указания только тех полей, что нужно
В REST это тоже делалось задолго до создания GraphQL. Параметр fields в конце URL.
Можно за один запрос получить данные с разных backend-ов
Обожаю этот аргумент! Вы когда-нибудь писали кастомный резолвер, который вам соберет сложный объект по нескольким микросервисам? Это одинаковая головная боль, что для REST, что для GraphQL. Только в случае последнего вам придется писать резольвер по-настоящему общего назначения, который будет работать для всех полей и связанных объектов, и потом решать проблемы производительности с этим чудом. В случае REST такие вещи хотя бы ограничивают универсальность применения одним ендпоинтом и доступными для него спидхаками и упрощениями выборки.
Можно получать связанные данные (пользователь + его заказы, например)
Да можно, вопрос какой ценой нагрузки на сервер. Вероятно, можно написать хаки для ресольвера, чтобы он какие-то случаи запросов покрывал джойнами, а не выборкой связанных данных отдельными подзапросами. Но чем такие оптимизации принципиально отличаются от создания специализированного рестового ендпоинта?
Запросы к бекендам могут параллелиться без изменения логики в клиенте
Чтобы что?
Просто в REST со стандартом проблема, его по сути нет. Есть рекомендации и устоявшаяся практика. Чем Вам Method+URL+параметр не нотация?
В REST вы тоже можете собирать с многих сервисов. Некоторые даже делают это в API gateway.
А вот возможность получить на сервер запрос всех полей и связанных с ними записей думаю сильно плохо скажется на его здоровье. Интересно посмотреть статистику отказа в обслуживании таких endpoint’ов.
Просто в REST со стандартом проблема, его по сути нет. Есть рекомендации и устоявшаяся практика. Чем Вам Method+URL+параметр не нотация?
Потому что "нотация" GraphQL создана из рассчета, что у нас волшебный сервер, который одинаково эффективно возвращает запрошенные данные. И пофиг как там GraphQL ложится на внутреннюю предметную область, аппаратные ограничения, уже реализованные способы доступа к объектам. За исключением простых случаев, ситуация когда фронтендщики диктуют схему доступа к данным, пусть и прекрываясь технологией, черевата проблемами с производительностью и неоптимальной организацией хранения данных. Потому что для фронтендщика не будут видны под капотом ключи MySQL, лимиты на внешние апи, внутренная организация кэширования. И REST, на мой взгляд, куда лучше справляется как с учетом этих особенностей, так и защитой фронтеднщиков от этих ненужных деталей.
К тому же олновесная реализация нотации GraphQL для всех сущностей системы может стоить дорого. А реализация ограниченного подмножества будет по сути не особо отличаться от REST. Только вместо ендпоинтов для сущностей нужно будет создавать ресолверы для новых сущностей.
А вот возможность получить на сервер запрос всех полей и связанных с ними записей думаю сильно плохо скажется на его здоровье. Интересно посмотреть статистику отказа в обслуживании таких endpoint’ов.
Если пытаться на ендпоинте сделать логику выборки из базы как в авторезолверах, строящих запросы по аннотациям в ORM, то все может быть очень печально. А если сделать выборку вручную написанными запросами, созданными специально под конкретный флоу, то все может быть в разы лучше чем у GraphQL.
Я бы еще отнес к минусам сложность с пермишенами на чтение нод/пропертей
Если говорить про сторонний API на graphQL то удобство в том, что я могу
1) Получать нужные мне данные и их количество из запроса.
2) Комбинировать данные в одном запросе.
Если про свои проекты то там обычный REST API
Собственно, вы правы. Изначально GraphQL был придуман в Facebook, чтобы меньше зависеть от бэкенда. Там же куча сервсов, а к каждому и не один запрос - вот и придумали гейтвей, на который можно было бы переложить эту сложность.
Пользуясь случаем, задам вопрос.
Как в чарлзе мокать GraphQL запросы? с REST там по URL оно прекрасно матчится, а что с GraphQL делать? там эндпоинт-то всегда один.
Когда-то разбирался, клиент хотел на GraphQL. Как по мне, главные:
Замена одного запроса один, что дает выигрыш в "скорости", и возможность гибко задавать что именно надо сейчас. REST API структурирован. Да, он может быть использован как транспорт для передачи "объектов" запрос, но это уже выглядит сильно натянуто, плюс бэкенд надо ж как-то написать
Наличие "акселераторов", которые ускоряют разработку решения в целом
Возможно статья не смогла раскрыть это акцентировано, но ... лично мне зашло, жалко проект не взлетел
Расскажите, пожалуйста, как происходит процесс изменения схемы GraphQL. Вот, к примеру, есть система "на бою", у нее сотни клиентских приложений, у каждого клиентского приложения тысячи юзеров. И в какой-то момент какое-то поле в схеме GraphQL (скажем, идентификатор клиентского приложения, оно во всех запросах присутствует) вдруг должно быть изменено. Скажем, раньше это был простой строковый идентификатор, а теперь нужно передавать объект из двух полей: GUID и строковый идентификатор. Как это изменение должно выкатиться на прод, не задев все клиентские приложения?
Как Вы в своих реальных рабочих проектах с этим справляетесь?
Обычно это организационный процесс в первую очередь. Можно добавить новое поле, старое пометить deprecated и запланировать удаление через 1-3 года. Из минусов - бекенд одновременно поддерживает два поля. Из плюсов - обратная совместимость и контролируемый процесс перехода.
Разницы между GraphQL и REST в данном случае нету, подход и там и там применим.
Сами разработчики GraphQL как раз не поддерживают идею api versioning и смотрят в сторону mutable схемы в общем случае.
Проще новое поле добавить, а в последующих версиях избавиться от старого. Сам сейчас поддерживаю такой проект.
После прочтения статьи сложилось устойчивое ощущение, что автор не разбирается ни в REST API, ни в GraphQL. Плюсы и минусы к реальности не имеют никакого отношения, про json-rpc автор, похоже, вообще не слышал, про проблемы мутаций составных объектов даже не догадывается, в каждом абзаце - фактическая ошибка.
Для технического писателя это нормально, но зачем технический писатель вообще пишет подобные статьи самостоятельно?
Интересно, а в МТС догадываются, как именно подобные статьи влияют на бренд компании? Я бы побоялся даже как пользователь связываться с компанией с таким уровнем публичных статей, про работать я даже не говорю....
REST API vs GraphQL: в чём между ними разница