Условия задачи:
На страницу вывести форму с полями input:email, select:категория из http://www.icndb.com/api/ При заполнении формы на емейл нужно отправить письмо с темой "Случайная шутка из %имя категории%" В теле письма должна быть случайная шутка из этой категории Эту же шутку нужно записать в файл на диске
Требования:
Работу с API необходимо реализовать самому с использованием http://docs.guzzlephp.org/en/stable/ Приложение должно быть на базе Symfony (3 или 4)
Пожелания:
Написание тестов будет плюсом.
Упор делайте не на скорость выполнения, а на качество исполнения. Предоставленное решение мы будем оценивать на соответствие принципам SOLID и чистого кода.
Рекомендуемые книги:
Martin, Robert C. (2009). Clean Code: A Handbook of Agile Software Craftsmanship
Principles of Package Design Preparing your code for reuse Matthias Noback
A Year With Symfony Writing healthy, reusable Symfony2 code Matthias Noback
Забавляет приведеннный список книг. Конечно упор на качество, а не на скорость. Но вряд ли работодатель будет столько ждать, пока я изучу приведенные книги :) Я читал одну из них - "Чистый код" Мартина, изучение еще не закончил. На том и стою.
Guzzle. Я с этой библиотекой напрямую не работал, только через адаптер движка (Laravel). Для использования этой библиотеки в Symfony есть как минимум два пакета. Использовал один из них - CsaGuzzleBundle
, т.к. не смог настроить через конфиги Symfony библиотеку, скачанную отдельно. В конфиге пакета хардкодом забит адрес http://api.icndb.com/, что по сути так же деревянно, как и внедрять Guzzle без посредников.
Все исходники собраны в каталоге [src/joker/], кроме статики и представлений, разумеется.
Каталог для сохранения шуток - [storage/jokes/].
Список категорий кешируется на сутки. Кеш в Redis.
В настройках почтовика прописана моя заглушка на mailtrap.io.
Метод контроллера JokerController::joking()
не содержит бизнес-логику. Он выполняет в точности то, что должен делать контроллер: управляет процессом. Можно было бы перенести все действия (получить шутку, отправить, сохранить) в метод сервиса, но это был бы фасад, не меняющий суть. При этом такой сервис нарушит принцип SRP, т.к. делает три разных вещи. А вот метод контроллера справляется со своей задачей.
Unit-тесты не писал, т.к. бизнес-логики нет вообще. Приемочные тесты на контроллеры не писал, т.к. не считаю это критически важным, в отличие от unit-тестов.
Список категорий GET http://api.icndb.com/categories
Случайная шутка в категории GET http://api.icndb.com/jokes/random?limitTo=[nerdy]
Надо бы удалить из проекта лишние каталоги. Symfony оказывается может создать более компактный boilerplate:
composer create-project symfony/skeleton my-project
Только при этом придется вручную добавлять нужные пакеты и библиотеки.