Мы создаем микросервисную архитектуру для наших проектов, в которой в основном интерфейсные приложения Symfony взаимодействуют с внутренними API RESTful.
Проблема в том, что этот подход нарушает управление сущностями Symfony, в значительной степени полагаясь на Doctrine с базой данных. Там, где Symfony обычно обрабатывает сущности с помощью Doctrine, автоматизируя большую часть работы, это не может быть легко воспроизведено, когда нам нужно получить доступ к внешним данным из API.
Например, для объекта Client:
- Используя Doctrine, мы просто должны определить наш класс Client, и теперь стало легко создавать, обновлять, извлекать наших клиентов.
- Используя подход REST API, клиенты доступны через API, но у нас много работы, чтобы определить, как клиент создается (POST), обновляется (PUT), извлекается (GET) и т. Д.
Следует отметить, что клиенты используются несколькими приложениями, а не только интерфейсным приложением, следовательно, выделенным API.
Должны ли мы создавать классы с сущностно-подобными методами, скрывающими сложность вызовов API, импортирующими все данные API локально и получающими к ним доступ через Doctrine или любым другим способом?
Ответы:
Я сделал проект на основе Symfony, который использует внешний API (JSON); я создал независимую клиентскую библиотеку («клиентская библиотека» - часть программного обеспечения, пакет композитора) с собственным набором сущностей (POPO); он интегрируется с платформой с использованием интерфейсов, предоставляемых Symfony (например, путем простого создания пользовательского поставщика ).
Клиент делает http-вызовы «закулисными», что важно для будущих возможностей тестирования. Вы не хотите раскрывать способ общения с источником данных, а также не хотите, чтобы ваши тесты опирались на живые API.
Интерфейс клиентской библиотеки (пример того, как это может выглядеть):
Клиентская библиотека внутренне использует Guzzle для связи и компонент Doctrine Cache для кэширования результатов. Отображение между объектами-сущностями и json было сделано мапперами, которые когда-то писали - менялись не очень часто (или вообще не происходили). В этом случае я бы предложил использовать JMS Serializer для автоматического преобразования в JSON и обратно (я предполагаю, что вы используете JSON).
Вам понадобится хороший механизм кэширования и локальное хранилище, например, Redis. Выполнение api-вызовов для каждого запроса приложения убьет ваш сервер и резко замедлит работу вашего приложения. Очень важно понимать, как работают http-кэши. Если ваш API-интерфейс не использует кэширующие заголовки (или использует его неясным образом), будет очень сложно и ресурсоемко отслеживать изменения.
Вам также захочется подумать о том, как должен вести себя клиент в случае разрыва соединения - должен ли клиент использовать заблокированные данные? Было бы неплохо использовать прокси-сервер между вашим приложением и API. В этом случае прокси (например, Varnish) может ускорить ваши запросы, а также обновить заблокированные данные в фоновом режиме, не замедляя работу приложения. Он также будет поддерживать ваш сайт в сети в случае сбоя API. В то же время вы не сможете записывать данные, но ваши пользователи по-прежнему смогут просматривать кэшированные данные.
И если говорить о доктрине, см. « Закон орудия ».
источник
Doctrine - это уровень доступа к базе данных. Вы не хотите получить доступ к базе данных, но apis. Вы все еще можете создать Entity, но затем как простой объект, который не должен расширять нашу реализацию (popo). Он должен иметь репозиторий, который реализует все методы CRUD. В этом случае вызовы API вместо базы данных. Я бы создал интерфейс для этого. Приложение не должно чувствовать себя по-другому, за исключением того, что вы должны учитывать, что микросервис может не отвечать.
источник
К вашему сведению, теперь есть компонент HttpClient для v4.3.
https://symfony.com/blog/new-in-symfony-4-3-httpclient-component
источник