SlideShare une entreprise Scribd logo
1  sur  47
Building SPA with Symfony2 and 
AngularJS 
Antonio Perić-Mažar 
02.10.2014, ZgPHP Conference 2014 
https://joind.in/12007
About me 
• Antonio Perić-Mažar, 
mag. ing. comp. 
• CEO @ locastic 
• Software developer, Symfony2 
• Sylius Awesome Contributor :) 
• www.locastic.com 
• antonio@locastic.com 
• twitter: @antonioperic
Who we are? 
• locastic (www.locastic.com) 
• Web and mobile development 
• UI/UX design 
• Located in Split, Croatia
Our works?
Symfony2 AngularJS 
Usage, language Backend, PHP Frontend, Javascript 
Dependency Injection Yes Yes 
Templating Twig HTML 
Form component Yes Yes 
Routing component Yes Yes 
MVC Yes Yes 
Testable Yes Yes 
Services Yes Yes 
Events Yes Yes 
i18n Yes Yes 
Dependency management Yes Yes 
Deteatciled comparison: http://vsch.a..rt.com/compare/a..n. gularjs/vs/symfony
SPA 
 Aka SPI (Single Page interface) 
 desktop apps UX 
 HTML / JS / CSS / etc in single page load 
 fast 
 AJAX and XHR
UI == APP
SPA Arhitecture 
Backend (rest api) with Symfony2 
Frontend with AngularJs 
Separation or combination?
SPA Arhitecture 
Backend (rest api) with Symfony2 
Frontend with AngularJs 
Separation or combination?
RESTful ws 
Simpler than SOAP & WSDL 
Resource-oriented (URI) 
Principles: 
HTTP methods (idempotent & not) 
stateless 
directory structure-like URIs 
XML or JSON (or XHTML) 
GET (vs HEAD), POST, PUT (vs PATCH), DELETE, OPTIONS
Building Rest API with SF2 
There is bundle for everything in Sf2. Right? 
So lets use some of them!
Building Rest API with SF2 
What we need? 
JMSSerializerBundle 
FOSRestBundle 
NelmioApiDocBundle
Building Rest API with SF2 
JMSSerializerBundle 
(de)serialization 
via annotations / YAML / XML / PHP 
integration with the Doctrine ORM 
handling of other complex cases (e.g. circular references)
Building Rest API with SF2 
LocasticBundleTodoBundleEntityTodo: 
# exclusion_policy: ALL 
exclusion_policy: NONE 
properties: 
# description: 
# expose: true 
createdAt: 
# expose: true 
exclude: true 
deadline: 
type: DateTime<'d.m.Y. H:i:s'> 
# expose: true 
done: 
# expose: true 
serialized_name: status
Building Rest API with SF2 
fos_rest: 
disable_csrf_role: ROLE_API 
param_fetcher_listener: true 
view: 
view_response_listener: 'force' 
formats: 
xml: true 
json: true 
templating_formats: 
html: true 
format_listener: 
rules: 
- { path: ^/, priorities: [ html, json, xml ], fallback_format: ~, prefer_extension: true } 
exception: 
codes: 
'SymfonyComponentRoutingExceptionResourceNotFoundException': 404 
'DoctrineORMOptimisticLockException': HTTP_CONFLICT 
messages: 
'SymfonyComponentRoutingExceptionResourceNotFoundException': true 
allowed_methods_listener: true 
access_denied_listener: 
json: true 
body_listener: true
Building Rest API with SF2 
/** 
* @ApiDoc( 
* resource = true, 
* description = "Get stories from users that you follow (newsfeed)", 
* section = "Feed", 
* output={ 
* "class" = "LocasticBundleFeedBundleEntityStory" 
* }, 
* statusCodes = { 
* 200 = "Returned when successful", 
* 400 = "Returned when bad parameters given" 
* } 
* ) 
* 
* @RestView( 
* serializerGroups = {"feed"} 
* ) 
*/ 
public function getFeedAction() 
{ 
$this->get('locastic_auth.auth.handler')->validateRequest($this->get('request')); 
return $this->getDoctrine()->getRepository('locastic.repository.story')->getStories($this- 
>get('request')->get('me')); 
}
Building Rest API with SF2
Templating 
TWIG <3
Templating 
<!DOCTYPE html> 
<html> 
<head> 
<meta charset="UTF-8" /> 
<title>{% block title %}Welcome!{% endblock %}</title> 
{% block stylesheets %} 
<!-- Place favicon.ico and apple-touch-icon.png in the root directory --> 
{#<link rel="stylesheet" href="{{ asset('css/normalize.css') }}">#} 
<link rel="stylesheet" href="{{ asset('css/main.css') }}"> 
<!-- load bootstrap and fontawesome via CDN --> 
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" /> 
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" /> 
<script src="{{ asset('js/vendor/modernizr-2.6.2.min.js') }}"></script> 
{% endblock %} 
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" /> 
</head> 
<body> 
{% block body %}{% endblock %} 
{% block javascripts %} 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script> 
<script src="https://code.angularjs.org/1.2.16/angular-route.min.js"></script> 
<script src="{{ asset('js/main.js') }}"></script> 
{% endblock %} 
</body> 
</html>
Templating 
Problem: 
{{ interpolation tags }} - used both by twig and AngularJS
Templating 
{% verbatim %} 
{{ message }} 
{% endverbatim %}
Templating 
var phpDayDemoApp = angular.module('phpDayDemoApp', [], 
function($interpolateProvider) { 
$interpolateProvider.startSymbol('[['); 
$interpolateProvider.endSymbol(']]'); 
}); 
Now we can use 
{% block content %} 
[[ message ]] {# rendered by AngularJS #} 
{% end block %} 
Tweak Twig lexer delimiters? Bad idea.
Templating 
Using assetic for minimize 
{% javascripts 
"js/angular-modules/mod1.js" 
"#s/angular-modules/mod2.js" 
"@AngBundle/Resources/public/js/controller/*.js" 
output="compiled/js/app.js" 
%} 
<script type="text/javascript" src="{{ asset_url }}"></script> 
{% endjavascripts %}
Templating 
Using assetic for minimize 
Since Angular infers the controller's dependencies from the names of 
arguments to the controller's constructor function, if you were to minify the 
JavaScript code for PhoneListCtrl controller, all of its function arguments 
would be minified as well, and the dependency injector would not be able 
to identify services correctly. 
Use an inline annotation where, instead of just providing the function, you 
provide an array. This array contains a list of the service names, followed by 
the function itself. 
function PhoneListCtrl($scope, $http) {...} 
phonecatApp.controller('phpDayCtrl', ['$scope', '$http', PhoneListCtrl]);
Templating 
Frontend developers still can use their tools like: 
Bower 
Grunt 
Etc.
Managing routes 
Client side: 
ngRoute 
independent since Angular 1.1.6 
hashbang #! & HTML5 mode 
<base href="/"> 
$locationProvider 
.html5Mode(true) 
.hashPrefix('!'); 
Also good for SEO!
Managing routes 
http://localhost/todos 
http://localhost/#todos 
Resolving conflicts 
Fallback, managing 404 
angular: 
path: '/{route}' 
defaults: { _controller: LocasticAngularBundle:Default:index} 
requirements: 
route: ".+"
Managing routes – client side 
// module configuration...$routeProvider.when('/todos/show/:id', { 
templateUrl : 'todo/show', 
controller : 'todoController' 
}) 
// receive paramssfugDemoApp.controller('todoController', function($scope, $http, $routeParams){ 
$scope.todo = {}; 
$http 
.get('/api/todo/show/' + $routeParams.id) 
.success(function(data){ 
$scope.todo = data['todo']; 
}); 
});
Managing routes 
Think of using FOSJsRoutingBundle for Frontend route 
managament 
<script 
src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script> 
<script src="{{ path('fos_js_routing_js', {"callback": 
"fos.Router.setData"}) }}"></script> 
my_route_to_expose_with_defaults: 
pattern: /blog/{page} 
defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 
}
Managing routes – server side 
locastic_rest_todo_getall: 
pattern: /api/get-all 
defaults: 
_controller: LocasticRestBundle:Todo:getAll 
locastic_rest_todo_create: 
pattern: /api/create 
defaults: 
_controller: LocasticRestBundle:Todo:create 
locastic_rest_todo_show: 
pattern: /api/show/{id} 
defaults: 
_controller: LocasticRestBundle:Todo:show
Translations 
AngularJS has its own translation system 
I18N/L10N . But it might be interesting to monitor 
and centralize translations from your backend 
Symfony. 
JMSTranslationBundle
Forms 
Symfony Forms <3 
We don't want to throw them away 
Build custom directive
Forms 
sfugDemoApp.directive('ngToDoForm', function() { 
return { 
restrict: 'E', 
template: '<div class="todoForm">Form will be!</div>' 
} 
}); 
'A' - <span ng-sparkline></span> 
'E' - <ng-sparkline></ng-sparkline> 
'C' - <span class="ng-sparkline"></span> 
'M' - <!-- directive: ng-sparkline → 
Usage of directive in HTML: 
<ng-to-do-form></ng-to-do-form>
Forms 
sfugDemoApp.directive('ngToDoForm', function() { 
return { 
restrict: 'E', 
templateUrl: '/api/form/show.html' 
} 
});
Forms 
sfugDemoApp.directive('ngToDoForm', function() { 
return { 
restrict: 'E', 
templateUrl: '/api/form/show.html' 
} 
}); 
locastic_show_form: 
pattern: /form/show.html 
defaults: 
_controller: LocasticWebBundle:Default:renderForm 
public function renderFormAction() 
{ 
$form = $this->createForm(new TodoType()); 
return $this->render('LocasticWebBundle::render_form.html.twig', array( 
'form' => $form->createView() 
)); 
}
Forms 
Suprise!!!
Forms 
Template behind directive 
<form class="form-inline" role="form" style="margin-bottom: 30px;"> 
Create new todo: 
<div class="form-group"> 
{{ form_label(form.description) }} 
{{ form_widget(form.description, {'attr': {'ng-model': 'newTodo.description', 'placeholder': 
'description', 'class': 'form-control'}}) }} 
</div> 
<div class="form-group"> 
<label class="sr-only" for="deadline">Deadline</label> 
<input type="text" class="form-control" id="deadline" placeholder="deadline (angular-ui)" ng-model=" 
newTodo.deadline"> 
</div> 
<input type="button" class="btn btn-default" ng-click="addNew()" value="add"/> 
</form>
Submitting forms? 
When the AngularJS $http service POSTs data the header application/x-www-form-urlencoded 
is never set (unlike jQuery’s $.ajax()). Also, the $http data is not serialized 
when sent. Both of these facts mean that the $_POST variable is never set properly by 
php. Without the $_POST variable Symfony’s built in form handling cannot be used. 
The fix is actually pretty simple: 
 angular needs to forced into setting a header 
 the data needs to be serialized 
 and the data needs to be normalized into a multidimensional array.
Submitting forms? 
var postData = { 
formtype_name: { 
id: some_id, 
name: some_name 
} 
}; 
$http({ 
method: "POST", 
url: url, 
headers: { 
'Content-Type': 'application/x-www-form-urlencoded' 
}, 
data: $.param(postData) 
});
Same-origin policy 
For security reasons, web browsers prevent JavaScript to Ajax requests (XMLHttpRequest) 
to other areas ( Same-origin policy ). 
An example of exception thrown by the browser: 
XMLHttpRequest cannot load http://api.mondomaine.com/v1/maressource.json. 
Invalid HTTP status code 405 
 Using JSOP (Json with Padding) – easy with FOSRestApi 
 Configure server (simple and stupid) 
<VirtualHost *:80> ServerName mon-appli-angular.com DocumentRoot 
/var/www/some-ng-app/ Alias /api /var/www/some-ng-app/ <Directory xxxx> 
</Directory> </VirtualHost> </VirtualHost> 
 Use Cors 
CORS (Cross-origin resource sharing) is an elegant and standardized response to allow 
Cross-domain requests. 
Be careful though, the CORS mechanism is not supported by all browsers (guess 
which ) …
Testing 
Symfony and AngularJS are designed to test. So write test 
Behat 
PHPUnit 
PHPSpec 
Jasmine 
… 
Or whatever you want just write tests
Summary 
The cleanest way is to separate backend and frontend. But there is some 
advantages to use both together. 
Twig + HTML works well. 
Assetic Bundle is very useful to minify bunches of Javascript files used by 
AngularJs 
Translation in the template. the data in the API payload does not need 
translation in most cases. Using Symfony I18N support for the template 
makes perfect sense. 
Loading of Option lists. Say you have a country list with 200+ options. You 
can build an API to populate a dynamic dropdown in angularjs, but as 
these options are static, you can simply build that list in twig. Forms in
And remember 
Keep controllers small and stupid, master Dependency 
injection, delegate to services and events.
Thank you!
QA 
Please rate my talk 
https://joind.in/12007 
follow me on twitter: @antonioperic

Contenu connexe

Tendances

REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101Samantha Geitz
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackIgnacio Martín
 
Bullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkBullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkVance Lucas
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswanivvaswani
 
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Jesus Manuel Olivas
 
RESTful API development in Laravel 4 - Christopher Pecoraro
RESTful API development in Laravel 4 - Christopher PecoraroRESTful API development in Laravel 4 - Christopher Pecoraro
RESTful API development in Laravel 4 - Christopher PecoraroChristopher Pecoraro
 
Hello World on Slim Framework 3.x
Hello World on Slim Framework 3.xHello World on Slim Framework 3.x
Hello World on Slim Framework 3.xRyan Szrama
 
How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0Takuya Tejima
 
OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010ikailan
 
Silex: From nothing to an API
Silex: From nothing to an APISilex: From nothing to an API
Silex: From nothing to an APIchrisdkemper
 
Ionic으로 모바일앱 만들기 #4
Ionic으로 모바일앱 만들기 #4Ionic으로 모바일앱 만들기 #4
Ionic으로 모바일앱 만들기 #4성일 한
 
RESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP FrameworkRESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP FrameworkBo-Yi Wu
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your AppLuca Mearelli
 
ACL in CodeIgniter
ACL in CodeIgniterACL in CodeIgniter
ACL in CodeIgnitermirahman
 
Silex, the microframework
Silex, the microframeworkSilex, the microframework
Silex, the microframeworkInviqa
 
AngularJS with Slim PHP Micro Framework
AngularJS with Slim PHP Micro FrameworkAngularJS with Slim PHP Micro Framework
AngularJS with Slim PHP Micro FrameworkBackand Cohen
 

Tendances (20)

REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
 
Bullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkBullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-Framework
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
 
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...
 
Javascript laravel's friend
Javascript laravel's friendJavascript laravel's friend
Javascript laravel's friend
 
WebGUI Developers Workshop
WebGUI Developers WorkshopWebGUI Developers Workshop
WebGUI Developers Workshop
 
Laravel 5
Laravel 5Laravel 5
Laravel 5
 
RESTful API development in Laravel 4 - Christopher Pecoraro
RESTful API development in Laravel 4 - Christopher PecoraroRESTful API development in Laravel 4 - Christopher Pecoraro
RESTful API development in Laravel 4 - Christopher Pecoraro
 
Hello World on Slim Framework 3.x
Hello World on Slim Framework 3.xHello World on Slim Framework 3.x
Hello World on Slim Framework 3.x
 
How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0
 
OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010
 
Silex: From nothing to an API
Silex: From nothing to an APISilex: From nothing to an API
Silex: From nothing to an API
 
Ionic으로 모바일앱 만들기 #4
Ionic으로 모바일앱 만들기 #4Ionic으로 모바일앱 만들기 #4
Ionic으로 모바일앱 만들기 #4
 
RESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP FrameworkRESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP Framework
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
 
ACL in CodeIgniter
ACL in CodeIgniterACL in CodeIgniter
ACL in CodeIgniter
 
Silex, the microframework
Silex, the microframeworkSilex, the microframework
Silex, the microframework
 
Kyiv.py #17 Flask talk
Kyiv.py #17 Flask talkKyiv.py #17 Flask talk
Kyiv.py #17 Flask talk
 
AngularJS with Slim PHP Micro Framework
AngularJS with Slim PHP Micro FrameworkAngularJS with Slim PHP Micro Framework
AngularJS with Slim PHP Micro Framework
 

En vedette

Symfony + AngularJS | Mladen Plavsic @DaFED26
Symfony + AngularJS | Mladen Plavsic @DaFED26Symfony + AngularJS | Mladen Plavsic @DaFED26
Symfony + AngularJS | Mladen Plavsic @DaFED26Mladen Plavšić
 
Symfony with angular.pptx
Symfony with angular.pptxSymfony with angular.pptx
Symfony with angular.pptxEsokia
 
Desarrollo Web Ágil con Symfony, Bootstrap y Angular
Desarrollo Web Ágil con Symfony, Bootstrap y AngularDesarrollo Web Ágil con Symfony, Bootstrap y Angular
Desarrollo Web Ágil con Symfony, Bootstrap y AngularFreelancer
 
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...
deSymfony 2013 -  Creando aplicaciones web desde otro ángulo con Symfony y A...deSymfony 2013 -  Creando aplicaciones web desde otro ángulo con Symfony y A...
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...Pablo Godel
 
Symfony 2 : chapitre 4 - Les services et les formulaires
Symfony 2 : chapitre 4 - Les services et les formulairesSymfony 2 : chapitre 4 - Les services et les formulaires
Symfony 2 : chapitre 4 - Les services et les formulairesAbdelkader Rhouati
 
Introduction au business modèle des applications mobile
Introduction au business modèle des applications mobileIntroduction au business modèle des applications mobile
Introduction au business modèle des applications mobileAbdelkader Rhouati
 
Building real time applications with Symfony2
Building real time applications with Symfony2Building real time applications with Symfony2
Building real time applications with Symfony2Antonio Peric-Mazar
 
برنامج جمعية بسمة أمل بوجدة لسنة 2013
برنامج جمعية بسمة أمل بوجدة لسنة 2013برنامج جمعية بسمة أمل بوجدة لسنة 2013
برنامج جمعية بسمة أمل بوجدة لسنة 2013Abdelkader Rhouati
 
Dependency Injection Smells
Dependency Injection SmellsDependency Injection Smells
Dependency Injection SmellsMatthias Noback
 
Symfony2 & l'architecture Rest
Symfony2 & l'architecture Rest Symfony2 & l'architecture Rest
Symfony2 & l'architecture Rest Ahmed Ghali
 
Créer une API GraphQL avec Symfony
Créer une API GraphQL avec SymfonyCréer une API GraphQL avec Symfony
Créer une API GraphQL avec SymfonySébastien Rosset
 
Applications secure by default
Applications secure by defaultApplications secure by default
Applications secure by defaultSecuRing
 
LVIV IT Arena - SmartHome using low cost components
LVIV IT Arena - SmartHome using low cost componentsLVIV IT Arena - SmartHome using low cost components
LVIV IT Arena - SmartHome using low cost componentsOriol Rius
 
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Innomatic Platform
 
SPI server centric SEO compatible stateless web sites... ALLELUIA!
SPI server centric SEO compatible stateless web sites... ALLELUIA!SPI server centric SEO compatible stateless web sites... ALLELUIA!
SPI server centric SEO compatible stateless web sites... ALLELUIA!Jose María Arranz
 
How to choose a web framework and be surprised
How to choose a web framework and be surprisedHow to choose a web framework and be surprised
How to choose a web framework and be surprisedJose María Arranz
 
Design patterns avec Symfony
Design patterns avec SymfonyDesign patterns avec Symfony
Design patterns avec SymfonyMohammed Rhamnia
 

En vedette (20)

Symfony and Angularjs
Symfony and AngularjsSymfony and Angularjs
Symfony and Angularjs
 
Symfony + AngularJS | Mladen Plavsic @DaFED26
Symfony + AngularJS | Mladen Plavsic @DaFED26Symfony + AngularJS | Mladen Plavsic @DaFED26
Symfony + AngularJS | Mladen Plavsic @DaFED26
 
Symfony with angular.pptx
Symfony with angular.pptxSymfony with angular.pptx
Symfony with angular.pptx
 
Desarrollo Web Ágil con Symfony, Bootstrap y Angular
Desarrollo Web Ágil con Symfony, Bootstrap y AngularDesarrollo Web Ágil con Symfony, Bootstrap y Angular
Desarrollo Web Ágil con Symfony, Bootstrap y Angular
 
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...
deSymfony 2013 -  Creando aplicaciones web desde otro ángulo con Symfony y A...deSymfony 2013 -  Creando aplicaciones web desde otro ángulo con Symfony y A...
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...
 
Symfony 2 : chapitre 4 - Les services et les formulaires
Symfony 2 : chapitre 4 - Les services et les formulairesSymfony 2 : chapitre 4 - Les services et les formulaires
Symfony 2 : chapitre 4 - Les services et les formulaires
 
Introduction au business modèle des applications mobile
Introduction au business modèle des applications mobileIntroduction au business modèle des applications mobile
Introduction au business modèle des applications mobile
 
Building real time applications with Symfony2
Building real time applications with Symfony2Building real time applications with Symfony2
Building real time applications with Symfony2
 
برنامج جمعية بسمة أمل بوجدة لسنة 2013
برنامج جمعية بسمة أمل بوجدة لسنة 2013برنامج جمعية بسمة أمل بوجدة لسنة 2013
برنامج جمعية بسمة أمل بوجدة لسنة 2013
 
Dependency Injection Smells
Dependency Injection SmellsDependency Injection Smells
Dependency Injection Smells
 
Symfony2 & l'architecture Rest
Symfony2 & l'architecture Rest Symfony2 & l'architecture Rest
Symfony2 & l'architecture Rest
 
Etude des Frameworks PHP
Etude des Frameworks PHPEtude des Frameworks PHP
Etude des Frameworks PHP
 
Créer une API GraphQL avec Symfony
Créer une API GraphQL avec SymfonyCréer une API GraphQL avec Symfony
Créer une API GraphQL avec Symfony
 
Drupal8 for Symfony Developers
Drupal8 for Symfony DevelopersDrupal8 for Symfony Developers
Drupal8 for Symfony Developers
 
Applications secure by default
Applications secure by defaultApplications secure by default
Applications secure by default
 
LVIV IT Arena - SmartHome using low cost components
LVIV IT Arena - SmartHome using low cost componentsLVIV IT Arena - SmartHome using low cost components
LVIV IT Arena - SmartHome using low cost components
 
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
 
SPI server centric SEO compatible stateless web sites... ALLELUIA!
SPI server centric SEO compatible stateless web sites... ALLELUIA!SPI server centric SEO compatible stateless web sites... ALLELUIA!
SPI server centric SEO compatible stateless web sites... ALLELUIA!
 
How to choose a web framework and be surprised
How to choose a web framework and be surprisedHow to choose a web framework and be surprised
How to choose a web framework and be surprised
 
Design patterns avec Symfony
Design patterns avec SymfonyDesign patterns avec Symfony
Design patterns avec Symfony
 

Similaire à Building Single Page Application (SPA) with Symfony2 and AngularJS

Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Eliran Eliassy
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
A gently introduction to AngularJS
A gently introduction to AngularJSA gently introduction to AngularJS
A gently introduction to AngularJSGregor Woiwode
 
Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsDylan Jay
 
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSAngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSmurtazahaveliwala
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)Igor Bronovskyy
 
Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's CodeWildan Maulana
 
Voorhoede - Front-end architecture
Voorhoede - Front-end architectureVoorhoede - Front-end architecture
Voorhoede - Front-end architectureJasper Moelker
 
Karlsruher Entwicklertag 2013 - Webanwendungen mit AngularJS
Karlsruher Entwicklertag 2013 - Webanwendungen mit AngularJSKarlsruher Entwicklertag 2013 - Webanwendungen mit AngularJS
Karlsruher Entwicklertag 2013 - Webanwendungen mit AngularJSPhilipp Burgmer
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Fwdays
 
Angular1x and Angular 2 for Beginners
Angular1x and Angular 2 for BeginnersAngular1x and Angular 2 for Beginners
Angular1x and Angular 2 for BeginnersOswald Campesato
 
Reactive application using meteor
Reactive application using meteorReactive application using meteor
Reactive application using meteorSapna Upreti
 
Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020Matt Raible
 
Building ColdFusion And AngularJS Applications
Building ColdFusion And AngularJS ApplicationsBuilding ColdFusion And AngularJS Applications
Building ColdFusion And AngularJS ApplicationsColdFusionConference
 

Similaire à Building Single Page Application (SPA) with Symfony2 and AngularJS (20)

Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
A gently introduction to AngularJS
A gently introduction to AngularJSA gently introduction to AngularJS
A gently introduction to AngularJS
 
Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web apps
 
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSAngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
 
Spring Surf 101
Spring Surf 101Spring Surf 101
Spring Surf 101
 
The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's Code
 
Voorhoede - Front-end architecture
Voorhoede - Front-end architectureVoorhoede - Front-end architecture
Voorhoede - Front-end architecture
 
Karlsruher Entwicklertag 2013 - Webanwendungen mit AngularJS
Karlsruher Entwicklertag 2013 - Webanwendungen mit AngularJSKarlsruher Entwicklertag 2013 - Webanwendungen mit AngularJS
Karlsruher Entwicklertag 2013 - Webanwendungen mit AngularJS
 
Intro to Laravel 4
Intro to Laravel 4Intro to Laravel 4
Intro to Laravel 4
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
 
ParisJS #10 : RequireJS
ParisJS #10 : RequireJSParisJS #10 : RequireJS
ParisJS #10 : RequireJS
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
 
Angular1x and Angular 2 for Beginners
Angular1x and Angular 2 for BeginnersAngular1x and Angular 2 for Beginners
Angular1x and Angular 2 for Beginners
 
Angular Js Basics
Angular Js BasicsAngular Js Basics
Angular Js Basics
 
Reactive application using meteor
Reactive application using meteorReactive application using meteor
Reactive application using meteor
 
Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020
 
Building ColdFusion And AngularJS Applications
Building ColdFusion And AngularJS ApplicationsBuilding ColdFusion And AngularJS Applications
Building ColdFusion And AngularJS Applications
 

Plus de Antonio Peric-Mazar

You call yourself a Senior Developer?
You call yourself a Senior Developer?You call yourself a Senior Developer?
You call yourself a Senior Developer?Antonio Peric-Mazar
 
Using API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonyconUsing API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonyconAntonio Peric-Mazar
 
Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...Antonio Peric-Mazar
 
Are you failing at being agile? #digitallabin
Are you failing at being agile? #digitallabinAre you failing at being agile? #digitallabin
Are you failing at being agile? #digitallabinAntonio Peric-Mazar
 
Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19Antonio Peric-Mazar
 
A year with progressive web apps! #webinale
A year with progressive web apps! #webinaleA year with progressive web apps! #webinale
A year with progressive web apps! #webinaleAntonio Peric-Mazar
 
The UI is the THE application #dpc19
The UI is the THE application #dpc19The UI is the THE application #dpc19
The UI is the THE application #dpc19Antonio Peric-Mazar
 
Symfony 4: A new way to develop applications #phpsrb
 Symfony 4: A new way to develop applications #phpsrb Symfony 4: A new way to develop applications #phpsrb
Symfony 4: A new way to develop applications #phpsrbAntonio Peric-Mazar
 
A year with progressive web apps! #DevConMU
A year with progressive web apps! #DevConMUA year with progressive web apps! #DevConMU
A year with progressive web apps! #DevConMUAntonio Peric-Mazar
 
Service workers are your best friends
Service workers are your best friendsService workers are your best friends
Service workers are your best friendsAntonio Peric-Mazar
 
Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformAntonio Peric-Mazar
 
Symfony4 - A new way of developing web applications
Symfony4 - A new way of developing web applicationsSymfony4 - A new way of developing web applications
Symfony4 - A new way of developing web applicationsAntonio Peric-Mazar
 
Build your business on top of Open Source
Build your business on top of Open SourceBuild your business on top of Open Source
Build your business on top of Open SourceAntonio Peric-Mazar
 
Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformAntonio Peric-Mazar
 
Lessons learned while developing with Sylius
Lessons learned while developing with SyliusLessons learned while developing with Sylius
Lessons learned while developing with SyliusAntonio Peric-Mazar
 
Drupal8 for Symfony developers - Dutch PHP
Drupal8 for Symfony developers - Dutch PHPDrupal8 for Symfony developers - Dutch PHP
Drupal8 for Symfony developers - Dutch PHPAntonio Peric-Mazar
 
Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 for Symfony Developers (PHP Day Verona 2017)Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 for Symfony Developers (PHP Day Verona 2017)Antonio Peric-Mazar
 
Maintainable + Extensible = Clean ... yes, Code!
Maintainable + Extensible = Clean ... yes, Code! Maintainable + Extensible = Clean ... yes, Code!
Maintainable + Extensible = Clean ... yes, Code! Antonio Peric-Mazar
 

Plus de Antonio Peric-Mazar (20)

You call yourself a Senior Developer?
You call yourself a Senior Developer?You call yourself a Senior Developer?
You call yourself a Senior Developer?
 
Using API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonyconUsing API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonycon
 
Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...
 
Are you failing at being agile? #digitallabin
Are you failing at being agile? #digitallabinAre you failing at being agile? #digitallabin
Are you failing at being agile? #digitallabin
 
Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19
 
A year with progressive web apps! #webinale
A year with progressive web apps! #webinaleA year with progressive web apps! #webinale
A year with progressive web apps! #webinale
 
The UI is the THE application #dpc19
The UI is the THE application #dpc19The UI is the THE application #dpc19
The UI is the THE application #dpc19
 
Symfony 4: A new way to develop applications #phpsrb
 Symfony 4: A new way to develop applications #phpsrb Symfony 4: A new way to develop applications #phpsrb
Symfony 4: A new way to develop applications #phpsrb
 
REST easy with API Platform
REST easy with API PlatformREST easy with API Platform
REST easy with API Platform
 
A year with progressive web apps! #DevConMU
A year with progressive web apps! #DevConMUA year with progressive web apps! #DevConMU
A year with progressive web apps! #DevConMU
 
Service workers are your best friends
Service workers are your best friendsService workers are your best friends
Service workers are your best friends
 
Progressive Web Apps are here!
Progressive Web Apps are here!Progressive Web Apps are here!
Progressive Web Apps are here!
 
Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API Platform
 
Symfony4 - A new way of developing web applications
Symfony4 - A new way of developing web applicationsSymfony4 - A new way of developing web applications
Symfony4 - A new way of developing web applications
 
Build your business on top of Open Source
Build your business on top of Open SourceBuild your business on top of Open Source
Build your business on top of Open Source
 
Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API Platform
 
Lessons learned while developing with Sylius
Lessons learned while developing with SyliusLessons learned while developing with Sylius
Lessons learned while developing with Sylius
 
Drupal8 for Symfony developers - Dutch PHP
Drupal8 for Symfony developers - Dutch PHPDrupal8 for Symfony developers - Dutch PHP
Drupal8 for Symfony developers - Dutch PHP
 
Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 for Symfony Developers (PHP Day Verona 2017)Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 for Symfony Developers (PHP Day Verona 2017)
 
Maintainable + Extensible = Clean ... yes, Code!
Maintainable + Extensible = Clean ... yes, Code! Maintainable + Extensible = Clean ... yes, Code!
Maintainable + Extensible = Clean ... yes, Code!
 

Dernier

SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Dernier (20)

SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

Building Single Page Application (SPA) with Symfony2 and AngularJS

  • 1. Building SPA with Symfony2 and AngularJS Antonio Perić-Mažar 02.10.2014, ZgPHP Conference 2014 https://joind.in/12007
  • 2. About me • Antonio Perić-Mažar, mag. ing. comp. • CEO @ locastic • Software developer, Symfony2 • Sylius Awesome Contributor :) • www.locastic.com • antonio@locastic.com • twitter: @antonioperic
  • 3. Who we are? • locastic (www.locastic.com) • Web and mobile development • UI/UX design • Located in Split, Croatia
  • 5.
  • 6. Symfony2 AngularJS Usage, language Backend, PHP Frontend, Javascript Dependency Injection Yes Yes Templating Twig HTML Form component Yes Yes Routing component Yes Yes MVC Yes Yes Testable Yes Yes Services Yes Yes Events Yes Yes i18n Yes Yes Dependency management Yes Yes Deteatciled comparison: http://vsch.a..rt.com/compare/a..n. gularjs/vs/symfony
  • 7. SPA  Aka SPI (Single Page interface)  desktop apps UX  HTML / JS / CSS / etc in single page load  fast  AJAX and XHR
  • 8.
  • 10. SPA Arhitecture Backend (rest api) with Symfony2 Frontend with AngularJs Separation or combination?
  • 11. SPA Arhitecture Backend (rest api) with Symfony2 Frontend with AngularJs Separation or combination?
  • 12. RESTful ws Simpler than SOAP & WSDL Resource-oriented (URI) Principles: HTTP methods (idempotent & not) stateless directory structure-like URIs XML or JSON (or XHTML) GET (vs HEAD), POST, PUT (vs PATCH), DELETE, OPTIONS
  • 13. Building Rest API with SF2 There is bundle for everything in Sf2. Right? So lets use some of them!
  • 14. Building Rest API with SF2 What we need? JMSSerializerBundle FOSRestBundle NelmioApiDocBundle
  • 15. Building Rest API with SF2 JMSSerializerBundle (de)serialization via annotations / YAML / XML / PHP integration with the Doctrine ORM handling of other complex cases (e.g. circular references)
  • 16. Building Rest API with SF2 LocasticBundleTodoBundleEntityTodo: # exclusion_policy: ALL exclusion_policy: NONE properties: # description: # expose: true createdAt: # expose: true exclude: true deadline: type: DateTime<'d.m.Y. H:i:s'> # expose: true done: # expose: true serialized_name: status
  • 17. Building Rest API with SF2 fos_rest: disable_csrf_role: ROLE_API param_fetcher_listener: true view: view_response_listener: 'force' formats: xml: true json: true templating_formats: html: true format_listener: rules: - { path: ^/, priorities: [ html, json, xml ], fallback_format: ~, prefer_extension: true } exception: codes: 'SymfonyComponentRoutingExceptionResourceNotFoundException': 404 'DoctrineORMOptimisticLockException': HTTP_CONFLICT messages: 'SymfonyComponentRoutingExceptionResourceNotFoundException': true allowed_methods_listener: true access_denied_listener: json: true body_listener: true
  • 18. Building Rest API with SF2 /** * @ApiDoc( * resource = true, * description = "Get stories from users that you follow (newsfeed)", * section = "Feed", * output={ * "class" = "LocasticBundleFeedBundleEntityStory" * }, * statusCodes = { * 200 = "Returned when successful", * 400 = "Returned when bad parameters given" * } * ) * * @RestView( * serializerGroups = {"feed"} * ) */ public function getFeedAction() { $this->get('locastic_auth.auth.handler')->validateRequest($this->get('request')); return $this->getDoctrine()->getRepository('locastic.repository.story')->getStories($this- >get('request')->get('me')); }
  • 19. Building Rest API with SF2
  • 21. Templating <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>{% block title %}Welcome!{% endblock %}</title> {% block stylesheets %} <!-- Place favicon.ico and apple-touch-icon.png in the root directory --> {#<link rel="stylesheet" href="{{ asset('css/normalize.css') }}">#} <link rel="stylesheet" href="{{ asset('css/main.css') }}"> <!-- load bootstrap and fontawesome via CDN --> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" /> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" /> <script src="{{ asset('js/vendor/modernizr-2.6.2.min.js') }}"></script> {% endblock %} <link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" /> </head> <body> {% block body %}{% endblock %} {% block javascripts %} <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script> <script src="https://code.angularjs.org/1.2.16/angular-route.min.js"></script> <script src="{{ asset('js/main.js') }}"></script> {% endblock %} </body> </html>
  • 22. Templating Problem: {{ interpolation tags }} - used both by twig and AngularJS
  • 23. Templating {% verbatim %} {{ message }} {% endverbatim %}
  • 24. Templating var phpDayDemoApp = angular.module('phpDayDemoApp', [], function($interpolateProvider) { $interpolateProvider.startSymbol('[['); $interpolateProvider.endSymbol(']]'); }); Now we can use {% block content %} [[ message ]] {# rendered by AngularJS #} {% end block %} Tweak Twig lexer delimiters? Bad idea.
  • 25. Templating Using assetic for minimize {% javascripts "js/angular-modules/mod1.js" "#s/angular-modules/mod2.js" "@AngBundle/Resources/public/js/controller/*.js" output="compiled/js/app.js" %} <script type="text/javascript" src="{{ asset_url }}"></script> {% endjavascripts %}
  • 26. Templating Using assetic for minimize Since Angular infers the controller's dependencies from the names of arguments to the controller's constructor function, if you were to minify the JavaScript code for PhoneListCtrl controller, all of its function arguments would be minified as well, and the dependency injector would not be able to identify services correctly. Use an inline annotation where, instead of just providing the function, you provide an array. This array contains a list of the service names, followed by the function itself. function PhoneListCtrl($scope, $http) {...} phonecatApp.controller('phpDayCtrl', ['$scope', '$http', PhoneListCtrl]);
  • 27. Templating Frontend developers still can use their tools like: Bower Grunt Etc.
  • 28. Managing routes Client side: ngRoute independent since Angular 1.1.6 hashbang #! & HTML5 mode <base href="/"> $locationProvider .html5Mode(true) .hashPrefix('!'); Also good for SEO!
  • 29. Managing routes http://localhost/todos http://localhost/#todos Resolving conflicts Fallback, managing 404 angular: path: '/{route}' defaults: { _controller: LocasticAngularBundle:Default:index} requirements: route: ".+"
  • 30. Managing routes – client side // module configuration...$routeProvider.when('/todos/show/:id', { templateUrl : 'todo/show', controller : 'todoController' }) // receive paramssfugDemoApp.controller('todoController', function($scope, $http, $routeParams){ $scope.todo = {}; $http .get('/api/todo/show/' + $routeParams.id) .success(function(data){ $scope.todo = data['todo']; }); });
  • 31. Managing routes Think of using FOSJsRoutingBundle for Frontend route managament <script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script> <script src="{{ path('fos_js_routing_js', {"callback": "fos.Router.setData"}) }}"></script> my_route_to_expose_with_defaults: pattern: /blog/{page} defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 }
  • 32. Managing routes – server side locastic_rest_todo_getall: pattern: /api/get-all defaults: _controller: LocasticRestBundle:Todo:getAll locastic_rest_todo_create: pattern: /api/create defaults: _controller: LocasticRestBundle:Todo:create locastic_rest_todo_show: pattern: /api/show/{id} defaults: _controller: LocasticRestBundle:Todo:show
  • 33. Translations AngularJS has its own translation system I18N/L10N . But it might be interesting to monitor and centralize translations from your backend Symfony. JMSTranslationBundle
  • 34. Forms Symfony Forms <3 We don't want to throw them away Build custom directive
  • 35. Forms sfugDemoApp.directive('ngToDoForm', function() { return { restrict: 'E', template: '<div class="todoForm">Form will be!</div>' } }); 'A' - <span ng-sparkline></span> 'E' - <ng-sparkline></ng-sparkline> 'C' - <span class="ng-sparkline"></span> 'M' - <!-- directive: ng-sparkline → Usage of directive in HTML: <ng-to-do-form></ng-to-do-form>
  • 36. Forms sfugDemoApp.directive('ngToDoForm', function() { return { restrict: 'E', templateUrl: '/api/form/show.html' } });
  • 37. Forms sfugDemoApp.directive('ngToDoForm', function() { return { restrict: 'E', templateUrl: '/api/form/show.html' } }); locastic_show_form: pattern: /form/show.html defaults: _controller: LocasticWebBundle:Default:renderForm public function renderFormAction() { $form = $this->createForm(new TodoType()); return $this->render('LocasticWebBundle::render_form.html.twig', array( 'form' => $form->createView() )); }
  • 39. Forms Template behind directive <form class="form-inline" role="form" style="margin-bottom: 30px;"> Create new todo: <div class="form-group"> {{ form_label(form.description) }} {{ form_widget(form.description, {'attr': {'ng-model': 'newTodo.description', 'placeholder': 'description', 'class': 'form-control'}}) }} </div> <div class="form-group"> <label class="sr-only" for="deadline">Deadline</label> <input type="text" class="form-control" id="deadline" placeholder="deadline (angular-ui)" ng-model=" newTodo.deadline"> </div> <input type="button" class="btn btn-default" ng-click="addNew()" value="add"/> </form>
  • 40. Submitting forms? When the AngularJS $http service POSTs data the header application/x-www-form-urlencoded is never set (unlike jQuery’s $.ajax()). Also, the $http data is not serialized when sent. Both of these facts mean that the $_POST variable is never set properly by php. Without the $_POST variable Symfony’s built in form handling cannot be used. The fix is actually pretty simple:  angular needs to forced into setting a header  the data needs to be serialized  and the data needs to be normalized into a multidimensional array.
  • 41. Submitting forms? var postData = { formtype_name: { id: some_id, name: some_name } }; $http({ method: "POST", url: url, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: $.param(postData) });
  • 42. Same-origin policy For security reasons, web browsers prevent JavaScript to Ajax requests (XMLHttpRequest) to other areas ( Same-origin policy ). An example of exception thrown by the browser: XMLHttpRequest cannot load http://api.mondomaine.com/v1/maressource.json. Invalid HTTP status code 405  Using JSOP (Json with Padding) – easy with FOSRestApi  Configure server (simple and stupid) <VirtualHost *:80> ServerName mon-appli-angular.com DocumentRoot /var/www/some-ng-app/ Alias /api /var/www/some-ng-app/ <Directory xxxx> </Directory> </VirtualHost> </VirtualHost>  Use Cors CORS (Cross-origin resource sharing) is an elegant and standardized response to allow Cross-domain requests. Be careful though, the CORS mechanism is not supported by all browsers (guess which ) …
  • 43. Testing Symfony and AngularJS are designed to test. So write test Behat PHPUnit PHPSpec Jasmine … Or whatever you want just write tests
  • 44. Summary The cleanest way is to separate backend and frontend. But there is some advantages to use both together. Twig + HTML works well. Assetic Bundle is very useful to minify bunches of Javascript files used by AngularJs Translation in the template. the data in the API payload does not need translation in most cases. Using Symfony I18N support for the template makes perfect sense. Loading of Option lists. Say you have a country list with 200+ options. You can build an API to populate a dynamic dropdown in angularjs, but as these options are static, you can simply build that list in twig. Forms in
  • 45. And remember Keep controllers small and stupid, master Dependency injection, delegate to services and events.
  • 47. QA Please rate my talk https://joind.in/12007 follow me on twitter: @antonioperic