The goal is to create an HTTP API for uploading, optimizing, and serving images.
- The API should expose an endpoint for uploading an image. After uploading, the image should be sent for optimization via a queue (e.g. RabbitMQ) to prevent excessive system load in case of many parallel image uploads and increase the system durability.
- Uploaded images should be taken from the queue one by one and optimized using the
github.com/h2non/bimg
go package (orgithub.com/nfnt/resize
package). For each original image, three smaller-size image variants should be generated and saved, with 75%, 50%, and 25% quality. - The API should expose an endpoint for downloading an image by ID. The endpoint should allow specifying the image optimization level using query parameters (e.g.
?quality=100/75/50/25
).
Create .env file with the following values
HTTP_HOST=localhost
HTTP_PORT=8000
# Change AMQP_HOST=localhost if you run the app not in via docker-compose
AMQP_USER=guest
AMQP_PASSWORD=guest
AMQP_HOST=rabbitmq
AMQP_PORT=5672
Use make to run docker-compose
make appUp
OR
Run rabbitmq instance
docker run -d --name softcery-rabit -p 5672:5672 rabbitmq:3.10.7-management
And run command
make run
- Add tests
- Add more logs
- Use interfaces for consumer and publisher
- Add support for other image extensions
-
В чергу відправляється слайс байтів зображення.
Які можуть бути недоліки такого підходу?
Як можна було б це реалізувати по-іншому?
-
При відвантаженні зображення користувачу не повертається його ID. Як потім отримати це зображення, не використовуючи
/images-list
роут? -
В статично-типізованих мовах програмування додавати тип змінної до назви - це погана звичка.
-
Робота з чергою не абстрагована, немає інтерфейсу та реалізації (про це ти написав у README).
-
Навіщо існує окремий сервіс
Publisher
? Чому б не використовувати інтерфейсrabbitmq.Publisher
? Черга не може одночасно відноситись до шару транспорту і сервісу. -
Чому стискання зображення знаходиться в шарі
repository
? Стискання - це бізнес-логіка, яка повинна знаходитись в сервісі. Необхідно додати інтерфейсResizer
з методом для оптимізації, який повинен викликатись в сервісі.Вигляд пакету, де в
resizer.go
знаходиться інтерфейс, а в інших файлах - реалізації, які імлементують цей інтерфейс. Таким чином в застосунку ми використовуємо лише інтерфейс і можемо з легкістю підміняти імлементації. -
В шарі domain знаходяться помилки, які використовуються на різних шарах. Проте, в domain повинні знаходитись лише критичні бізнес-сутності, такі як Image та можливі якості зображень (зараз вони оголошуються в
app.go
). Чи правильно те, що одні і ті ж помилки шейряться між різними шарами? -
Валідація на розмір зображення знаходиться в шарі контроллера, чи правильно це?
- Використана чиста архітектура, хоча потребує деяких покращень.
- Є розуміння, що черга - це шар транспорту.
- Виділений окремий пакет для роботи з файловою системою і є шар repository, який би використовував цей пакет і реалізовував отримання/зберігання зображень.
- Є
.gitignore
, тому у репозиторій потенційно не зможуть потрапити файли, які там не повинні там бути. - Описаний
docker-compose
. - Є невеликий
makefile
. - Є описаний README з інструкцією для запуску.
- Є конфігураційний файл з потрібними значеннями.
- Немає непотрібних коментарів.
- Код не залитий одним комітом, дотримано принципу атомарності. Всі меседжі зрозумілі і несуть в собі сенс. Для стандартизації меседжів можна використовувати, наприклад: https://www.conventionalcommits.org/en/v1.0.0/.