Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Backends for frontends
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
290
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
380
Kubernetes Chaos Engineering: Lessons Learned in Networking
danielepolencic
0
230
Deploying and Scaling Spring Boot Microservices to Kubernetes
danielepolencic
0
110
Scaling Machine Learning in the Cloud with Kubernetes
danielepolencic
0
100
From Zero to Forex Trading bot Hero
danielepolencic
0
140
Other Decks in Technology
See All in Technology
2026TECHFRESH畢業分享會 - Lightning Talk - 資料也要 CI/CD? 用 Airbyte 自動化資料同步
line_developers_tw
PRO
0
1.3k
【セミナー資料】Claude Code をセキュアに使うための考え方と設定の勘どころ / Claude Code Webinar 20260616
masahirokawahara
2
420
2026TECHFRESH畢業分享會 - Lightning Talk - E起 See See : 電商推薦讀心術? 數據說了算
line_developers_tw
PRO
0
1.3k
AIのReact習熟度を測る
uhyo
2
660
PostgreSQL 19 新機能概要 OSC Hokkaido 2026
nori_shinoda
0
170
人材育成分科会.pdf
_awache
4
300
アンオフィシャルな、オフィシャルからのお願い
wyamazak_devrel
0
140
Oracle Cloud Infrastructure:2026年6月度サービス・アップデート
oracle4engineer
PRO
0
140
iOS アプリの「これって不具合ですか?」を AI に調べてもらう
miichan
0
110
SONiCで構築・運用する生成AI向けパブリッククラウドネットワーク ~実装編~
sonic
0
290
Kiro Ambassador を目指す話
k_adachi_01
0
110
アジャイルな経理と Claude Code と経営の未来
kawaguti
PRO
3
170
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
850
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
What's in a price? How to price your products and services
michaelherold
247
13k
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
66
55k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
sira's awesome portfolio website redesign presentation
elsirapls
0
280
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