Search
Write a publication
Pull to refresh
7
0
Алексей Коротин @m4rt1n

PHP developer

Send message
На данный момент у нас уже есть API для сторонних разработчиков.

Переход на новую версию, о которой шла речь в статье, произойдёт, но называть какие-то ETA я бы не хотел :)

Если мы говорим о shared-nothing architecture, используемой в PHP, кодогенерация — хороший способ сократить время бутстрапа приложения. Те же Doctrine и Symfony DI работают по такому принципу.

Понятное дело, что мы можем отказаться от конфигов в каком-то промежуточном формате и сразу писать код, но это менее удобно.
Да мы, в общем, ничего не изобретали :) JSON API — отдельная спека. Если сравнивать её с GraphQL, она несколько менее гибкая, но более простая в использовании.

Для того, чтобы эффективно использовать GraphQL, неплохо бы уметь параллельно опрашивать источники данных. В PHP есть разные способы для этого, но все они, так или иначе, имеют проблемы. Поэтому наш выбор пал на JSON API — её гибкости достаточно для наших клиентов, а реализация на бэке не требует костылей.
Безусловно, но всё слишком сильно зависит от конкретного случая.

Время на «сделать запрос» можно разделить на две составляющие: это время, которое будет потрачено на установление соединение, и время, которое нужно серверному приложению для бутстрапа. Первой составляющей, в общем-то, отчасти можно принебречь, поскольку HTTP/2 поддерживает мультиплексацию, упаковывая несколько запросов в одно соединение.

Так вот, если время, которое приложение потратит на генерацию ответа клиенту, сравнимо с временем, потраченным на сетевое взаимодействие и бутстрап (скажем, API достаёт уже подготовленный ответ из кеша), правда на вашей стороне.
Однако, если получение запрошенных коллекций требует выполнения какой-то сложной бизнес-логики, ситуация перестаёт быть такой однозначной, и тут вполне может выиграть распараллеливание запросов.
Мы преобразовываем json в модели и обратно: таким образом, в коде эндпойнта мы вообще никак не взаимодействуем с сущностями (под сущностями я понимаю те объекты, которые видит клиент нашего API). Кажется, что в данном случае единственное изменение требований, которое сделает такое пребразование неудобным — это отказ JSON API.
Разумеется, есть сложные случаи, когда одна модель должна распасться на несколько сущностей, или, напротив, одна сущность состоит из нескольких моделей — но такие кейсы мы умеем обрабатывать.

Не могли бы вы рассказать в общих чертах, как вы выполняете обратную трансформацию?

Ну и про отказ от бэкенда я вас, честно говоря, не понял :)

Я вижу тут два варианта:


  • либо тупой CRUD, но тогда в GraphQL-ный шлюз со временем неминуемо утечёт часть бизнес-логики, что нежелательно,
  • либо то, что описывает уважаемый VolCh, и тут, как мне кажется, перспектива получить "единый API на REST" разобьётся о скалы суровой реальности: разным GraphQL-серверам будет хотеться разных данных и PHP-шный бекенд будет вынужден удовлетворять запросы всех.
Я не работал с fractal, однако, навскидку, этот проект не выглядит хорошим кандидатом для расширения под наши хотелки:
  • fractal, как и многие другие решения, предлагает писать билдеры сущностей (в fractal они именуются трансформерами) — мы же, напротив, хотели уйти от кучи бесполезных классов, внутри которых делается что-нибудь типа
    return ['id' => (int) $item->id];
  • судя по устройству этих самых трансформеров, fractal умеет превращать модели в некие сущности, но не наборот: если клиент прислал нам некую сущность для сохранения, нам придётся руками преобразовывать её в модель (искать в базе, обновлять поля и т. д.)
  • fractal из-за своей архитектуры не умеет и, видимо, не научится делать eager-loading для связей: для lazy-loading они целый синтаксис сделали (довольно приятный, к слову), для eager — делай всё сам.
Если клиент хочет получить несколько коллекций сущностей за один вопрос, а мы у себя в коде будем собирать эти коллекции последовательно, в чем профит? Клиенту проще параллельно отправить несколько запросов.
Теперь я вас понял.

Получается, что запрос клиента обрабатывается GraphQL-сервером на Node, который отправляет запросы к PHP-бекенду, объединяет ответы и отдаёт результат клиенту обратно. В таком подходе лично мне не нравится наличие промежуточного слоя (Node), и, кроме того, есть ощущение, что со временем бизнес-логика начнёт размазываться по JS и PHP.
Ну, собственно, это я и имел ввиду — генерятся накие DTO без привязки к источникам данных (AR, Doctrine, вот это вот всё), верно?
Что вы конкретно имеете ввиду?
Ну хоть у кого-то взгляд за mature зацепился :)

1. Ну, спека-то, всё же, не наша. Смею предположить, что в момент перехода на JSON API вменяемой имплементации GraphQL на PHP не было. Однако, даже если я не прав, в GraphQL смущает другое: параллельное получение данных из разных источников на PHP хоть и возможно, но не без костылей.
2. Вариант с билдером показался более универсальным.
3. Swagger-UI.
Всё-таки, protobuf про сериализацию данных, а JSON API про их стандартизацию.

Тем не менее, любопытно, на каких платформах вы используете protobuf?
Насчёт клиентов вы правы, но как быть с сервером? Нам, как бекенду, важно не только договориться с клиентом о том, как будут выглядеть сущности в API, но и уметь генерировать эти сущности из моделей. Насколько я понимаю, для сервера swagger-gen может просто нагенерить пустых экшенов.
На данный момент для велосипеда актуализируется документация и специфичный для нашего проекта код выносится из кода велосипеда в код основного проекта. Следите за новостями в нашем блоге :)
Тогда возникнет соблазн поставить после слова «анонимность» тире. :)
Судя по общей позитивности поста — выдавали на участках. :)

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity