SlideShare a Scribd company logo
1 of 88
Download to read offline
Max Voloshin
● Location: Dnipro, Ukraine
● Position: Team Lead, OWOX
● In professional software development since 2010
● Fan of microservices and continuous deployment
Photographer: Avilov Alexandr
OWOX Business Intelligence
As business:
● More than 1 million transactions per week in our clients' projects
● 1 000+ projects in 50 countries rely on our solutions
● $ 200 000+ daily handled our clients' costs on advertising
As software:
● 10+ microservices in PHP/Java
● Web Components (Polymer 1.8)
● Several releases every day
Why am I here?
I want to share 9 improvements
for making frontend development easier
Who cares?
Frontend development
may be a constraint for your product
Let’s improve!
#1
Let frontend developer
don't deal with content management
#1
<div class="e-wrap">
<div class="e-grid-col1 e-grid-col-empty"></div>
<div class="e-grid-col8" role="main">
<h2 class="e-page-title">
Page not found
</h2>
<p class="error-message">
Incorrectly typed address or a page on the website no longer exists
</p>
<p class="error-link-wrap"><a href="/" class="error-link">
Home
</a></p>
</div>
<div class="clear"></div>
</div>
Do you really want
to change one selling text to another?..
#1
Use mnemonic names of texts
instead of hard-coded content
#1
Admin panel
for content
Write contentContent
manager
Frontend
developer Frontend
Write code
Matched by mnemonic name
#1
Polymer
<div class="e-wrap">
<div class="e-grid-col1 e-grid-col-empty"></div>
<div class="e-grid-col8" role="main">
<h2 class="e-page-title">
<html-text name="NotFoundPage.Title"></html-text>
</h2>
<p class="error-message">
<html-text name="NotFoundPage.Message"></html-text>
</p>
<p class="error-link-wrap"><a href="/" class="error-link">
<html-text name="HomePage.Title"></html-text>
</a></p>
</div>
</div>
Bonus: easy internalization
#1
#2
Let frontend developer
use HTML/JS templating
#2
.answers-i-link:before { CSS as Smarty (PHP) template
content: "";
position: absolute;
left: -30px;
width: 25px;
height: 25px;
background: url('/*{$settings.path}*//icons.png') 0 -414px no-repeat;
}
.answers-i-link:hover:before {
background: url('/*{$settings.path}*//icons.png') 0 -373px no-repeat;
}
.answers-i-link.active:before {
background: url('/*{$settings.path}*//icons.png') 0 -700px no-repeat;
}
.answers-i-link.active:hover:before {
background: url('/*{$settings.path}*//icons.png') 0 -659px no-repeat;
}
{foreach $tree as $section} HTML as Smarty (PHP) template
<h3 class="level-{$level}">{$section['title']}</h3>
{if $section['children']}
{include file='faq/subjects.tpl' tree=$section['children'] level=$level+1}
{/if}
{if isset($section['records'])}
{foreach $section['records'] as $record}
{if $is_contents}
<a href="#record-{$record.id}"
class="level-{$level}">{$record.title}</a><br />
{else}
<a name="record-{$record.id}"
class="level-{$level}">{$record.title}</a><br />
{$record['answer'] nofilter}
{/if}
{/foreach}
{/if}
{/foreach}
HTML as Smarty (PHP) template
<div class="b-expenses-head">
{foreach from=$manual_costs item="month" name="tabs"}
<div id="manual-costs-tab-{$smarty.foreach.tabs.index}" class="inline
b-expenses-head-month {if $month['is_active']}active{/if}">
<span class="b-expenses-month-title">{$month['month_title']}</span>
</div>
<script type="text/javascript">
ManualCosts.addGroup(new
ManualCostsTab_class({$smarty.foreach.tabs.index}, '{$month['hash']}'));
</script>
{/foreach}
</div>
JS as Smarty (PHP) template
initialize: function(data, connect_service_access) {
this.parent(data, connect_service_access);
Object.append(
this._templates,
{access_create: '/*{template_script_fetch file="access_create.jst" }*/'}
);
this._popup.addEvent('createAccess', this.onCreateAccess.bind(this));
},
onCreateAccess: function() {
this.send(
'/*{$menu.my.href}*/users/access/simple_services#createAccess',
{
service_name: this._data['service_name'],
token: token,
service_account: service_account
}
);
}
Do you really want to learn and debug
non JS/HTML templating?..
#2
Use HTML/JS templating,
use data as JSON
#2
Polymer
<template is="dom-if" if="[[!isEmpty(url)]]">
<page-item item-action>
<a is="pushstate-anchor" href="[[url]]" class="item-action">
<text-html name="Page.Item.Actions.Edit"></text-html>
</a>
</page-item>
</template>
Polymer
<dom-module id="page-external-link-styles">
<template>
<style include="shared-styles">
:host {
display: inline;
white-space: nowrap;
}
:host(:not(.no-link-style)) a {
color: var(--blue-color-main);
text-decoration: none;
}
</style>
</template>
</dom-module>
Bonus: static code analysis & tests
#2
#3
Let frontend developer
don't deal with backend routing
#3
Symfony (PHP) routing
# app/config/routing.yml
blog_list:
path: /blog/{page}
defaults: { _controller: AppBundle:Blog:list, page: 1 }
requirements:
page: 'd+'
blog_show:
# ...
Do you really want to learn and debug
backend routing?..
#3
Use frontend routing
via Single Page Application
#3
Polymer
<app-router id="appRouter" mode="pushstate" init="manual">
<app-route
id="dataPipeline"
path$="[[globals.pathPrefix]]/:context/pipeline/"
element="pipeline-page"
import="/components/pages/pipeline/pipeline-page.html"
></app-route>
<app-route
id="costDataPage"
path$="[[globals.pathPrefix]]/:context/pipeline/:property/:id/"
redirect="history/"
></app-route>
<app-route
id="costDataHistoryPage"
path$="[[globals.pathPrefix]]/:context/pipeline/:property/:id/history/"
element="cost-data-page"
import="/components/pages/cost-data/cost-data-page.html"
></app-route>
</app-router>
#4
Let frontend developer
don't deal with stagnated framework
#4
Switching framework is hard
● You can’t pause product development
● You can't release all changes at one time
#4
Two approaches
for framework switching
#4
1. Continuous deploy
then single release
#4
UI v1 (MooTools) → UI v2 (Polymer 0.5)
t
Release v1
Deploy v2
(part #1)
Change v1
prod
Deploy v2
(part #2)
Release v2
Deploy v2
(part #N)
...
Deploy != Release
#4
UI v1: https://domain.com/
UI v2: https://domain.com/v2/ ← SPA root
Continuous deploy then single release
+ Compatible with design switching
- Suitable only for small applications because of effort
duplication
#4
Off topic: why Polymer?
● Material Design out of the box
● Possibilities to UI reuse (not only JS)
● Google promotion of Web Components
● #UseThePlatform
#4
2. Page-by-page release
#4
The first law of holes
#4
Limitations:
1. Only one version of Polymer can be on page
2. We have Single Page Application
Solution: “break points” in Single Page Application
UI v2 — domain.com/v2/ UI v3 — domain.com/v3/
/foo/
/bar/
/baz/
/qux/
/foo/
/bar/
/baz/
/qux/
UI v2 (Polymer 0.5) → UI v3 (Polymer 1.8)
#4
UI v2
<app-router id="router" mode="pushstate" init="manual"
<app-route
id="pipeline"
path="/ui/:context/pipeline/"
import="{{$.globals.values.base_url}}pipeline-page/pipeline-page.html"
></app-route>
<app-route
id="cost_details"
path="/ui/:context/pipeline/:property/:id/"
redirect="history/"
></app-route>
<app-route
path="/ui/:context/pipeline/:property/:id/history/"
import="{{$.globals.values.base_url}}cost-page/cost-page.html"
new-page
></app-route>
</app-router>
<app-router id="appRouter" mode="pushstate" init="manual"> UI v3
<app-route
id="pipeline"
path$="[[globals.pathPrefix]]/:context/pipeline/"
element="pipeline-page"
import="/components/pages/pipeline/pipeline-page.html"
></app-route>
<app-route
id="costPage"
path$="[[globals.pathPrefix]]/:context/pipeline/:property/:id/"
redirect="history/"
></app-route>
<app-route
id="costHistoryPage"
path$="[[globals.pathPrefix]]/:context/pipeline/:property/:id/history/"
element="cost-data-page"
import="/components/pages/cost-data/cost-data-page.html"
old-page
></app-route>
</app-router>
+ Suitable for any size applications
- Only same design
- Time delays between UI transitions
Page-by-page release
#4
#5
Let frontend developer
deliver UI independently
#5
Delivery of UI with “monorepo” approach
1. Make changes
2. Wait till the whole monorepo can be deployed
3. Deploy
#5
Use standalone repository
and continuous delivery pipeline
#5
Delivery of UI with “standalone repo” approach
1. Make changes
2. Wait till the whole monorepo can be deployed
3. Deploy
#5
#6
Let frontend developer
use remote backend
#6
UI changes with “local backend” approach
1. Update backend source with dependencies
2. Update storage data
3. Update environment
4. Try to figure out via guide/FAQ why backend is not working
5. Call backend developer who knows how to update this
6. Spend half hour together to find stupid environment problem
7. Repeat 1-6 for each microservice
8. Make changes to frontend
#6
UI changes with “remote backend” approach
1. Update backend source with dependencies
2. Update storage data
3. Update environment
4. Try to figure out via guide/FAQ why backend is not working
5. Call backend developer who knows how to update this
6. Spend half hour together to find stupid environment problem
7. Repeat 1-6 for each microservice
8. Make changes to frontend
#6
request identity token
How to handle authorization?
identity token (JSON Web Token)
Backend
Attach header to each further request
Authorization: Bearer {identity token}
Frontend
#6
#6
#6
#6
#6
#6
#6
jwt.io
JSON Web Tokens libraries and debugger
#6
#7
Let frontend developer
don't deal with CORS
#7
#7
UI – https://domain.com/
https://foo.appspot.com/ https://bar.heroku.com/
Cross-origin resource sharing ?
#7
CORS (Cross-origin resource sharing)
● Request headers
○ Origin
○ Access-Control-Request-Method
○ Access-Control-Request-Headers
● Response headers
○ Access-Control-Allow-Origin
○ Access-Control-Allow-Credentials
○ Access-Control-Expose-Headers
○ Access-Control-Max-Age
○ Access-Control-Allow-Methods
○ Access-Control-Allow-Headers
#7
Use your web server’s ability
to serve UI and microservices
from single domain
#7
server {
server_name domain.com;
location /api/foo/ {
proxy_pass https://foo.appspot.com/;
}
location /api/bar/ {
proxy_pass https://bar.heroku.com/;
}
}
Nginx example
#7
#8
Let frontend developer
use production web server
without digging into its configuration
#8
Nginx
location /download/ {
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
#rewrite ^/ http://www.example.com/
return 403;
}
# rewrite_log on;
# rewrite /download/*/mp3/*.any_ext to /download/*/mp3/*.mp3
rewrite ^/(download/.*)/mp3/(.*)..*$ /$1/mp3/$2.mp3 break;
root /spool/www;
#autoindex on;
access_log /var/log/nginx-download.access_log download;
}
Do you really want to learn and debug
production web server configuration?..
#8
Why “dev web server” approach may fail?
1. HTTP caching issues
2. Security issues
3. Missing redirects
#8
Use production-like Docker containers
with your local configuration
#8
.env
#8
DOMAIN=domain.com
FOO_ENDPOINT_URL=/api/foo
FOO_REAL_ENDPOINT_URL=https://foo.appspot.com/
BAR_ENDPOINT_URL=/api/bar
BAR_REAL_ENDPOINT_URL=https://bar.heroku.com/
...
.env
#8
.env
docker-compose
.override.yml
#8
version: '2'
services:
init:
environment:
FOO_REAL_ENDPOINT_URL: http://foo.custom
serve:
extra_hosts:
- "foo.custom:172.16.0.95"
docker-compose.override.yml
#8
.env
docker-compose
.override.yml
Configuration
$ docker-compose up init
Configured web server
$ docker-compose up -d serve
#8
#9
Let frontend developer
use production state
of concrete user
#9
How to fix a bug?
1. Prepare state
2. Reproduce
3. Fix
#9
● manual actions
● accesses to services
● historical entities
● data uniqueness
Let frontend developer
receive identity token of concrete user
but with read-only(!) permissions
#9
request identity token
“Looks like” feature
identity token of another user (read-only)
Backend
Attach header to each further request
Authorization: Bearer {identity token}
Frontend
#9
Frontend
developer
configure
#9
Recap
Let frontend developer:
1. don't deal with content management
2. use HTML/JS templating
3. don't deal with backend routing
4. don't deal with stagnated framework
5. deliver UI independently
6. use remote backend
7. don't deal with CORS
8. use production web server without digging into its configuration
9. use production state of concrete user
Questions?

More Related Content

What's hot

Rock-solid Magento Deployments (and Development)
Rock-solid Magento Deployments (and Development)Rock-solid Magento Deployments (and Development)
Rock-solid Magento Deployments (and Development)AOE
 
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Optimising Your Front End Workflow With Symfony, Twig, Bower and GulpOptimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Optimising Your Front End Workflow With Symfony, Twig, Bower and GulpMatthew Davis
 
Magento with Composer
Magento with ComposerMagento with Composer
Magento with ComposerAOE
 
High Performance Snippets
High Performance SnippetsHigh Performance Snippets
High Performance SnippetsSteve Souders
 
Advanced front-end automation with npm scripts
Advanced front-end automation with npm scriptsAdvanced front-end automation with npm scripts
Advanced front-end automation with npm scriptsk88hudson
 
Hitchhiker's guide to the front end development
Hitchhiker's guide to the front end developmentHitchhiker's guide to the front end development
Hitchhiker's guide to the front end development정윤 김
 
webpack 101 slides
webpack 101 slideswebpack 101 slides
webpack 101 slidesmattysmith
 
When Web meet Native App
When Web meet Native AppWhen Web meet Native App
When Web meet Native AppYu-Wei Chuang
 
Puppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing ToolPuppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing ToolMiki Lombardi
 
Modern Web Application Development Workflow - EclipseCon France 2014
Modern Web Application Development Workflow - EclipseCon France 2014Modern Web Application Development Workflow - EclipseCon France 2014
Modern Web Application Development Workflow - EclipseCon France 2014Stéphane Bégaudeau
 
High Performance JavaScript - jQuery Conference SF Bay Area 2010
High Performance JavaScript - jQuery Conference SF Bay Area 2010High Performance JavaScript - jQuery Conference SF Bay Area 2010
High Performance JavaScript - jQuery Conference SF Bay Area 2010Nicholas Zakas
 
Your Script Just Killed My Site
Your Script Just Killed My SiteYour Script Just Killed My Site
Your Script Just Killed My SiteSteve Souders
 
Clojure Web Development
Clojure Web DevelopmentClojure Web Development
Clojure Web DevelopmentHong Jiang
 
WPE WebKit for Android
WPE WebKit for AndroidWPE WebKit for Android
WPE WebKit for AndroidIgalia
 

What's hot (20)

Rock-solid Magento Deployments (and Development)
Rock-solid Magento Deployments (and Development)Rock-solid Magento Deployments (and Development)
Rock-solid Magento Deployments (and Development)
 
An Intro into webpack
An Intro into webpackAn Intro into webpack
An Intro into webpack
 
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Optimising Your Front End Workflow With Symfony, Twig, Bower and GulpOptimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
 
Magento with Composer
Magento with ComposerMagento with Composer
Magento with Composer
 
High Performance Snippets
High Performance SnippetsHigh Performance Snippets
High Performance Snippets
 
What is HTML 5?
What is HTML 5?What is HTML 5?
What is HTML 5?
 
Advanced front-end automation with npm scripts
Advanced front-end automation with npm scriptsAdvanced front-end automation with npm scripts
Advanced front-end automation with npm scripts
 
Webpack DevTalk
Webpack DevTalkWebpack DevTalk
Webpack DevTalk
 
Hitchhiker's guide to the front end development
Hitchhiker's guide to the front end developmentHitchhiker's guide to the front end development
Hitchhiker's guide to the front end development
 
webpack 101 slides
webpack 101 slideswebpack 101 slides
webpack 101 slides
 
Webpack: from 0 to 2
Webpack: from 0 to 2Webpack: from 0 to 2
Webpack: from 0 to 2
 
When Web meet Native App
When Web meet Native AppWhen Web meet Native App
When Web meet Native App
 
Puppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing ToolPuppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing Tool
 
Modern Web Application Development Workflow - EclipseCon France 2014
Modern Web Application Development Workflow - EclipseCon France 2014Modern Web Application Development Workflow - EclipseCon France 2014
Modern Web Application Development Workflow - EclipseCon France 2014
 
Npm scripts
Npm scriptsNpm scripts
Npm scripts
 
High Performance JavaScript - jQuery Conference SF Bay Area 2010
High Performance JavaScript - jQuery Conference SF Bay Area 2010High Performance JavaScript - jQuery Conference SF Bay Area 2010
High Performance JavaScript - jQuery Conference SF Bay Area 2010
 
Js unit testing
Js unit testingJs unit testing
Js unit testing
 
Your Script Just Killed My Site
Your Script Just Killed My SiteYour Script Just Killed My Site
Your Script Just Killed My Site
 
Clojure Web Development
Clojure Web DevelopmentClojure Web Development
Clojure Web Development
 
WPE WebKit for Android
WPE WebKit for AndroidWPE WebKit for Android
WPE WebKit for Android
 

Similar to Max Voloshin - "Organization of frontend development for products with microservices"

Enterprise PHP (PHP London Conference 2008)
Enterprise PHP (PHP London Conference 2008)Enterprise PHP (PHP London Conference 2008)
Enterprise PHP (PHP London Conference 2008)Ivo Jansch
 
AD113 Speed Up Your Applications w/ Nginx and PageSpeed
AD113  Speed Up Your Applications w/ Nginx and PageSpeedAD113  Speed Up Your Applications w/ Nginx and PageSpeed
AD113 Speed Up Your Applications w/ Nginx and PageSpeededm00se
 
An Introduction to Web Components
An Introduction to Web ComponentsAn Introduction to Web Components
An Introduction to Web ComponentsRed Pill Now
 
Tran Minh Duc - Certified Hybris Dev
Tran Minh Duc - Certified Hybris DevTran Minh Duc - Certified Hybris Dev
Tran Minh Duc - Certified Hybris DevĐức Hítle
 
Software developer having 4.5 years of work experience in Ecommerce & E-Gover...
Software developer having 4.5 years of work experience in Ecommerce & E-Gover...Software developer having 4.5 years of work experience in Ecommerce & E-Gover...
Software developer having 4.5 years of work experience in Ecommerce & E-Gover...Prasanta Sahoo
 
Asp .Net Website on E Learning
Asp .Net Website on E LearningAsp .Net Website on E Learning
Asp .Net Website on E LearningMujeeb Rehman
 
Purnendu_MSc_Exp12Yrs_PHPMYSQL
Purnendu_MSc_Exp12Yrs_PHPMYSQLPurnendu_MSc_Exp12Yrs_PHPMYSQL
Purnendu_MSc_Exp12Yrs_PHPMYSQLphp2ranjan
 
Tanvi resume php
Tanvi resume phpTanvi resume php
Tanvi resume phptanvi patel
 
Web Application Introduction
Web Application  IntroductionWeb Application  Introduction
Web Application Introductionshaojung
 
Web Application Introduction
Web Application  IntroductionWeb Application  Introduction
Web Application Introductionshaojung
 
Web Application Introduction
Web Application  IntroductionWeb Application  Introduction
Web Application Introductionshaojung
 
Tek 2013 - Building Web Apps from a New Angle with AngularJS
Tek 2013 - Building Web Apps from a New Angle with AngularJSTek 2013 - Building Web Apps from a New Angle with AngularJS
Tek 2013 - Building Web Apps from a New Angle with AngularJSPablo Godel
 
The future of web development write once, run everywhere with angular js an...
The future of web development   write once, run everywhere with angular js an...The future of web development   write once, run everywhere with angular js an...
The future of web development write once, run everywhere with angular js an...Mark Leusink
 
The future of web development write once, run everywhere with angular.js and ...
The future of web development write once, run everywhere with angular.js and ...The future of web development write once, run everywhere with angular.js and ...
The future of web development write once, run everywhere with angular.js and ...Mark Roden
 
Building WebApp with HTML5
Building WebApp with HTML5Building WebApp with HTML5
Building WebApp with HTML5Tien Tran Le Duy
 
Building Creative Product Extensions with Experience Manager
Building Creative Product Extensions with Experience ManagerBuilding Creative Product Extensions with Experience Manager
Building Creative Product Extensions with Experience Managerconnectwebex
 

Similar to Max Voloshin - "Organization of frontend development for products with microservices" (20)

Enterprise PHP (PHP London Conference 2008)
Enterprise PHP (PHP London Conference 2008)Enterprise PHP (PHP London Conference 2008)
Enterprise PHP (PHP London Conference 2008)
 
AD113 Speed Up Your Applications w/ Nginx and PageSpeed
AD113  Speed Up Your Applications w/ Nginx and PageSpeedAD113  Speed Up Your Applications w/ Nginx and PageSpeed
AD113 Speed Up Your Applications w/ Nginx and PageSpeed
 
An Introduction to Web Components
An Introduction to Web ComponentsAn Introduction to Web Components
An Introduction to Web Components
 
Tran Minh Duc - Certified Hybris Dev
Tran Minh Duc - Certified Hybris DevTran Minh Duc - Certified Hybris Dev
Tran Minh Duc - Certified Hybris Dev
 
GDG Ibadan #pwa
GDG Ibadan #pwaGDG Ibadan #pwa
GDG Ibadan #pwa
 
Software developer having 4.5 years of work experience in Ecommerce & E-Gover...
Software developer having 4.5 years of work experience in Ecommerce & E-Gover...Software developer having 4.5 years of work experience in Ecommerce & E-Gover...
Software developer having 4.5 years of work experience in Ecommerce & E-Gover...
 
Asp .Net Website on E Learning
Asp .Net Website on E LearningAsp .Net Website on E Learning
Asp .Net Website on E Learning
 
Purnendu_MSc_Exp12Yrs_PHPMYSQL
Purnendu_MSc_Exp12Yrs_PHPMYSQLPurnendu_MSc_Exp12Yrs_PHPMYSQL
Purnendu_MSc_Exp12Yrs_PHPMYSQL
 
Tanvi resume php
Tanvi resume phpTanvi resume php
Tanvi resume php
 
Progressive Web Apps
Progressive Web AppsProgressive Web Apps
Progressive Web Apps
 
Web Application Introduction
Web Application  IntroductionWeb Application  Introduction
Web Application Introduction
 
Web Application Introduction
Web Application  IntroductionWeb Application  Introduction
Web Application Introduction
 
Web Application Introduction
Web Application  IntroductionWeb Application  Introduction
Web Application Introduction
 
Adobe & HTML5
Adobe & HTML5Adobe & HTML5
Adobe & HTML5
 
Tek 2013 - Building Web Apps from a New Angle with AngularJS
Tek 2013 - Building Web Apps from a New Angle with AngularJSTek 2013 - Building Web Apps from a New Angle with AngularJS
Tek 2013 - Building Web Apps from a New Angle with AngularJS
 
The future of web development write once, run everywhere with angular js an...
The future of web development   write once, run everywhere with angular js an...The future of web development   write once, run everywhere with angular js an...
The future of web development write once, run everywhere with angular js an...
 
The future of web development write once, run everywhere with angular.js and ...
The future of web development write once, run everywhere with angular.js and ...The future of web development write once, run everywhere with angular.js and ...
The future of web development write once, run everywhere with angular.js and ...
 
Ajaykumar_last
Ajaykumar_lastAjaykumar_last
Ajaykumar_last
 
Building WebApp with HTML5
Building WebApp with HTML5Building WebApp with HTML5
Building WebApp with HTML5
 
Building Creative Product Extensions with Experience Manager
Building Creative Product Extensions with Experience ManagerBuilding Creative Product Extensions with Experience Manager
Building Creative Product Extensions with Experience Manager
 

More from IT Event

Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...
Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...
Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...IT Event
 
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"IT Event
 
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "IT Event
 
Konstantin Krivlenia - "Continuous integration for frontend"
Konstantin Krivlenia - "Continuous integration for frontend"Konstantin Krivlenia - "Continuous integration for frontend"
Konstantin Krivlenia - "Continuous integration for frontend"IT Event
 
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"IT Event
 
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"IT Event
 
Vladimir Grinenko - "Dependencies in component web done right"
Vladimir Grinenko - "Dependencies in component web done right"Vladimir Grinenko - "Dependencies in component web done right"
Vladimir Grinenko - "Dependencies in component web done right"IT Event
 
Dmitry Bartalevich - "How to train your WebVR"
Dmitry Bartalevich - "How to train your WebVR"Dmitry Bartalevich - "How to train your WebVR"
Dmitry Bartalevich - "How to train your WebVR"IT Event
 
Aleksey Bogachuk - "Offline Second"
Aleksey Bogachuk - "Offline Second"Aleksey Bogachuk - "Offline Second"
Aleksey Bogachuk - "Offline Second"IT Event
 
James Allardice - "Building a better login with the credential management API"
James Allardice - "Building a better login with the credential management API"James Allardice - "Building a better login with the credential management API"
James Allardice - "Building a better login with the credential management API"IT Event
 
Fedor Skuratov "Dark Social: as messengers change the market of social media ...
Fedor Skuratov "Dark Social: as messengers change the market of social media ...Fedor Skuratov "Dark Social: as messengers change the market of social media ...
Fedor Skuratov "Dark Social: as messengers change the market of social media ...IT Event
 
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"IT Event
 
Алексей Рагозин "Java и linux борьба за микросекунды"
Алексей Рагозин "Java и linux борьба за микросекунды"Алексей Рагозин "Java и linux борьба за микросекунды"
Алексей Рагозин "Java и linux борьба за микросекунды"IT Event
 
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"IT Event
 
Наш ответ Uber’у
Наш ответ Uber’уНаш ответ Uber’у
Наш ответ Uber’уIT Event
 
Александр Крашенинников "Hadoop High Availability: опыт Badoo"
Александр Крашенинников "Hadoop High Availability: опыт Badoo"Александр Крашенинников "Hadoop High Availability: опыт Badoo"
Александр Крашенинников "Hadoop High Availability: опыт Badoo"IT Event
 
Leonid Vasilyev "Building, deploying and running production code at Dropbox"
Leonid Vasilyev  "Building, deploying and running production code at Dropbox"Leonid Vasilyev  "Building, deploying and running production code at Dropbox"
Leonid Vasilyev "Building, deploying and running production code at Dropbox"IT Event
 
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...IT Event
 
Mete Atamel "Resilient microservices with kubernetes"
Mete Atamel "Resilient microservices with kubernetes"Mete Atamel "Resilient microservices with kubernetes"
Mete Atamel "Resilient microservices with kubernetes"IT Event
 
Andrew Stain "User acquisition"
Andrew Stain "User acquisition"Andrew Stain "User acquisition"
Andrew Stain "User acquisition"IT Event
 

More from IT Event (20)

Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...
Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...
Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...
 
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"
 
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
 
Konstantin Krivlenia - "Continuous integration for frontend"
Konstantin Krivlenia - "Continuous integration for frontend"Konstantin Krivlenia - "Continuous integration for frontend"
Konstantin Krivlenia - "Continuous integration for frontend"
 
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"
 
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"
 
Vladimir Grinenko - "Dependencies in component web done right"
Vladimir Grinenko - "Dependencies in component web done right"Vladimir Grinenko - "Dependencies in component web done right"
Vladimir Grinenko - "Dependencies in component web done right"
 
Dmitry Bartalevich - "How to train your WebVR"
Dmitry Bartalevich - "How to train your WebVR"Dmitry Bartalevich - "How to train your WebVR"
Dmitry Bartalevich - "How to train your WebVR"
 
Aleksey Bogachuk - "Offline Second"
Aleksey Bogachuk - "Offline Second"Aleksey Bogachuk - "Offline Second"
Aleksey Bogachuk - "Offline Second"
 
James Allardice - "Building a better login with the credential management API"
James Allardice - "Building a better login with the credential management API"James Allardice - "Building a better login with the credential management API"
James Allardice - "Building a better login with the credential management API"
 
Fedor Skuratov "Dark Social: as messengers change the market of social media ...
Fedor Skuratov "Dark Social: as messengers change the market of social media ...Fedor Skuratov "Dark Social: as messengers change the market of social media ...
Fedor Skuratov "Dark Social: as messengers change the market of social media ...
 
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"
 
Алексей Рагозин "Java и linux борьба за микросекунды"
Алексей Рагозин "Java и linux борьба за микросекунды"Алексей Рагозин "Java и linux борьба за микросекунды"
Алексей Рагозин "Java и linux борьба за микросекунды"
 
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"
 
Наш ответ Uber’у
Наш ответ Uber’уНаш ответ Uber’у
Наш ответ Uber’у
 
Александр Крашенинников "Hadoop High Availability: опыт Badoo"
Александр Крашенинников "Hadoop High Availability: опыт Badoo"Александр Крашенинников "Hadoop High Availability: опыт Badoo"
Александр Крашенинников "Hadoop High Availability: опыт Badoo"
 
Leonid Vasilyev "Building, deploying and running production code at Dropbox"
Leonid Vasilyev  "Building, deploying and running production code at Dropbox"Leonid Vasilyev  "Building, deploying and running production code at Dropbox"
Leonid Vasilyev "Building, deploying and running production code at Dropbox"
 
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...
 
Mete Atamel "Resilient microservices with kubernetes"
Mete Atamel "Resilient microservices with kubernetes"Mete Atamel "Resilient microservices with kubernetes"
Mete Atamel "Resilient microservices with kubernetes"
 
Andrew Stain "User acquisition"
Andrew Stain "User acquisition"Andrew Stain "User acquisition"
Andrew Stain "User acquisition"
 

Recently uploaded

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 

Recently uploaded (20)

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 

Max Voloshin - "Organization of frontend development for products with microservices"

  • 1.
  • 2. Max Voloshin ● Location: Dnipro, Ukraine ● Position: Team Lead, OWOX ● In professional software development since 2010 ● Fan of microservices and continuous deployment Photographer: Avilov Alexandr
  • 3. OWOX Business Intelligence As business: ● More than 1 million transactions per week in our clients' projects ● 1 000+ projects in 50 countries rely on our solutions ● $ 200 000+ daily handled our clients' costs on advertising As software: ● 10+ microservices in PHP/Java ● Web Components (Polymer 1.8) ● Several releases every day
  • 4. Why am I here? I want to share 9 improvements for making frontend development easier
  • 5. Who cares? Frontend development may be a constraint for your product
  • 7. #1
  • 8. Let frontend developer don't deal with content management #1
  • 9. <div class="e-wrap"> <div class="e-grid-col1 e-grid-col-empty"></div> <div class="e-grid-col8" role="main"> <h2 class="e-page-title"> Page not found </h2> <p class="error-message"> Incorrectly typed address or a page on the website no longer exists </p> <p class="error-link-wrap"><a href="/" class="error-link"> Home </a></p> </div> <div class="clear"></div> </div>
  • 10. Do you really want to change one selling text to another?.. #1
  • 11. Use mnemonic names of texts instead of hard-coded content #1
  • 12. Admin panel for content Write contentContent manager Frontend developer Frontend Write code Matched by mnemonic name #1
  • 13. Polymer <div class="e-wrap"> <div class="e-grid-col1 e-grid-col-empty"></div> <div class="e-grid-col8" role="main"> <h2 class="e-page-title"> <html-text name="NotFoundPage.Title"></html-text> </h2> <p class="error-message"> <html-text name="NotFoundPage.Message"></html-text> </p> <p class="error-link-wrap"><a href="/" class="error-link"> <html-text name="HomePage.Title"></html-text> </a></p> </div> </div>
  • 15. #2
  • 16. Let frontend developer use HTML/JS templating #2
  • 17. .answers-i-link:before { CSS as Smarty (PHP) template content: ""; position: absolute; left: -30px; width: 25px; height: 25px; background: url('/*{$settings.path}*//icons.png') 0 -414px no-repeat; } .answers-i-link:hover:before { background: url('/*{$settings.path}*//icons.png') 0 -373px no-repeat; } .answers-i-link.active:before { background: url('/*{$settings.path}*//icons.png') 0 -700px no-repeat; } .answers-i-link.active:hover:before { background: url('/*{$settings.path}*//icons.png') 0 -659px no-repeat; }
  • 18. {foreach $tree as $section} HTML as Smarty (PHP) template <h3 class="level-{$level}">{$section['title']}</h3> {if $section['children']} {include file='faq/subjects.tpl' tree=$section['children'] level=$level+1} {/if} {if isset($section['records'])} {foreach $section['records'] as $record} {if $is_contents} <a href="#record-{$record.id}" class="level-{$level}">{$record.title}</a><br /> {else} <a name="record-{$record.id}" class="level-{$level}">{$record.title}</a><br /> {$record['answer'] nofilter} {/if} {/foreach} {/if} {/foreach}
  • 19. HTML as Smarty (PHP) template <div class="b-expenses-head"> {foreach from=$manual_costs item="month" name="tabs"} <div id="manual-costs-tab-{$smarty.foreach.tabs.index}" class="inline b-expenses-head-month {if $month['is_active']}active{/if}"> <span class="b-expenses-month-title">{$month['month_title']}</span> </div> <script type="text/javascript"> ManualCosts.addGroup(new ManualCostsTab_class({$smarty.foreach.tabs.index}, '{$month['hash']}')); </script> {/foreach} </div>
  • 20. JS as Smarty (PHP) template initialize: function(data, connect_service_access) { this.parent(data, connect_service_access); Object.append( this._templates, {access_create: '/*{template_script_fetch file="access_create.jst" }*/'} ); this._popup.addEvent('createAccess', this.onCreateAccess.bind(this)); }, onCreateAccess: function() { this.send( '/*{$menu.my.href}*/users/access/simple_services#createAccess', { service_name: this._data['service_name'], token: token, service_account: service_account } ); }
  • 21. Do you really want to learn and debug non JS/HTML templating?.. #2
  • 22. Use HTML/JS templating, use data as JSON #2
  • 23. Polymer <template is="dom-if" if="[[!isEmpty(url)]]"> <page-item item-action> <a is="pushstate-anchor" href="[[url]]" class="item-action"> <text-html name="Page.Item.Actions.Edit"></text-html> </a> </page-item> </template>
  • 24. Polymer <dom-module id="page-external-link-styles"> <template> <style include="shared-styles"> :host { display: inline; white-space: nowrap; } :host(:not(.no-link-style)) a { color: var(--blue-color-main); text-decoration: none; } </style> </template> </dom-module>
  • 25. Bonus: static code analysis & tests #2
  • 26. #3
  • 27. Let frontend developer don't deal with backend routing #3
  • 28. Symfony (PHP) routing # app/config/routing.yml blog_list: path: /blog/{page} defaults: { _controller: AppBundle:Blog:list, page: 1 } requirements: page: 'd+' blog_show: # ...
  • 29. Do you really want to learn and debug backend routing?.. #3
  • 30. Use frontend routing via Single Page Application #3
  • 31. Polymer <app-router id="appRouter" mode="pushstate" init="manual"> <app-route id="dataPipeline" path$="[[globals.pathPrefix]]/:context/pipeline/" element="pipeline-page" import="/components/pages/pipeline/pipeline-page.html" ></app-route> <app-route id="costDataPage" path$="[[globals.pathPrefix]]/:context/pipeline/:property/:id/" redirect="history/" ></app-route> <app-route id="costDataHistoryPage" path$="[[globals.pathPrefix]]/:context/pipeline/:property/:id/history/" element="cost-data-page" import="/components/pages/cost-data/cost-data-page.html" ></app-route> </app-router>
  • 32. #4
  • 33. Let frontend developer don't deal with stagnated framework #4
  • 34. Switching framework is hard ● You can’t pause product development ● You can't release all changes at one time #4
  • 36. 1. Continuous deploy then single release #4
  • 37. UI v1 (MooTools) → UI v2 (Polymer 0.5) t Release v1 Deploy v2 (part #1) Change v1 prod Deploy v2 (part #2) Release v2 Deploy v2 (part #N) ... Deploy != Release #4 UI v1: https://domain.com/ UI v2: https://domain.com/v2/ ← SPA root
  • 38. Continuous deploy then single release + Compatible with design switching - Suitable only for small applications because of effort duplication #4
  • 39. Off topic: why Polymer? ● Material Design out of the box ● Possibilities to UI reuse (not only JS) ● Google promotion of Web Components ● #UseThePlatform #4
  • 41. The first law of holes #4
  • 42. Limitations: 1. Only one version of Polymer can be on page 2. We have Single Page Application Solution: “break points” in Single Page Application UI v2 — domain.com/v2/ UI v3 — domain.com/v3/ /foo/ /bar/ /baz/ /qux/ /foo/ /bar/ /baz/ /qux/ UI v2 (Polymer 0.5) → UI v3 (Polymer 1.8) #4
  • 43. UI v2 <app-router id="router" mode="pushstate" init="manual" <app-route id="pipeline" path="/ui/:context/pipeline/" import="{{$.globals.values.base_url}}pipeline-page/pipeline-page.html" ></app-route> <app-route id="cost_details" path="/ui/:context/pipeline/:property/:id/" redirect="history/" ></app-route> <app-route path="/ui/:context/pipeline/:property/:id/history/" import="{{$.globals.values.base_url}}cost-page/cost-page.html" new-page ></app-route> </app-router>
  • 44. <app-router id="appRouter" mode="pushstate" init="manual"> UI v3 <app-route id="pipeline" path$="[[globals.pathPrefix]]/:context/pipeline/" element="pipeline-page" import="/components/pages/pipeline/pipeline-page.html" ></app-route> <app-route id="costPage" path$="[[globals.pathPrefix]]/:context/pipeline/:property/:id/" redirect="history/" ></app-route> <app-route id="costHistoryPage" path$="[[globals.pathPrefix]]/:context/pipeline/:property/:id/history/" element="cost-data-page" import="/components/pages/cost-data/cost-data-page.html" old-page ></app-route> </app-router>
  • 45. + Suitable for any size applications - Only same design - Time delays between UI transitions Page-by-page release #4
  • 46. #5
  • 47. Let frontend developer deliver UI independently #5
  • 48. Delivery of UI with “monorepo” approach 1. Make changes 2. Wait till the whole monorepo can be deployed 3. Deploy #5
  • 49. Use standalone repository and continuous delivery pipeline #5
  • 50. Delivery of UI with “standalone repo” approach 1. Make changes 2. Wait till the whole monorepo can be deployed 3. Deploy #5
  • 51. #6
  • 52. Let frontend developer use remote backend #6
  • 53. UI changes with “local backend” approach 1. Update backend source with dependencies 2. Update storage data 3. Update environment 4. Try to figure out via guide/FAQ why backend is not working 5. Call backend developer who knows how to update this 6. Spend half hour together to find stupid environment problem 7. Repeat 1-6 for each microservice 8. Make changes to frontend #6
  • 54. UI changes with “remote backend” approach 1. Update backend source with dependencies 2. Update storage data 3. Update environment 4. Try to figure out via guide/FAQ why backend is not working 5. Call backend developer who knows how to update this 6. Spend half hour together to find stupid environment problem 7. Repeat 1-6 for each microservice 8. Make changes to frontend #6
  • 55. request identity token How to handle authorization? identity token (JSON Web Token) Backend Attach header to each further request Authorization: Bearer {identity token} Frontend #6
  • 56. #6
  • 57. #6
  • 58. #6
  • 59. #6
  • 60. #6
  • 61. #6
  • 62. jwt.io JSON Web Tokens libraries and debugger #6
  • 63. #7
  • 64. Let frontend developer don't deal with CORS #7
  • 65. #7
  • 66. UI – https://domain.com/ https://foo.appspot.com/ https://bar.heroku.com/ Cross-origin resource sharing ? #7
  • 67. CORS (Cross-origin resource sharing) ● Request headers ○ Origin ○ Access-Control-Request-Method ○ Access-Control-Request-Headers ● Response headers ○ Access-Control-Allow-Origin ○ Access-Control-Allow-Credentials ○ Access-Control-Expose-Headers ○ Access-Control-Max-Age ○ Access-Control-Allow-Methods ○ Access-Control-Allow-Headers #7
  • 68. Use your web server’s ability to serve UI and microservices from single domain #7
  • 69. server { server_name domain.com; location /api/foo/ { proxy_pass https://foo.appspot.com/; } location /api/bar/ { proxy_pass https://bar.heroku.com/; } } Nginx example #7
  • 70. #8
  • 71. Let frontend developer use production web server without digging into its configuration #8
  • 72. Nginx location /download/ { valid_referers none blocked server_names *.example.com; if ($invalid_referer) { #rewrite ^/ http://www.example.com/ return 403; } # rewrite_log on; # rewrite /download/*/mp3/*.any_ext to /download/*/mp3/*.mp3 rewrite ^/(download/.*)/mp3/(.*)..*$ /$1/mp3/$2.mp3 break; root /spool/www; #autoindex on; access_log /var/log/nginx-download.access_log download; }
  • 73. Do you really want to learn and debug production web server configuration?.. #8
  • 74. Why “dev web server” approach may fail? 1. HTTP caching issues 2. Security issues 3. Missing redirects #8
  • 75. Use production-like Docker containers with your local configuration #8
  • 80. .env docker-compose .override.yml Configuration $ docker-compose up init Configured web server $ docker-compose up -d serve #8
  • 81. #9
  • 82. Let frontend developer use production state of concrete user #9
  • 83. How to fix a bug? 1. Prepare state 2. Reproduce 3. Fix #9 ● manual actions ● accesses to services ● historical entities ● data uniqueness
  • 84. Let frontend developer receive identity token of concrete user but with read-only(!) permissions #9
  • 85. request identity token “Looks like” feature identity token of another user (read-only) Backend Attach header to each further request Authorization: Bearer {identity token} Frontend #9 Frontend developer configure
  • 86. #9
  • 87. Recap Let frontend developer: 1. don't deal with content management 2. use HTML/JS templating 3. don't deal with backend routing 4. don't deal with stagnated framework 5. deliver UI independently 6. use remote backend 7. don't deal with CORS 8. use production web server without digging into its configuration 9. use production state of concrete user