Symfony & Javascript. Combining the best of two worlds

17,815 views

Published on

Published in: Technology

Symfony & Javascript. Combining the best of two worlds

  1. 1. Symfony & JavaScriptCombining the best of two worlds Nacho Martín @nacmartin
  2. 2. Symfony & JavaScriptCombining the best of two worlds Nacho Martín @nacmartin
  3. 3. A bit of history
  4. 4. ClientServer
  5. 5. ClientServer
  6. 6. ClientServer
  7. 7. What’s that??
  8. 8. What’s that?? It’s just a JavaScript
  9. 9. ClientServer
  10. 10. ClientServer
  11. 11. ClientServer
  12. 12. ClientServer
  13. 13. ClientServer
  14. 14. Why should I care?
  15. 15. Users like it
  16. 16. Users like itYou want to do it
  17. 17. Users expect itYou want to do it
  18. 18. Users expect itYou need to do it
  19. 19. It’s still just a JavaScript
  20. 20. But, but...JavaScript is HARD
  21. 21. Sequential
  22. 22. Sequential
  23. 23. Sequential
  24. 24. Sequential
  25. 25. Sequential
  26. 26. Sequential
  27. 27. Sequential
  28. 28. Asynchronous
  29. 29. Asynchronous
  30. 30. Asynchronous
  31. 31. Asynchronous Call me back
  32. 32. Asynchronous
  33. 33. Asynchronous
  34. 34. Asynchronous Done !
  35. 35. Asynchronous
  36. 36. for(var i = 1; i <= 5; i++) { console.log(i);}
  37. 37. 1for(var i = 1; i <= 5; i++) { 2 console.log(i); 3} 4 5
  38. 38. for(var i = 1; i <= 5; i++) { setTimeout(function() { console.log(i); }, 100);}
  39. 39. 6for(var i = 1; i <= 5; i++) { setTimeout(function() { 6 console.log(i); 6 }, 100);} 6 6
  40. 40. for(var i = 1; i <= 5; i++) { (function() { var j = i; setTimeout( function() { console.log(j); }, 100); })();}
  41. 41. for(var i = 1; i <= 5; i++) { (function() { 1 var j = i; setTimeout( 2 function() { 3 console.log(j); 4 }, 100); })(); 5}
  42. 42. Callback nesting
  43. 43. Callback nesting• Events
  44. 44. Callback nesting• Events• Async.js
  45. 45. “this” gotchavar o = {};o.prop = {};var o.f1 = function(){ var that = this; this.prop.active = false; var activate = function(){ that.prop.active = true; }; activate();};
  46. 46. “this” gotchavar o = {};o.prop = {};var o.f1 = function(){ var that = this; this.prop.active = false; var activate = function(){ that.prop.active = true; }; activate();};
  47. 47. http://www.flickr.com/photos/bensonkua/3161323177/in/photostream/
  48. 48. Douglas Crockford
  49. 49. But, but...
  50. 50. But, but...•Can be ugly
  51. 51. But, but...•Can be ugly•Tons of crappy code
  52. 52. But, but...•Can be ugly•Tons of crappy code•Inconsistencies
  53. 53. But, but...•Can be ugly•Tons of crappy code•Inconsistencies•Weird stuff inside
  54. 54. But, but...•Can be ugly •Huge community•Tons of crappy code•Inconsistencies•Weird stuff inside
  55. 55. But, but...•Can be ugly •Huge community•Tons of crappy code •Easy to get help•Inconsistencies•Weird stuff inside
  56. 56. But, but...•Can be ugly •Huge community•Tons of crappy code •Easy to get help•Inconsistencies •Low entry barrier•Weird stuff inside
  57. 57. But, but...•Can be ugly •Huge community•Tons of crappy code •Easy to get help•Inconsistencies •Low entry barrier•Weird stuff inside •Is everywhere
  58. 58. http://www.flickr.com/photos/73935252@N00/181308667
  59. 59. The team needs discipline compromise readablityhttp://www.flickr.com/photos/39865537@N03/4395203300 http://www.flickr.com/photos/73935252@N00/181308667
  60. 60. Pick your battles http://www.flickr.com/photos/43322231@N07/5589147122
  61. 61. is the perfectcomplement
  62. 62. is the perfectcomplement
  63. 63. Client side JS
  64. 64. Level I Text http://www.flickr.com/photos/lecates/307250887/
  65. 65. Assetic
  66. 66. FOSJsRouterBundlePHP/** * @Route ("/foo/{id}/bar", name="my_route_to_expose", options={"expose"=true}) */public function exposedAction($foo)JSRouting.generate(my_route_to_expose, { id: 10 });// /foo/10/bar
  67. 67. Level II http://www.flickr.com/photos/49766155@N07/4945673508 Text
  68. 68. ClientServer
  69. 69. ClientServer
  70. 70. ClientServer
  71. 71. Then Symfony...?
  72. 72. Then Symfony...?Still does almost everything
  73. 73. •Small library•Stable for JS world•Active•Open Source•Popular
  74. 74. • Models • Models• Collections • Repositories• Views • Controllers• Templates • Views• Routing • Routing
  75. 75. ViewModel Model
  76. 76. View Books=new Backbone.collection();Model Model Books.url = ‘/books’; Books.fetch()
  77. 77. View Books=new Backbone.collection();Model Model Books.url = ‘/books’; Books.fetch() GET /books
  78. 78. View Books=new Backbone.collection();Model Model Books.url = ‘/books’; Books.fetch() GET /books
  79. 79. View Books.on(‘reset’, this.render); Books=new Backbone.collection();Model Model Books.url = ‘/books’; Books.fetch() GET /books
  80. 80. View Books.on(‘reset’, this.render); Books=new Backbone.collection();Model Model Books.url = ‘/books’; Books.fetch() GET /books
  81. 81. View Books.on(‘reset’, this.render); Books=new Backbone.collection();Model Model Books.url = ‘/books’; Books.fetch() GET /books
  82. 82. ViewModel Model
  83. 83. events: { ‘click .mybutton’: ‘doStuffAndSave’} ViewModel Model
  84. 84. events: { ‘click .mybutton’: ‘doStuffAndSave’} ViewModel Model
  85. 85. events: { ‘click .mybutton’: ‘doStuffAndSave’} View doStuffAndSave: function() { var book = Books.get(3); book.stuff(); Books.get(3).save(); }Model Model
  86. 86. events: { ‘click .mybutton’: ‘doStuffAndSave’} View doStuffAndSave: function() { var book = Books.get(3); book.stuff(); Books.get(3).save(); }Model Model
  87. 87. events: { ‘click .mybutton’: ‘doStuffAndSave’} View doStuffAndSave: function() { var book = Books.get(3); book.stuff(); Books.get(3).save(); }Model Model PUT /books/3
  88. 88. Build an API http://www.flickr.com/photos/kaptainkobold/3203311346/
  89. 89. FOSRestBundle /** * @View() * GET /users */public function getUsersAction(){ return $this->getDoctrine()->getRepository(myBundle:User)->findAll();}
  90. 90. [ Response {“id”:1, “name”:”nacho”, “password”: “X$$%$X”, “email”:”nacho@limenius.com”, “profile”: { “id”:3, “phone”: “666666666”} } }, {...},]
  91. 91. JMSSerializerMyBundleUser: exclusion_policy: ALL properties: id: expose: true name: expose: true email: expose: true
  92. 92. JMSSerializerMyBundleUser: exclusion_policy: ALL properties: id: expose: true name: expose: true email: expose: true callback_methods: pre_serialize: serializeProfile
  93. 93. JMSSerializerpublic function serializeProfile(){ $this->phone = $this->profile->getPhone(); $this->profile = null;}
  94. 94. Response[ {“id”:1, “name”:”nacho”, “email”:”nacho@limenius.com”, “phone”: “666666666” }, {...},]
  95. 95. Deserialize forms•SimpleThingsFormSerializeBundle•Symfony-cmf/CreateBundle•http://williamdurand.fr/2012/08/02/ rest-apis-with-symfony2-the-right- way/
  96. 96. NelmioApiDocBundle
  97. 97. Twig.js Twig
  98. 98. Twig.js Backbone Twig
  99. 99. Twig.js{% javascripts "@MyBundle/Resources/views/tmpl.html.twig" filter="twig_js, ?yui_js" %} <script language="javascript" src="{{ asset_url }}"> </script>{% endjavascripts %}
  100. 100. Server side JS
  101. 101. ClientServer
  102. 102. ClientServer
  103. 103. ClientServer
  104. 104. ClientServer
  105. 105. What for
  106. 106. What for•Streaming data
  107. 107. What for•Streaming data•Soft realtime •Chats •Notifications
  108. 108. Challenges to face
  109. 109. Challenges to face•Organization of a big code base
  110. 110. Challenges to face•Organization of a big code base•General lower level of abstraction
  111. 111. Challenges to face•Organization of a big code base•General lower level of abstraction•Deployment •Serving static files
  112. 112. Challenges to face•Organization of a big code base•General lower level of abstraction•Deployment •Serving static files
  113. 113. Use case:Notifications
  114. 114.
  115. 115.
  116. 116.
  117. 117.
  118. 118. Websocketsio.sockets.on(connection, function (socket) { socket.join(user1); socket.broadcast.to(user1).emit(Hi user 1);});
  119. 119. Dealing with secretshttp://www.flickr.com/photos/45940879@N04/6277724736
  120. 120. httpMQ
  121. 121. The pusher waysecret secret
  122. 122. The pusher way so ck et idsecret secret
  123. 123. The pusher way id & e so ck am ck so l n et et ne id an chsecret secret
  124. 124. ke y:s ign at usecret ch re an ne so l n ck am et e id & so ck et id The pusher waysecret
  125. 125. secret &The pusher way e am re l n tu ne na an sig ch y: ke id et ck so id & e et ck am so l n ne rean ch secret u at ign y:s ke
  126. 126. Deploy
  127. 127. Deploy
  128. 128. Deploy
  129. 129. It’s just a JavaScript
  130. 130. Thanks Nacho Martín @nacmartin nacho@limenius.comhttp://www.flickr.com/photos/95572727@N00/2380543038

×