Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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.

Slide 3

Slide 3 text

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.

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

about:me Summer BBQ Look Winter Conference Look vs

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

The Premise Application server serves data Application server ~ web server

Slide 10

Slide 10 text

MyPets

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Backend API Backend

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

MyPets - List + Details Add an index.html file under /api/pets: GET /api/pets → 200 OK Fast forward: demock/examples> git checkout get-api

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

MyPets - Sign In

Slide 23

Slide 23 text

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.

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

MyPets - Sign In - Response Filtering Special properties in the response object to trigger changes to the response. Fast forward: demock/examples> git checkout master

Slide 30

Slide 30 text

Behind the Scenes

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

demock Could also be used on the backend!

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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.

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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.

Slide 41

Slide 41 text

Pros & Cons

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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.

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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.

Slide 48

Slide 48 text

Pro: Handcrafted Permutations ● Bare minimum, fully representative set ● Establish convention for deterministic naming of entities ● Don’t use a backend snapshot full of junk

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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