Краткий обзор способов формирования JSON
На сегодняшний день в Rails имеются следующие способы сериализации объектов в JSON:
- Вызов to_json() напрямую.
- RABL
- Active model serializers
- JBuilder
Первый способ идеально подходит для ситуаций, когда не требуется сериализовать вложенные объекты.
@posts.to_json(:include => [...], :methods => [...])
Однако, формируя JSON ответ со списком моделей, возникает необходимость сериализовать связанные модели в нужном виде.
JBuilder
По личному опыту, наиболее органично вписывающимся в Rails-разработку является, включенный по умолчанию в Rails 4, JBuilder.
json.extract! message, :id, :content, :chat_id
json.user do
json.cache!(["user_", message.user_id]) do
json.partial! 'users/user', user: message.user
end
end
RABL
RABL, по сравнению с остальными гемами, представляется древним из-за синтаксиса и неповоротливым из-за низкой производительности монстром.
collection :@messages
attributes :id, :content, :chat_id
child(:user) { attributes :name }
node(:read) { |message| message.read_by?(@user) }
ActiveModel::Serializer
Active model serializers предлагает описывать JSON в виде ruby классов, без придуманного синтаксиса, что уменьшает зоопарк использования различных DSL в проекте.
Решение проблем с производительностью
Небольшое сравнение
Тестовые данные: 1000 типичных сообщений с отправителем и дополнительными полями.
JSON:
{
id: 1,
content: "Lorem",
chat_id: 1,
created_at: "2014-06-18T21:47:49.363Z",
kind: 0,
formatted_content: "<span>Lorem</span>",
user: {
id: 1,
name: "Ivan Petrov",
image: "https://lh6.googleusercontent.com/photo.jpg"
},
files: [ ],
links: [ ]
}
to_json: 0.2ms
Oj: 0.1ms
JBuilder: 129.0ms
JBuilder with OJ: 88.0ms
Числа усреднены, но общая картина ясна. Сравнивать различные гемы между собой не имеет смысла, так как разница не существенна, но объективно, JBuilder является самым быстрым на сегодняшний день.
За удобство приходится платить скоростью. Все описанные гемы по скорости проигрывают методу to_json() в несколько раз.
Использование JBuilder без настройки будет стоить вам ~600.0ms
Существует несколько сопособов ускорить JBuilder:
- Подключить гемы: oj, oj_mimic_json, multi_json.
Добавить в инициализациюMultiJson.use(:oj)
Что заменит стандартный сериализатор на более быстрый Oj. - Не использовать partials, существенно замедляющие JBuilder. Давно созданн issues, в котором, не смотря на закрытый статус, данная проблема фактически не решена
- Кешировать шаблоны, используя встроенный в JBuilder метод cache!
В проекте Staply (почти открытая бета) мы использовали JBuilder, только на начальном этапе разработки, постепенно переходя на формирование JSON вручную при помощи to_json(). Что является оличной демонстрации всей концепции Rails, обеспечивающих довольно быструю и лёгкую разработку в начале с оптимизацией в конце.
Автор: maks_ohs