Pull to refresh

Comments 40

NodeJS сможет с лёгкостью отправить одновременно несколько запросов на связанные сущьности. Например, если надо вытянуть данные человека, его друзей, его посты, сообщения. Запросы на друзей, сообщения и посты можно отправить параллельно. В PHP, насколько я знаю, такой возможности нет (за исключением особых извращений)
Ну во первых в этой статье я не говорю что надо использовать PHP, а не Node.js. Я просто рассказываю как использовать GraphQL, если вы используете PHP. А про преимущества и недостатки этих языков можно спорить бесконечно.
Во вторых на PHP конечно нельзя параллельно выполнить подобные запросы. Но во многих случаях можно написать более сложные запросы к БД, которые за один раз получат всю или почти всю необходимую информацию, но в данной статье я не стал усложнять код, потому что это бы усложнило его понимание.
Я к пытался сказать, что PHP плох, NodeJS хорош. Каждый язык — просто инструмент. И каждый язык имеет свои сильные и слабые стороны. Как по мне профит от использования GraphQL не в последнюю (хотя и не единственную) очередь заключается в возможности распараллеливания запросов, когда за различные сущьности отвечают различные сервисы.
Вот уж в отправке асинхронных запросов к БД в PHP никаких проблем нет. Но как правило даже этого ненужно.

https://github.com/Youshido/GraphQL советую присмотреться. Реализует почти все из протокола, есть подход как инлайн конфигурации, так и OO. По опыту использования советую

Спасибо. Я слышал и про эту библиотеку, но так как она не полностью реализует спецификацию, то решил пользоваться graphql-php. Но соглашусь — по стилю эта реализация мне тоже нравится больше. Обязательно рассмотрю её.

пробовал, ни та ни другая реализация graphql под php не понравились. В целом Youshido/GraphQL понравилась больше чем webonyx/graphql-php, однако под последнюю проще писать обертки и фасады упрощающие дела. В целом я еще недостаточно набаловался с обеими.

А что по поводу безопасности самого graphql?

а что не так с безопасностью?

Ну во первых можно намеренно слать самые тяжелые запросы, даже те, которых на фронтенде нет. Во вторых при вытагивании ресурсов было бы неплохо еще всякие политики безопасности иметь, например не показывать удаленных пользователей, сообщения находящиеся в определенных разделах и так далее.
Это решается точно так же, как и в других API. Или в моделях, если graphql — это просто обертка, или через middleware
Похоже не дошли ещё до безопасности в GraphQL.

Типа свежая хипстерская технология.

Имхо.
Вот я удивляюсь. Под каждой статьёй про GraphQL обязательно кто нибудь спросит про безопасность. Но ещё сильнее меня удивляет то, что после комментариев, в которых говорится: «безопасность вашего приложения зависит от вас, а не от GraphQL» — вы делаете вывод, что безопасности в GraphQL нет.

рассмотрим любую спецификацию любого api, например rest. Что должен получить клиент при запросе GET /api/orders? Все 100000 заказов, если в конкретной реализации разработчик не позаботился о том, чтобы данный запрос был с дефолтными page=1&limit=20 (условно). Точно также работает и graphql. Это спецификации доступа к данным, а не про безопасность.

если в конкретной реализации разработчик не позаботился о том,
и кстати в этот момент это API перестаёт быть REST и становится «просто ещё одно кастомное API на URL и HTTP»

не совсем. рест вообще не спека, а крайне общая парадигма, в своей основе имеющая понятия ресурсов и методов доступа к ним. О пагинированности листингов оно не говорит.

в этот момент это API перестаёт быть REST

Я вам больше скажу. Если у вас клиент не использует HATEOAS — у вас не REST. Мобилки не умеют в гипертекст. А сделать так чтобы у нас все на клиенте декларировалось гипертекстом — получится недо-браузер и десяток человеко-лет разработки. Это никому не нужно.


Так что сойдемся на rest-like и норм.

стандарты типа jsonapi вообще никаких решений в этом ключе не предоставляют и никто не замарачивается.

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


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

проникся? помню, в том году ты еще был скептически настроен.

Ну в целом оно решает мои проблемы. Причем неплохо. Тут больше агрессивный маркетинг напрягал.

А я вот все смотрю на него, смотрю. Домашние проекты даже некоторые делал с GraphQL, но вот в реальных проектах пока не решаюсь.

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

UFO just landed and posted this here
Насколько я знаю в реализациях GraphQL на PHP пока нет готового решения этой проблемы, но думаю в будущем она появится. А пока можно просто накладывать определённые ограничения на вложенности или время выполнения запроса. Или же создать что-то вроде реестра доступных запросов и тогда, если запроса полученного сервером не будет в реестре, то он не будет выполняться. Хороший ответ на подобный вопрос есть тут: http://stackoverflow.com/questions/37337466/how-do-you-prevent-nested-attack-on-graphql-apollo-server
UFO just landed and posted this here
Возможно я чего-то не понимаю, или этот подход не для меня, поэтому ответьте пожалуйста на вопрос:

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

это объяснимый, но нехороший способ решать проблемы.


Т.е. данные в базах могут быть специально нормализованы под какой-то высоконагруженный endpoint и от этого будет профит.

обычно все-таки при использовании в качестве бэка sql-решений имеют нормализованную базу и заточенную под фронт денормализованное быстрое хранилище.


Но ведь получается сам подход GraphQL этому противоречит?

GraphQL не предъявляет никаких требований к хранилищу. Используйте любое на какое хватит ума и опыта. В ресолверах могут быть тяжелые запросы с джойнами к sql-хранилищу либо быстрые запросы к redis/mongo/elasticsearch/solr.

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

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


Но ведь получается сам подход GraphQL этому противоречит?

нисколько. Это по сути агрегатор. Фэйсбук его по сути создавал решать простую проблему. У вас есть 5 серверов и нам надо сделать 5 запросов что бы забрать данные на один скрин. В итоге нам проще сделать своего рода фасад над нашим сервером который будет агрегировать данные так как их хочет видеть клиент. Будете вы делать для филда запрос по HTTP или в базу — это уже деталь реализации.

я правильно понимаю, что на выборку из 50 пользователей будет сгенерировано еще +50 запросов на получение кол-ва друзей для каждого? Это можно как-то одним пакетным запросом через WHERE IN решить?

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

Покажите тогда пример как эту ситуацию можно обыграть через +1 запрос с WHERE IN

Конкретно про решение проблемы n+1 можете почитать здесь:
http://webonyx.github.io/graphql-php/data-fetching/#solving-n1-problem

Это документация к библиотеке graphql-php и в ней этот случай описан. Если все равно возникнут вопросы — задавайте.
Sign up to leave a comment.

Articles