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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
300
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
Hatena Engineer Seminar 37 jj1uzh
jj1uzh
0
440
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
11k
LiDAR SLAMの実装とセンサ融合 ~Lie群からContinuous-Time LIOまで~
naokiakai
1
970
從觀望到全公司落地:AI Agentic Coding 導入實戰 — 流程整合與安全治理
appleboy
1
1k
美しいコードを書くためにF#を学んでみた話
yud0uhu
1
210
テスト設計の本質を改めて考えてみる~生成AIを活用する時代だからこそ、作ったテストの説明性を高めよう~
yamasaki696
1
300
依頼文化をやめる日 EM視点で語るPlatform EngineeringとInclusive SRE / Discussing Platform Engineering and Inclusive SRE from an EM's Perspective
shin1988
3
2.4k
どうして今サーバーサイドKotlinを選択したのか
nealle
0
200
スタートアップにおけるアジャイルの実践について #shibuyagile
murabayashi
3
2.1k
なぜ私たちのSREプラクティスはなかなか機能しないのか 〜システムより先に組織を見る〜 / Why our SRE practices aren't really working
vtryo
0
910
AIに「使われる」時代のSaaS戦略 〜既存WebAPIのMCPサーバー化における開発ノウハウ〜
ekispert_api
0
290
AIDLC_ヤフーショッピングの取り組み
lycorptech_jp
PRO
0
540
Featured
See All Featured
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
280
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
180
Exploring anti-patterns in Rails
aemeredith
3
440
How to Talk to Developers About Accessibility
jct
2
280
RailsConf 2023
tenderlove
30
1.5k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
Into the Great Unknown - MozCon
thekraken
41
2.6k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
180
Tell your own story through comics
letsgokoyo
1
980
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
Optimizing for Happiness
mojombo
378
71k
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