Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Backends for frontends

Backends for frontends

Daniele Polencic

May 10, 2016
Tweet

More Decks by Daniele Polencic

Other Decks in Technology

Transcript

  1. !

  2. 1. user requests page 2. wait for app to load

    3. ajax request to /me 4. redirect
  3. !

  4. !

  5. 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>
  6. 1. user requests page 2. wait for app to load

    3. ajax request to /photos 4. render page
  7. !

  8. 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>
  9. !

  10. !

  11. 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>
  12. backend $reCaptcha = new ReCaptcha($secret); if ($_POST["g-recaptcha-response"]) { $response =

    $reCaptcha->verifyResponse( $_SERVER["REMOTE_ADDR"], $_POST["g-recaptcha-response"] ); }
  13. !

  14. 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'; } # ... }
  15. 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
  16. AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT

    CORS PREFLIGHT BOOTSTRAPPING FRONT-END CODE
  17. AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT

    CORS PREFLIGHT BOOTSTRAPPING FRONT-END CODE
  18. AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT

    CORS PREFLIGHT BOOTSTRAPPING infrastructure coupling
  19. AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT

    CORS PREFLIGHT BOOTSTRAPPING no separation of concerns
  20. AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT

    CORS PREFLIGHT BOOTSTRAPPING hidden dependencies
  21. 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'); });
  22. user authentication const express = require('express'); const passport = require('passport');

    const app = express(); app.post('/login', passport.authenticate('local'), (req, res) => { res.redirect('/'); });
  23. bootstrapping1 const express = require('express'); const app = express(); app.get('/dashboard',

    (req, res) => { res.render('homepage.html', { googleAnalyticsId: '123', locale: 'en_GB' }); });
  24. 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!')); });
  25. 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 })) });
  26. 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');
  27. freedom to create api, architecture visibility, better ux, SRP and

    SOC, clearer responsabilities in the team
  28. AUTH SERVER REST API #2 REST API #1 CAPTCHA PREFLIGHT

    CORS PREFLIGHT BOOTSTRAPPING FRONT-END CODE PRESENTATION LAYER