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

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.

Ates Goral

March 16, 2014
Tweet

More Decks by Ates Goral

Other Decks in Programming

Transcript

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

    View Slide

  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.

    View Slide

  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.

    View Slide

  4. about:me
    Hi!
    My name is Ates Goral,
    which is pronounced: “Atesh Gir-uhl”,
    because it’s actually spelled: Ateş Göral

    View Slide

  5. about:me
    Summer BBQ
    Look
    Winter Conference
    Look
    vs

    View Slide

  6. about:me
    Done: 8bit, 16bit, 32bit, 64bit
    68000 Assembly, Object Pascal, C++, Java,
    other things...
    Then HTML/CSS/JavaScript = bliss :)

    View Slide

  7. The Premise
    Single Page Application (SPA) with a usually
    stateless backend API
    Application state is on the UI

    View Slide

  8. The Premise
    Web server serves static assets:
    ● JavaScript
    ● HTML
    ● CSS
    ● Images
    ● ...

    View Slide

  9. The Premise
    Application server serves data
    Application server ~ web server

    View Slide

  10. MyPets

    View Slide

  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

    View Slide

  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

    View Slide

  13. Backend API
    Backend

    View Slide

  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
    ...

    View Slide

  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

    View Slide

  16. MyPets - List + Details
    Remove backend:
    demock/examples> git checkout no-api
    GET /api/pets
    → 404 Not Found

    View Slide

  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

    View Slide

  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

    View Slide

  19. Problem: Content-Type
    index.html → text/html :(
    index.json → application/json :)
    Angular doesn’t care. jQuery does.
    I haven’t checked other libs.

    View Slide

  20. Solution 1
    Configure static web server:
    ● Default documents + index.json
    ● MIME types + .json → application/json

    View Slide

  21. Solution 2
    jQuery.ajax options:
    + dataType: 'json'

    View Slide

  22. MyPets - Sign In

    View Slide

  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.

    View Slide

  24. Request Filtering
    Intercept, modify, pass down.
    APPLICATION
    INTERCEPTOR
    REQUEST
    FILTERING
    TRANSPORT
    APPLICATION
    TRANSPORT

    View Slide

  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

    View Slide

  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

    View Slide

  27. While we’re at it...
    We can interpret and modify the response as
    well.

    View Slide

  28. Request & Response Filtering
    Intercept, modify, pass down; then up.
    APPLICATION
    INTERCEPTOR REQUEST &
    RESPONSE
    FILTERING
    TRANSPORT

    View Slide

  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

    View Slide

  30. Behind the Scenes

    View Slide

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

    View Slide

  32. demock
    Library-agnostic and convention-agnostic
    APPLICATION
    TRANSPORT
    ADAPTOR
    TRANSPORT
    demock
    Request
    Request &
    Response
    REQUEST &
    RESPONSE
    FILTERS
    Request
    Request &
    Response

    View Slide

  33. demock
    Could also be used on the backend!

    View Slide

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

    View Slide

  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

    View Slide

  36. demock - Filter Ideas
    ● $header - set HTTP response headers
    ● $repeat - generate massive set of data
    ● $param - parameterize response content

    View Slide

  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.

    View Slide

  38. Enabling the Mock at Dev. Time
    Principle: Avoid contaminating production
    code with dev/test artifacts. Do it
    transparently if you can.

    View Slide

  39. Enabling the Mock at Dev. Time
    ● Already have plug-ins? A SDK plugin.
    ● Conditional dependencies, versioning
    ● Build pragmas, switches, etc.

    View Slide

  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.

    View Slide

  41. Pros & Cons

    View Slide

  42. Con: Synchronization
    Your mock data set and actual backend may
    go out of synch.

    View Slide

  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.)

    View Slide

  44. Con: It’s Still Code
    It’s declarative, but still has script-like
    qualities.

    View Slide

  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.

    View Slide

  46. Pro: Portable
    Implement an entire feature on your next 8
    hour flight.

    View Slide

  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.

    View Slide

  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

    View Slide

  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

    View Slide

  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^@#

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide


  55. View Slide

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

    View Slide

  57. Boulder Dash Cloning
    Writing Boulder Dash clones == “Hello World!”
    ● 68000 (Atari ST, Amiga)
    ● Object Pascal (PC)
    ● No C++ :( :( :(
    ● JavaScript (lost count)

    View Slide

  58. BD in 20 Lines of JavaScript
    http://magnetiq.com/bd20/

    View Slide

  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.lengthv})}

    View Slide

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

    View Slide

  61. Subpixel Scrolltext on a
    http://magnetiq.com/spst/
    Tiniest pixel font ever!
    1px by 4px

    View Slide