Tequila - язык для продвинутой генерации JSON

  • 1,517 views
Uploaded on

 

More in: Technology , Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,517
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
6
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

  • - JavaScript Object Notation.
    - в переводе: Текстовый формат обмена данными, основанный на синтаксисе JavaScript
    - Сферический JSON в вакууме.
  • Где нужен JSON?
    Для начала давайте рассмотрим ситуации, когда возникает необходимость передавать данные в формате JSON
  • Когда у нас есть фронтенд на клиентской стороне например с динамической фильтрацией/сортировкой данных.
    Пример: http://ukijs.org/examples/core-examples/table/

  • Когда мы пишем backend для ExtJS, Flash, AIR-приложений

  • Или нам нужно выкатить API нашего приложения наружу

  • Как обычно отдается JSON из рельсового приложения?

  • Можно делать по старинке
  • Получаем вот такую нарядную кашу в контроллере
  • В Rails 2.3.3 решили разделить представление данных и непосредственно конвертирование.
    as_json формирует хэш, а to_json его тупо перегоняет в json

  • Все наши “нестандартности” теперь можно и нужно выносить в модель
  • А вернее в модели.
    В каждой модели где нам нужно поведение, отличное от стандартного, мы определяем метод as_json.

    Мы можем не вызывать super, а
  • Контроллеры теперь у нас гладкие и шелковистые.
    Fat model. Skinny controller.
    Все as_json теперь у нас просто вызываются по цепочке.
    Итого имеем:
    - метод-презентер в каждой из нужных нам моделей
    - некоторое количество методов-хелперов, чтобы “причесать” данные перед выдачей на клиент
    Это то, что сейчас называется Rails way.



  • нам нужно более чем одно представление модели в json
    Например, для страницы со списком пользователей мы хотим выдавать много информации о юзере, а в случае, когда мы инклюдим пользователя к коментарию, нам нужны только его login и id.
    Тогда нам некуда деваться, и, все места, в которых поведение отличается от дефолтного(заданного нами), опять писать ручками в контроллере

  • Так нельзя к сожалению
  • Но если сильно хочется, то можно.

  • Итого, вот на какие неприятности мы имеем шансы нарваться.

  • Если используется штатный to_json, при изменении структуры базы данных, изменяется структура JSON-данных


  • Нет простого способа вызвать метод с параметрами

  • При переопределении as_json в модели мы имеем только одно представление нашей модели. А иногда нужно больше

  • Если некоторые модели вынесены в плагины, использование as_json оборачивается рядом неудобств.
  • !! Вставить картинку
  • Какие задачи мы решали созданием текилы.



  • Чтобы это было красиво и наглядно. Как в HAML например.

  • Самое веселое в том, что мы делали это проект в рамках RailsRumble. И нам надо было успеть закончить его за два дня.


  • 1. код to json -> tequila
    2. оптимизируем
    3. выносим хелперы в шаблон
  • Фичи
    надо сделать по красивому примерчику на каждую фичу.
  • Отступо-ориентированное форматирование
    Как в python, HAML, SASS




  • можно переименовать название ассоциации
  • можно переименовать атрибуты и методы





  • Подклеивание has_one ассоциаций
  • Подклеивание has_one ассоциаций
    Это работает на сколь угодно вложенные ассоциации.


  • А теперь позначательная страничка о том как все это происходит
  • Мы берем наши кучерявые данные
  • Приводим их в приличный нужный нам вид
  • Доводим до кондиции
  • Доводим до кондиции
  • Treetop!






Transcript

  • 1. TEQUILA Язык для продвинутой генерации JSON Иван Немытченко г. Омск, компания JazzCloud
  • 2. JSON { “id” : 205633, “name” : “jQuery in Action”, “authors” : [“Yehuda Katz”, “Bear Bibeault”] }
  • 3. Когда нужен JSON?
  • 4. Когда нужен JSON? • Rich client
  • 5. Когда нужен JSON? • Rich client • ExtJS, Flash, AIR
  • 6. Когда нужен JSON? • Rich client • ExtJS, Flash, AIR • External API
  • 7. Как обычно отдается JSON?
  • 8. to_json render :json => @products.to_json(...)
  • 9. to_json @products.to_json( :methods => [:label, :confirmed?, :formatted_description, :comment_text, :tag_list, ...], :include => { :comments => { :only => [:comment, :id, :commenter_id], :methods => [:commenter_name, :date] }, :taggings => { :methods => [:date], :include => { :tag => { :only => [:name, :background, :foreground] }, :tagger => { :only => [:login] }}}})
  • 10. as_json render :json => @products
  • 11. переопределение as_json в модели class Product def as_json(options) super( :methods => [:label, :confirmed?, :formatted_description, :comment_text, :tag_list, ...], :include => { :comments => { :only => [:comment, :id, :commenter_id], :methods => [:commenter_name, :date]}, :taggings => { :methods => [:date], :include => { :tag => { :only =>[:name, :background, :foreground]}, :tagger => { :only => [:login] }}}} ) end end
  • 12. переопределение as_json в моделях class Product < AR::Base class Tagging def label; end def as_json # ... def confirmed?; end end #... def as_json class Tag super( def as_json # ... :methods => [:label, :confirmed?, end :formatted_description, :comment_text, :tag_list, ...], class User :include => { :comments, :taggings } def as_json # ... ) end end end class Comment < AR::Base def as_json super( :only => [:comment, :id, :commenter_id], :methods => [:commenter_name, :date] ) end end
  • 13. Гладкий и шелковистый контроллер class ProductsController < ApplicationController def index render :json => @products end end
  • 14. А что, если ...
  • 15. нужно более чем одно представление модели class ProductsController < ApplicationController def index render :json => @products.as_json(...) end end
  • 16. хочется передать параметр в метод render :json => @product.to_json( :methods => :favorited_by_user?(current_user) )
  • 17. хочется передать параметр в метод render :json => @product.to_json( я Так нельз :methods => :favorited_by_user?(current_user) )
  • 18. хочется передать параметр в метод render :json => @product.to_json( я Так нельз :methods => :favorited_by_user?(current_user) ) class Product < AR::Base   attr_accessor :current_user   def favorited_by_user?(user=nil)     user ||= current_user # ... Если си ль   end то можн но хочется, end о конеч но @product.current_user = current_user render :json => @product.to_json(:methods => :favorited_by_user?)
  • 19. Неприятности: • Каша из :include и :methods в сложных случаях
  • 20. Неприятности: • Каша из :include и :methods в сложных случаях • Структура базы меняется → Меняется JSON
  • 21. Неприятности: • Каша из :include и :methods в сложных случаях • Структура базы меняется → Меняется JSON • Модель засоряется мелкими методами, только чтобы “причесать” JSON output
  • 22. Неприятности: • Каша из :include и :methods в сложных случаях • Структура базы меняется → Меняется JSON • Модель засоряется мелкими методами, только чтобы “причесать” JSON output • Нельзя вызвать метод с параметрами
  • 23. Неприятности: • Каша из :include и :methods в сложных случаях • Структура базы меняется → Меняется JSON • Модель засоряется мелкими методами, только чтобы “причесать” JSON output • Нельзя вызвать метод с параметрами • Модель может иметь одно представление в JSON при использовании as_json
  • 24. Неприятности: • Каша из :include и :methods в сложных случаях • Структура базы меняется → Меняется JSON • Модель засоряется мелкими методами, только чтобы “причесать” JSON output • Нельзя вызвать метод с параметрами • Модель может иметь одно представление в JSON при использовании as_json • Некоторые модели вынесены в плагины
  • 25. Tequila
  • 26. Задачи: • Вынести логику представления в отдельный слой (presenter)
  • 27. Задачи: • Вынести логику представления в отдельный слой (presenter) • Очистить модели от методов-хелперов
  • 28. Задачи: • Вынести логику представления в отдельный слой (presenter) • Очистить модели от методов-хелперов • Вызов методов с параметрами
  • 29. Задачи: • Вынести логику представления в отдельный слой (presenter) • Очистить модели от методов-хелперов • Вызов методов с параметрами • Получить больший контроль над представлением данных
  • 30. Задачи: • Вынести логику представления в отдельный слой (presenter) • Очистить модели от методов-хелперов • Вызов методов с параметрами • Получить больший контроль над представлением данных • Чтобы красиво!
  • 31. Задачи: • Вынести логику представления в отдельный слой (presenter) • Очистить модели от методов-хелперов • Вызов методов с параметрами • Получить больший контроль над представлением данных • Чтобы красиво! • Успеть за 2 дня!!!
  • 32. Отступы -@humans => people   :only     .name => login   :code => enhanced_name     name + "!!!"   :code => hello_world     "Hello world!"   +pets     :except       .human_id       .pet_type_id     +toys       :methods         .railsize("$", price.to_s)
  • 33. Associations :include => { :association => {...}}
  • 34. Associations :include => { :association => {...}} +association
  • 35. Вызов методов :methods => [:calculate]
  • 36. Вызов методов :methods => [:calculate] :methods .calculate .favorited_by_user?(current_user)
  • 37. Переименование нод +favourites => faves
  • 38. Переименование нод :only .tag_id => id :methods .calculate => calculated
  • 39. Блоки кода :code => number_of_guests pluralize(number_of_guests,‘guest’)
  • 40. Блоки кода :code => formatted_price “$#{price}”
  • 41. Блоки кода :code => last_comment comments.last.comment if comments.any?
  • 42. Опциональный ключ -users [{ :only "user": { .username "username": "heather" }},{ "user": { "username": "george" }},{ "user": { "username": "frank" }},{ "user": { "username": "aaron" }}]
  • 43. Опциональный ключ -users~ [{ :only "username": "heather"},{ .username "username": "george"},{ "username": "frank"},{ "username": "elizabeth"} ]
  • 44. Подклеивание ассоциаций +tag {'tag' : :only {'label' : 'Happy Christmas!', 'tagger' : {'name' : 'Mr Lawrence"}} .label +tagger :only .name
  • 45. Подклеивание ассоциаций +tag {'tag' : :only {'label' : 'Happy Christmas!', 'tagger' : {'name' : 'Mr Lawrence"}} .label +tagger :only .name +tag {'tag' : :only {'label' : 'Happy Christmas!', 'tagger_name' : 'Mr Lawrence"}} .label <tagger :only .name => tagger_name
  • 46. Partials -users :only .name &shared/pets render :partial => ‘shared/pets’
  • 47. Комментарии +tag :only .label //temporarily disabled //<tagger // :only // .name => tagger_name
  • 48. Познавательная страничка
  • 49. Как использовать gem install tequila config.gem ‘tequila’ /app/views/users/index.json.jazz
  • 50. tequila-demo.heroku.com
  • 51. Планы по развитию Синтаксис ActiveRecord Error handling Syntax highlight support
  • 52. Спасибо, вопросы! github.com/inem/tequila inem.github.com/tequila twitter.com/inem twitter.com/0ex0 jazzcloud.net http://www.flickr.com/photos/tequilaphotos/