SlideShare ist ein Scribd-Unternehmen logo
1 von 88
Downloaden Sie, um offline zu lesen
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?

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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
 

Ähnlich wie 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
 

Ähnlich wie 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
 

Mehr von 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
 

Mehr von 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"
 

Kürzlich hochgeladen

"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
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
 
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
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
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
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 

Kürzlich hochgeladen (20)

"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
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
 
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!
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
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.
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 

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