Your SlideShare is downloading. ×
Tequila - язык для продвинутой генерации JSON
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

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

1,785
views

Published on

Published in: Technology, Business

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,785
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
7
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/