Мы, в компании XIAG, в разных проектах постоянно решаем одну и ту же задачу: как хранить и показывать бинарные пользовательские данные. Это могут быть логотипы компаний, PDF файлы с описанием вакансий или приветственное видео. Причем это содержание нужно показывать на страницах сайта самым разнообразным способом: лого должно быть нужного размера, PDF — в виде маленькой превью-картинки, а из видео нужно показать пару стоп-кадров.
Уверен, такая задача знакома всем веб-разработчикам. В этой статье мы хотим поделиться нашим решением проблемы, опубликованным под открытой лицензией на ГитХабе.
Познакомьтесь с веб-сервисом Barberry (https://github.com/Magomogo/Barberry), который мы успешно используем уже около года. Суть сервиса в том, что он хранит оригиналы загруженных документов и способен по-разному отдавать их, конвертируя на лету.
Веб-сервис с REST интерфейсом
Первая и очевидная мысль — решение стандартной задачи не должно быть частью конкретного приложения. Нам нужен изолированный сервис, на который можно возложить эту простую ответственность.
Barberry размещается на сервере отдельно и взаимодействует с миром по HTTP. Чтобы попробовать сервис в работе, необходимо инсталлировать https://github.com/Magomogo/barberry-service на ваш сервер. Мы уже сделали это у себя, демонстрацию работы сервиса можно увидеть по адресу http://barberry.xiag.ch
Загрузка
Для того, чтобы загрузить данные в Barberry, необходимо сделать POST запрос. Сервис определит Content-Type и сообщит уникальный идентификатор сохраненного документа.
Пример загрузки фотографии DSC01823.JPG, например в консоли командой curl:
$ curl -X POST -F file=@/tmp/DSC01823.JPG barberry.xiag.ch
Запрос:
POST / HTTP/1.1
-- данные --
Ответ:
HTTP/1.1 201 Created
{"id":"yPkjPk","contentType":"image/jpeg","ext":"jpg","length":218038,"filename":"DSC01823.JPG"}
JSON ответ сервера описывает полученный документ. Дальнейшее обращение к нему будет происходить по уникальному “id”:”yPkjPk”.
Выгрузка
Идентификатор загруженного документа необходимо сохранить на стороне вашего приложения. Он используется для выгрузки:
Запрос:
GET /yPkjPk.jpg HTTP/1.1
Ответ:
HTTP/1.1 200 OK
Content-Type: image/jpeg
В окне браузера появится изображение. Ничего особенного. Вся мощь Barberry раскрывается далее.
Конвертация на лету и кеширование
Что будет, если попросить документ в другом формате? Для этого к идентификатору документа необходимо дописать другое расширение.
Запрос:
GET /yPkjPk.gif HTTP/1.1
Ответ:
HTTP/1.1 200 OK
Content-Type: image/gif
Изображение изменится, сервис сконвертировал JPG -> GIF, и передал нам. Для конвертации был использован barberry-plugin-imagemagick, который берет на себя конвертацию изображений.
Запрос может быть еще более сложным:
Запрос:
GET /yPkjPk_200x200.gif HTTP/1.1
Изменится не только формат исходного изображения, но и размер. В общем случае после идентификатора документа идет произвольная команда, которая будет передана плагину, который будет производить конвертацию в нужный формат.
Если попросить странного, сервис ответит правильно:
Запрос:
GET /yPkjPk.pdf HTTP/1.1
Ответ:
HTTP/1.1 404 Not Found
Это значит, что сервис не нашел возможности конвертировать изображение в PDF документ. Конечно, никто не запрещает написать плагин для этого, и подключить к вашей установке Barberry.
О кешировании. Конвертация не происходит при каждом GET запросе. Веб-сервер сконфигурирован так, что запускает конвертер только если в кеше не нашлось необходимого файла. В примере используется apache с его rewrite модулем.
Гибкость
Несмотря на то, что задача стандартна, для разных проектов есть свои ньюансы. Архитектура Barberry позволяет создавать специфичные плагины, расширяя возможности по конвертации данных. Например, вместо плагина для работы с картинками github.com/Magomogo/barberry-plugin-imagemagick можно реализовать свой, добавляющий на изображение водяной знак вашего сайта.
Так у Barberry появились довольно экзотические способности:
- github.com/kevich/barberry-plugin-pdf — преобразование PDF в простой текст и изображения
- github.com/ykovaleva/barberry-plugin-webcapture — снимки веб-сайтов в интернете в виде изображений или PDF (используется webkit)
- github.com/jamayka/barberry-plugin-openoffice — конвертирование таблиц и документов XSL, DOC, PDF и всего остального, что умеет Open Office headless.
- github.com/ykovaleva/barberry-plugin-ffmpeg — работа с видео, получение стоп-кадров
Управление зависимостями отдано менеджеру пакетов composer. Чтобы создать barberry сервис для своего приложения, мы рекомендуем сделать форк https://github.com/Magomogo/barberry-service и добавлять свою специфику.
Например, заглянуть в composer.json и подключить необходимые вам плагины. Изначально подключен только плагин для работы с картинками:
"require": {
"barberry/barberry": "1.1.*",
"barberry/plugin-imagemagick": "1.0.*"
}
Чтобы расширить функциональность, можно подключить плагины, которые будут работать с документами других Content-Type.
Мониторинг
Как и любое веб-приложение, Barberry в продуктивном режиме должен быть подключен к системе мониторинга. По адресу barberry.xiag.ch/monitoring.php находится скрипт, который опрашивает все подключенные плагины и рапортует, всё ли в порядке.
Заключение
Описание деталей реализации находится за рамками этого поста. Заинтересованных приглашаем к сотрудничеству на страницах ГитХаба.
Автор: MaximG