Backend-less UI Development

Backend-less UI Development

While the modern web development environment has many tools for easily setting up and running your backend (via package managers, dependency managers, migrations, etc.), there are still some advantages to having a simple mock backend that allows a single-page application to be run literally after a simple checkout. I will show a simple exploit to use any static web server as your mock backend. An HTTP transport adaptor for your favourite library (jQuery being one) can also be used for the best effect; simulating HTTP verbs, HTTP response codes, as well as latency.

C7f65a2f291636c0bd19920b2b6d525b?s=128

Ates Goral

March 16, 2014
Tweet

Transcript

  1. Backend-less UI Development Ates Goral, Myplanet @atesgoral, myplanet.io jQueryTO 2014

  2. tl;dr • A simple approach for mocking an application server’s

    API. • An implementation + demo of it. • A discussion around pros/cons of mocking your API like this.
  3. Mocking Your API “You’re not RESTful and you reek of

    RPC!” Simulating a backend with scripted responses in order to aid development and testing.
  4. about:me Hi! My name is Ates Goral, which is pronounced:

    “Atesh Gir-uhl”, because it’s actually spelled: Ateş Göral
  5. about:me Summer BBQ Look Winter Conference Look vs

  6. about:me Done: 8bit, 16bit, 32bit, 64bit 68000 Assembly, Object Pascal,

    C++, Java, other things... Then HTML/CSS/JavaScript = bliss :)
  7. The Premise Single Page Application (SPA) with a usually stateless

    backend API Application state is on the UI
  8. The Premise Web server serves static assets: • JavaScript •

    HTML • CSS • Images • ...
  9. The Premise Application server serves data Application server ~ web

    server
  10. MyPets

  11. MyPets > git clone https://github.com/atesgoral/demock > cd demock/examples demock/examples> bower

    install demock/examples> npm install -g serve demock/examples> serve .. http://localhost:3000/examples/angular.html http://localhost:3000/examples/jquery.html
  12. A SPA Can Be Very Complicated • 100’s or 1000’s

    of JavaScript modules • Plug-ins • Many external services • Many ways your environment can break
  13. Backend API Backend

  14. Rendering Typically, a view can be rendered with just GET

    requests: • GET /lib/jquery.min.js • GET /scripts/main.js • GET /api/user/status • GET /api/bills ...
  15. A Trivial Realization Default document feature: GET requests against an

    API can be simulated with a static web server. GET /api/entities → GET /api/entities/index.html
  16. MyPets - List + Details Remove backend: demock/examples> git checkout

    no-api GET /api/pets → 404 Not Found
  17. MyPets - List + Details Add an index.html file under

    /api/pets: GET /api/pets → 200 OK Fast forward: demock/examples> git checkout get-api
  18. What did we just accomplish? • Render an entire application

    without its backend, however complex it may be • Not a single line of change to our application • No external tools, frameworks added -- just a good old static web server
  19. Problem: Content-Type index.html → text/html :( index.json → application/json :)

    Angular doesn’t care. jQuery does. I haven’t checked other libs.
  20. Solution 1 Configure static web server: • Default documents +

    index.json • MIME types + .json → application/json
  21. Solution 2 jQuery.ajax options: + dataType: 'json'

  22. MyPets - Sign In

  23. Problem: Other HTTP Methods Can’t simulate POST, PUT, DELETE, etc.

    with a static web server. Need to start tapping into the HTTP transport layer.
  24. Request Filtering Intercept, modify, pass down. APPLICATION INTERCEPTOR REQUEST FILTERING

    TRANSPORT APPLICATION TRANSPORT
  25. Convention: Append Method to Path POST /api/entities → GET /api/entities/POST

    → GET /api/entities/POST/index.html DELETE /api/entities/1 → GET /api/entities/1/DELETE → GET /api/entities/1/DELETE/index.html
  26. MyPets - Sign In Add transport interceptor and an index.html

    file under /api/signIn/POST: GET /api/signIn/POST → 200 OK Fast forward: demock/examples> git checkout post-api
  27. While we’re at it... We can interpret and modify the

    response as well.
  28. Request & Response Filtering Intercept, modify, pass down; then up.

    APPLICATION INTERCEPTOR REQUEST & RESPONSE FILTERING TRANSPORT
  29. MyPets - Sign In - Response Filtering Special properties in

    the response object to trigger changes to the response. Fast forward: demock/examples> git checkout master
  30. Behind the Scenes

  31. demock Declarative mocking with static JSON https://github.com/atesgoral/demock

  32. demock Library-agnostic and convention-agnostic APPLICATION TRANSPORT ADAPTOR TRANSPORT demock Request

    Request & Response REQUEST & RESPONSE FILTERS Request Request & Response
  33. demock Could also be used on the backend!

  34. demock Tiny interface .filterRequest(request) .filterResponse(request, response) .requestFilters .responseFilters .config

  35. demock - Stock Filters • $method - append method to

    path • $defaultDocument - append default document to path (disabled) • $delay - introduce latency • $timeout - trigger HTTP timeout • $status - override HTTP response status • $switch - conditional responses based
  36. demock - Filter Ideas • $header - set HTTP response

    headers • $repeat - generate massive set of data • $param - parameterize response content
  37. What About Production Time? Q: How do you enable the

    mock only at development time? A: It’s application-specific. I don’t have a single answer.
  38. Enabling the Mock at Dev. Time Principle: Avoid contaminating production

    code with dev/test artifacts. Do it transparently if you can.
  39. Enabling the Mock at Dev. Time • Already have plug-ins?

    A SDK plugin. • Conditional dependencies, versioning • Build pragmas, switches, etc.
  40. Prior Art There are blog posts, libraries, and even facilities

    built into frameworks for server mocking. Some are similar to this approach of using statically serving JSON files.
  41. Pros & Cons

  42. Con: Synchronization Your mock data set and actual backend may

    go out of synch.
  43. Con: Not Exercising the Full Stack Bugs elsewhere in the

    stack may escape. Certain bugs only surface in certain conditions (latency, exact order of asynchronous operations, etc.)
  44. Con: It’s Still Code It’s declarative, but still has script-like

    qualities.
  45. Pro: Fast! Once initial setup is done, it’s checkout-and- go.

    Change a single line of code, hit Refresh (or use live reloading) and see the result right away.
  46. Pro: Portable Implement an entire feature on your next 8

    hour flight.
  47. Pro: Rapid Prototyping Focus on what you need to achieve

    on the UI. Once the API is nailed down, the UI side of things are done. It’s not wasted effort.
  48. Pro: Handcrafted Permutations • Bare minimum, fully representative set •

    Establish convention for deterministic naming of entities • Don’t use a backend snapshot full of junk
  49. Pro: Edge Cases Easily mock hard-to-reproduce edge cases: • Network

    latency • Request timeout • 503 Internal Server Error • Legacy/incompatible data from backend • Looooooooooooooong text • Ünḯcṏde
  50. Pro: Permutations, Edge Cases ✔ DO: • User One, ...

    • John Doe, ... • Jane Withlonglastname • Elmo • 宮崎 駿 ✘ DON’T: • Test User1 • Test User11 • DELETEME • Bob’s Third Test • __TEMPPPPPPP • testing 123^@#
  51. Pro: UI-first Design The UI is your storefront • Focus

    on user experience • Interaction design that’s uninhibited by technical concerns • Optimize for performance later
  52. Pro: API-first Design • Decouple API from ugly implementation details

    of the backend • Backend is a black box • UI is the primary consumer of the API • API is immediately reusable
  53. Pro: API-first Design Specification by Example (SBE) • Save time

    from separately documenting the API via JSON Hyper-Schema, WADL, WSDL, Swagger, etc. • “Here, I want to receive this.” • Leaves no room for ambiguity, reduces feedback loops
  54. Pro: Synchronization (bis) Your mock data set and actual backend

    may go out of synch. • Makes you more cognizant about backwards compatibility of your API • Good opportunity to assess the impact to consumers of your API
  55. </content>

  56. MOAR about:me Some of my wackier work...

  57. Boulder Dash Cloning Writing Boulder Dash clones == “Hello World!”

    • 68000 (Atari ST, Amiga) • Object Pascal (PC) • No C++ :( :( :( • JavaScript (lost count)
  58. BD in 20 Lines of JavaScript http://magnetiq.com/bd20/

  59. Tweet-sized Functions http://140byt.es Date formatter (132 characters): function(d,f){return f.replace(/{(.+?)(?::(.*?))?}/g,function(v, c,p){for(v=d["get"+c]()+/h/.test(c)+"";v.length<p;v=0+v);return

    v})}
  60. HTML Polygons http://blog.magnetiq.com/post/516048517/rendering-n-sided-polygons-with-dhtml

  61. Subpixel Scrolltext on a <canvas> http://magnetiq.com/spst/ Tiniest pixel font ever!

    1px by 4px