Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Backends for frontends
Search
Daniele Polencic
May 10, 2016
Technology
150
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Backends for frontends
Daniele Polencic
May 10, 2016
More Decks by Daniele Polencic
See All by Daniele Polencic
Zero to Kubernetes — Developer's Gym Singapore
danielepolencic
2
220
Scaling Microservices with Message Queues, Spring Boot and Kubernetes
danielepolencic
3
380
7 tips and tricks on how to make the most of your Kubernetes journey
danielepolencic
3
310
Deploying and Scaling Spring Boot Microservices to Amazon EKS
danielepolencic
1
700
From Zero to Forex Trading Bot Hero with Node.js and Typescript
danielepolencic
0
390
Kubernetes Chaos Engineering: Lessons Learned in Networking
danielepolencic
0
250
Deploying and Scaling Spring Boot Microservices to Kubernetes
danielepolencic
0
120
Scaling Machine Learning in the Cloud with Kubernetes
danielepolencic
0
130
From Zero to Forex Trading bot Hero
danielepolencic
0
150
Other Decks in Technology
See All in Technology
"優秀な誰か"の下位互換にならないために
yut0naga1_fa
0
130
転んだ話が背中を預ける理由になる / A_story_about_falling_down_gives_you_a_reason_to_watch_each_other_s_backs.pdf
pauli
3
330
Meet AgentCore Identity Consent Portal
hironobuiga
3
190
FOSS4Gを活用した自治体業務DXの試み
470715
0
120
無理せず続ける、子育てエンジニアの学び
codmoninc
PRO
0
410
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
17
120k
分析の民主化を支えるメタデータ整備の実践
kakehashi
PRO
2
960
AI時代に必要な脅威モデリング― 変化の速度に負けない理解とリスク判断
masakane55
5
1.2k
あなたの知らないAmazon VPC Route Server/Amazon VPC Route Server you don't know about
masakiokuda
2
230
ファミコンでPHPを動かす / PHP on the Famicom side b
tomzoh
0
140
20260930_Gemma4_Hands-on
tsho
0
240
生成AIで高い生産性を求められて、 悩み、乗り越えた話
mot_techtalk
2
130
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
142
7.7k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.1k
Automating Front-end Workflow
addyosmani
1369
210k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
320
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
260
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
550
Designing Powerful Visuals for Engaging Learning
tmiket
1
600
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
300
Transcript
backends for frontends @danielepolencic
the good old days !
None
monolith templates cosmetic js
ajax ! revolution
None
api driven js widgets encapsulation
modern js era
None
serverless single page apps js bunsiness logic
serverless
just html, js & css
easy to deploy easy to build easy to scale
what about backend?
perfect rest api
None
everybody wins
None
!
how do you authenticate?
server side class UsersController < ApplicationController before_action :logged_in_user ... end
1. user requests page 2. redirected to login
client side UsersApi.isLoggedIn(cookie).then(user => { ... });
1. user requests page 2. wait for app to load
3. ajax request to /me 4. redirect
! are we there yet?
also1
auth server api
PUBLIC FACING AUTH SERVER
PUBLIC FACING AUTH SERVER
rest api + auth
frontend ! architecture
also2
tokens vs !!
CORS stateless CSRF JWT mobile
frontend ! backend apis
also3
little secrets
None
None
no harm, but... do you have a choice?
!
!
what about bootstrapping?
server side <body> ... <script> App.photos = new Photos([ {
id: 2, name: "My dog", filename: "IMG_0392.jpg" }, { id: 3, name: "Our house", filename: "IMG_0393.jpg" }, { id: 4, name: "My favorite food", filename: "IMG_0394.jpg" }, { id: 5, name: "His bag", filename: "IMG_0394.jpg" }, ... ]); </script> </body>
client side function AppController() { loadPhotos().then(photos => { ... });
}
1. user requests page 2. wait for app to load
3. ajax request to /photos 4. render page
! are we there yet?
… and this is the best case scenario
1. ajax request to /photos 2. ajax request to /posts
3. ajax request to /comments
!
what about aggregating calls?
server side class ClientsController < ApplicationController def fetch posts_response =
conn.get '/posts' followers_response = conn.get '/followers' ... end end <body> ... <script> App.photos = new Photos([ { id: 2, name: "My dog", filename: "IMG_0392.jpg" }, { id: 3, name: "Our house", filename: "IMG_0393.jpg" }, { id: 4, name: "My favorite food", filename: "IMG_0394.jpg" }, { id: 5, name: "His bag", filename: "IMG_0394.jpg" }, ... ]); </script> </body>
3 db queries
3 http requests server ✌ server
client side 3 http requests
! are we there yet?
SELECT * FROM Photos INNER JOIN Followers
!
!
cannot trust the user
None
client side <body> <form action="" method="post"> <div class="g-recaptcha" data-sitekey="site_key_here"></div> <input
type="submit" value="Submit" /> </form> <script src='https://www.google.com/recaptcha/api.js'></script> </body>
backend $reCaptcha = new ReCaptcha($secret); if ($_POST["g-recaptcha-response"]) { $response =
$reCaptcha->verifyResponse( $_SERVER["REMOTE_ADDR"], $_POST["g-recaptcha-response"] ); }
sadly, no client side only captcha
None
! solution !
REST SERVER
CAPTCHA API REST SERVER
client specific code in the rest api !
!
cross-origin resource sharing
fe: www.mysite.com be: api.mysite.com
nginx config # # Wide-open CORS config for nginx #
location / { if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept'; } # ... }
front-end specific code in the web server
whatch out for glitches1
cookies are not included with preflight requests
None
PUBLIC FACING AUTH SERVER
PUBLIC FACING AUTH SERVER IF PREFLIGHT
in the auth server unless is_preflight_request? do authorise_request end
client specific code in the rest api !
whatch out for glitches2
ie9 doesn't send cookies at all
None
None
client specific code in nginx !
whatch out for glitches3
None
If the 302 status code is received in response to
a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued - w3
CORS REDIRECT Y U NO WORK???
!"#$...
websockets, sse, long polling batch api calls api data filter/enhance
validation
but...
just html, js & css
meanwhile your app...
it's fast !
it's easy to develop !
it's secure !
meanwhile your architecture...
AUTH SERVER REST API #2 REST API #1
AUTH SERVER REST API #2 REST API #1 FRONT-END CODE
AUTH SERVER REST API #2 REST API #1 CAPTCHA
AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT
PREFLIGHT
AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT
CORS PREFLIGHT
AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT
CORS PREFLIGHT BOOTSTRAPPING
AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT
CORS PREFLIGHT BOOTSTRAPPING FRONT-END CODE
AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT
CORS PREFLIGHT BOOTSTRAPPING FRONT-END CODE
AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT
CORS PREFLIGHT BOOTSTRAPPING infrastructure coupling
AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT
CORS PREFLIGHT BOOTSTRAPPING no separation of concerns
AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT
CORS PREFLIGHT BOOTSTRAPPING hidden dependencies
just html, js & css
so what shall you do?
going back to server side rendering?
nope.
ignore and move on?
nope.
good artists copy, great artists steal — Pablo Picasso
! presentation layer !
None
None
FRONT-END CODE
does it help?
PRESENTATION LAYER
PRESENTATION LAYER same domain
!! issues no more
cors & preflight request const express = require('express'); const cors
= require('cors'); const app = express(); app.options('/products/:id', cors()); app.del('/products/:id', cors(), (req, res) => { res.json({msg: 'CORS-enabled for all origins!'}); }); app.listen(3000, () => { console.log('web server listening on port 80'); });
user authentication const express = require('express'); const passport = require('passport');
const app = express(); app.post('/login', passport.authenticate('local'), (req, res) => { res.redirect('/'); });
bootstrapping1 const express = require('express'); const app = express(); app.get('/dashboard',
(req, res) => { res.render('homepage.html', { googleAnalyticsId: '123', locale: 'en_GB' }); });
bootstrapping2 <body> ... <script> angular .module('myApp', []) .constant('GA', '{{ googleAnalyticsId
}}') .constant('locale', '{{ locale }}') </script> </body>
captcha const express = require('express'); const app = express(); const
Captcha = require('./captcha'); const captcha = new Captcha(PUBLIC_KEY, PRIVATE_KEY); app.post('/comment', (req, res) => { captcha .verify(req.body['g-recaptcha-response']) .then(() => res.send('success!')); });
api aggregation const express = require('express'); const app = express();
app.post('/posts-and-flower', (req, res) => { Promise.all([ request.get('http://service1.com/posts'), request.get('http://service2.com/flowers') ]).spread((posts, flowers) => res.json({ posts, flowers })) });
websockets const http = require('http'); const sockjs = require('sockjs'); var
echo = sockjs.createServer({...}); echo.on('connection', (conn) => { conn.on('data', (message) => { request.get(`http://service1.com/${message}`) .then(response => conn.write(response)); }); conn.on('close', () => {}); }); const server = http.createServer(); echo.installHandlers(server, {prefix:'/echo'}); server.listen(9999, '0.0.0.0');
all requests are routed through the presentation layer
API {aggregation, filtering, enhancing}, data validation, encapsulation, state, cors, credentials,
caching, bootstrapping
wait
this is not front-end
PRESENTATION LAYER
this is the new front-end
None
freedom to create api, architecture visibility, better ux, SRP and
SOC, clearer responsabilities in the team
great power great responsability
static html vs real server
deployment
AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT
CORS PREFLIGHT BOOTSTRAPPING FRONT-END CODE PRESENTATION LAYER
scalability
performance
security and testing
point of failure
no, it doesn't make sense if you're building todo apps
nothing new adapter pattern
netflix
None
None
soundcloud
None
None
spotify
None
paypal
None
uber
None
what about you?
thanks