136
Symfony & JavaScript Combining the best of two worlds Nacho Martín @nacmartin

Symfony & Javascript. Combining the best of two worlds

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Symfony & Javascript. Combining the best of two worlds

Symfony & JavaScript

Combining the best of two worlds

Nacho Martín@nacmartin

Page 2: Symfony & Javascript. Combining the best of two worlds

Symfony & JavaScript

Combining the best of two worlds

Nacho Martín@nacmartin

Page 3: Symfony & Javascript. Combining the best of two worlds

A bit of history

Page 4: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 5: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 6: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 7: Symfony & Javascript. Combining the best of two worlds

What’s that??

Page 8: Symfony & Javascript. Combining the best of two worlds

What’s that??

It’s just a JavaScript

Page 9: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 10: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 11: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 12: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 13: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 14: Symfony & Javascript. Combining the best of two worlds

Why should I care?

Page 15: Symfony & Javascript. Combining the best of two worlds

Users like it

Page 16: Symfony & Javascript. Combining the best of two worlds

Users like it

You want to do it

Page 17: Symfony & Javascript. Combining the best of two worlds

Users it

You want to do it

expect

Page 18: Symfony & Javascript. Combining the best of two worlds

Users it

You to do itneed

expect

Page 19: Symfony & Javascript. Combining the best of two worlds

It’s still just a JavaScript

Page 20: Symfony & Javascript. Combining the best of two worlds

But, but...

JavaScript is HARD

Page 21: Symfony & Javascript. Combining the best of two worlds

Sequential

Page 22: Symfony & Javascript. Combining the best of two worlds

Sequential

Page 23: Symfony & Javascript. Combining the best of two worlds

Sequential

Page 24: Symfony & Javascript. Combining the best of two worlds

Sequential

Page 25: Symfony & Javascript. Combining the best of two worlds

Sequential

Page 26: Symfony & Javascript. Combining the best of two worlds

Sequential

Page 27: Symfony & Javascript. Combining the best of two worlds

Sequential

Page 28: Symfony & Javascript. Combining the best of two worlds

Asynchronous

Page 29: Symfony & Javascript. Combining the best of two worlds

Asynchronous

Page 30: Symfony & Javascript. Combining the best of two worlds

Asynchronous

Page 31: Symfony & Javascript. Combining the best of two worlds

AsynchronousCall me back

Page 32: Symfony & Javascript. Combining the best of two worlds

Asynchronous

Page 33: Symfony & Javascript. Combining the best of two worlds

Asynchronous

Page 34: Symfony & Javascript. Combining the best of two worlds

Asynchronous

Done !

Page 35: Symfony & Javascript. Combining the best of two worlds

Asynchronous

Page 36: Symfony & Javascript. Combining the best of two worlds

for(var i = 1; i <= 5; i++) { console.log(i);}

Page 37: Symfony & Javascript. Combining the best of two worlds

for(var i = 1; i <= 5; i++) { console.log(i);}

12345

Page 38: Symfony & Javascript. Combining the best of two worlds

for(var i = 1; i <= 5; i++) { setTimeout(function() { console.log(i); }, 100);}

Page 39: Symfony & Javascript. Combining the best of two worlds

for(var i = 1; i <= 5; i++) { setTimeout(function() { console.log(i); }, 100);}

66666

Page 40: Symfony & Javascript. Combining the best of two worlds

for(var i = 1; i <= 5; i++) { (function() { var j = i; setTimeout( function() { console.log(j); }, 100); })();}

Page 41: Symfony & Javascript. Combining the best of two worlds

for(var i = 1; i <= 5; i++) { (function() { var j = i; setTimeout( function() { console.log(j); }, 100); })();}

12345

Page 42: Symfony & Javascript. Combining the best of two worlds

Callback nesting

Page 43: Symfony & Javascript. Combining the best of two worlds

Callback nesting

• Events

Page 44: Symfony & Javascript. Combining the best of two worlds

Callback nesting

• Events• Async.js

Page 45: Symfony & Javascript. Combining the best of two worlds

“this” gotchavar o = {};o.prop = {};

var o.f1 = function(){ var that = this;

this.prop.active = false;

var activate = function(){ that.prop.active = true;

};

activate();

};

Page 46: Symfony & Javascript. Combining the best of two worlds

“this” gotchavar o = {};o.prop = {};

var o.f1 = function(){ var that = this;

this.prop.active = false;

var activate = function(){ that.prop.active = true;

};

activate();

};

Page 47: Symfony & Javascript. Combining the best of two worlds

http://www.flickr.com/photos/bensonkua/3161323177/in/photostream/

Page 48: Symfony & Javascript. Combining the best of two worlds

Douglas Crockford

Page 49: Symfony & Javascript. Combining the best of two worlds
Page 50: Symfony & Javascript. Combining the best of two worlds

But, but...

Page 51: Symfony & Javascript. Combining the best of two worlds

But, but...

•Can be ugly

Page 52: Symfony & Javascript. Combining the best of two worlds

But, but...

•Can be ugly

•Tons of crappy code

Page 53: Symfony & Javascript. Combining the best of two worlds

But, but...

•Can be ugly

•Tons of crappy code

•Inconsistencies

Page 54: Symfony & Javascript. Combining the best of two worlds

But, but...

•Can be ugly

•Tons of crappy code

•Inconsistencies

•Weird stuff inside

Page 55: Symfony & Javascript. Combining the best of two worlds

But, but...

•Can be ugly

•Tons of crappy code

•Inconsistencies

•Weird stuff inside

•Huge community

Page 56: Symfony & Javascript. Combining the best of two worlds

But, but...

•Can be ugly

•Tons of crappy code

•Inconsistencies

•Weird stuff inside

•Huge community

•Easy to get help

Page 57: Symfony & Javascript. Combining the best of two worlds

But, but...

•Can be ugly

•Tons of crappy code

•Inconsistencies

•Weird stuff inside

•Huge community

•Easy to get help

•Low entry barrier

Page 58: Symfony & Javascript. Combining the best of two worlds

But, but...

•Can be ugly

•Tons of crappy code

•Inconsistencies

•Weird stuff inside

•Huge community

•Easy to get help

•Low entry barrier

•Is everywhere

Page 60: Symfony & Javascript. Combining the best of two worlds

http://www.flickr.com/photos/73935252@N00/181308667http://www.flickr.com/photos/39865537@N03/4395203300

The team needs discipline

compromise readablity

Page 61: Symfony & Javascript. Combining the best of two worlds

http://www.flickr.com/photos/43322231@N07/5589147122

Pick your battles

Page 62: Symfony & Javascript. Combining the best of two worlds

is the perfect complement

Page 63: Symfony & Javascript. Combining the best of two worlds

is the perfect complement

Page 64: Symfony & Javascript. Combining the best of two worlds

Client side JS

Page 65: Symfony & Javascript. Combining the best of two worlds

Text

Level I

http://www.flickr.com/photos/lecates/307250887/

Page 66: Symfony & Javascript. Combining the best of two worlds

Assetic

Page 67: Symfony & Javascript. Combining the best of two worlds

FOSJsRouterBundle

/** * @Route ("/foo/{id}/bar", name="my_route_to_expose", options={"expose"=true}) */public function exposedAction($foo)

Routing.generate('my_route_to_expose', { id: 10 });// /foo/10/bar

PHP

JS

Page 68: Symfony & Javascript. Combining the best of two worlds

Text

Level II

http://www.flickr.com/photos/49766155@N07/4945673508

Page 69: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 70: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 71: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 72: Symfony & Javascript. Combining the best of two worlds

Then Symfony...?

Page 73: Symfony & Javascript. Combining the best of two worlds

Then Symfony...?

Still does almost everything

Page 74: Symfony & Javascript. Combining the best of two worlds

•Small library

•Stable for JS world

•Active

•Open Source

•Popular

Page 75: Symfony & Javascript. Combining the best of two worlds

•Models

•Collections

•Views

•Templates

•Routing

•Models

•Repositories

•Controllers

•Views

•Routing

Page 76: Symfony & Javascript. Combining the best of two worlds

ModelModel

View

Page 77: Symfony & Javascript. Combining the best of two worlds

ModelModel

View

Books.fetch()

Books=new Backbone.collection();

Books.url = ‘/books’;

Page 78: Symfony & Javascript. Combining the best of two worlds

ModelModel

View

GET /books

Books.fetch()

Books=new Backbone.collection();

Books.url = ‘/books’;

Page 79: Symfony & Javascript. Combining the best of two worlds

ModelModel

View

GET /books

Books.fetch()

Books=new Backbone.collection();

Books.url = ‘/books’;

Page 80: Symfony & Javascript. Combining the best of two worlds

ModelModel

View

GET /books

Books.fetch()

Books=new Backbone.collection();

Books.url = ‘/books’;

Books.on(‘reset’, this.render);

Page 81: Symfony & Javascript. Combining the best of two worlds

ModelModel

View

GET /books

Books.fetch()

Books=new Backbone.collection();

Books.url = ‘/books’;

Books.on(‘reset’, this.render);

Page 82: Symfony & Javascript. Combining the best of two worlds

ModelModel

View

GET /books

Books.fetch()

Books=new Backbone.collection();

Books.url = ‘/books’;

Books.on(‘reset’, this.render);

Page 83: Symfony & Javascript. Combining the best of two worlds

ModelModel

View

Page 84: Symfony & Javascript. Combining the best of two worlds

ModelModel

Viewevents: { ‘click .mybutton’: ‘doStuffAndSave’}

Page 85: Symfony & Javascript. Combining the best of two worlds

ModelModel

Viewevents: { ‘click .mybutton’: ‘doStuffAndSave’}

Page 86: Symfony & Javascript. Combining the best of two worlds

ModelModel

Viewevents: { ‘click .mybutton’: ‘doStuffAndSave’}

doStuffAndSave: function() { var book = Books.get(3); book.stuff(); Books.get(3).save();}

Page 87: Symfony & Javascript. Combining the best of two worlds

ModelModel

Viewevents: { ‘click .mybutton’: ‘doStuffAndSave’}

doStuffAndSave: function() { var book = Books.get(3); book.stuff(); Books.get(3).save();}

Page 88: Symfony & Javascript. Combining the best of two worlds

ModelModel

View

PUT /books/3

events: { ‘click .mybutton’: ‘doStuffAndSave’}

doStuffAndSave: function() { var book = Books.get(3); book.stuff(); Books.get(3).save();}

Page 89: Symfony & Javascript. Combining the best of two worlds

http://www.flickr.com/photos/kaptainkobold/3203311346/

Build an API

Page 90: Symfony & Javascript. Combining the best of two worlds

FOSRestBundle

/** * @View() * GET /users */ public function getUsersAction() { return $this->getDoctrine()->getRepository('myBundle:User')->findAll(); }

Page 91: Symfony & Javascript. Combining the best of two worlds

Response[ {“id”:1, “name”:”nacho”, “password”: “X$$%$X”, “email”:”[email protected]”, “profile”: { “id”:3, “phone”: “666666666”} } }, {...},]

Page 92: Symfony & Javascript. Combining the best of two worlds

JMSSerializerMyBundle\User: exclusion_policy: ALL properties: id: expose: true name: expose: true email: expose: true

Page 93: Symfony & Javascript. Combining the best of two worlds

MyBundle\User: exclusion_policy: ALL properties: id: expose: true name: expose: true email: expose: true callback_methods: pre_serialize: serializeProfile

JMSSerializer

Page 94: Symfony & Javascript. Combining the best of two worlds

JMSSerializer

public function serializeProfile(){ $this->phone = $this->profile->getPhone(); $this->profile = null;}

Page 95: Symfony & Javascript. Combining the best of two worlds

Response

[ {“id”:1, “name”:”nacho”, “email”:”[email protected]”, “phone”: “666666666” }, {...},]

Page 97: Symfony & Javascript. Combining the best of two worlds

NelmioApiDocBundle

Page 98: Symfony & Javascript. Combining the best of two worlds

Twig.js

Twig

Page 99: Symfony & Javascript. Combining the best of two worlds

Twig.js

TwigBackbone

Page 100: Symfony & Javascript. Combining the best of two worlds

Twig.js

{% javascripts "@MyBundle/Resources/views/tmpl.html.twig" filter="twig_js, ?yui_js" %} <script language="javascript" src="{{ asset_url }}"> </script>{% endjavascripts %}

Page 101: Symfony & Javascript. Combining the best of two worlds

Server side JS

Page 102: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 103: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 104: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 105: Symfony & Javascript. Combining the best of two worlds

Client

Server

Page 106: Symfony & Javascript. Combining the best of two worlds
Page 107: Symfony & Javascript. Combining the best of two worlds

What for

Page 108: Symfony & Javascript. Combining the best of two worlds

•Streaming data

What for

Page 109: Symfony & Javascript. Combining the best of two worlds

•Streaming data

•Soft realtime

•Chats

•Notifications

What for

Page 110: Symfony & Javascript. Combining the best of two worlds

Challenges to face

Page 111: Symfony & Javascript. Combining the best of two worlds

•Organization of a big code base

Challenges to face

Page 112: Symfony & Javascript. Combining the best of two worlds

•Organization of a big code base

•General lower level of abstraction

Challenges to face

Page 113: Symfony & Javascript. Combining the best of two worlds

•Organization of a big code base

•General lower level of abstraction

•Deployment

•Serving static files

Challenges to face

Page 114: Symfony & Javascript. Combining the best of two worlds

•Organization of a big code base

•General lower level of abstraction

•Deployment

•Serving static files

Challenges to face

Page 115: Symfony & Javascript. Combining the best of two worlds

Use case:Notifications

Page 116: Symfony & Javascript. Combining the best of two worlds
Page 117: Symfony & Javascript. Combining the best of two worlds
Page 118: Symfony & Javascript. Combining the best of two worlds

Page 119: Symfony & Javascript. Combining the best of two worlds

Page 120: Symfony & Javascript. Combining the best of two worlds

Page 121: Symfony & Javascript. Combining the best of two worlds

Page 122: Symfony & Javascript. Combining the best of two worlds

Websockets

io.sockets.on('connection', function (socket) { socket.join('user1'); socket.broadcast.to('user1').emit('Hi user 1');});

Page 123: Symfony & Javascript. Combining the best of two worlds

http://www.flickr.com/photos/45940879@N04/6277724736

Dealing with secrets

Page 124: Symfony & Javascript. Combining the best of two worlds
Page 125: Symfony & Javascript. Combining the best of two worlds

http

MQ

Page 126: Symfony & Javascript. Combining the best of two worlds

The pusher way

secret secret

Page 127: Symfony & Javascript. Combining the best of two worlds

The pusher way

socket id

secret secret

Page 128: Symfony & Javascript. Combining the best of two worlds

The pusher way

socket id

chan

nel n

ame &

sock

et id

secret secret

Page 129: Symfony & Javascript. Combining the best of two worlds

The pusher way

socket id

chan

nel n

ame &

sock

et id

key:s

ignatu

re

secret secret

Page 130: Symfony & Javascript. Combining the best of two worlds

The pusher way

socket id

chan

nel n

ame &

sock

et id

key:s

ignatu

rechannel name &

key:signature

secret secret

Page 131: Symfony & Javascript. Combining the best of two worlds

Deploy

Page 132: Symfony & Javascript. Combining the best of two worlds

Deploy

Page 133: Symfony & Javascript. Combining the best of two worlds

Deploy

Page 134: Symfony & Javascript. Combining the best of two worlds
Page 135: Symfony & Javascript. Combining the best of two worlds

It’s just a JavaScript