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

Clients in control building demand-driven systems with Om Next

Clients in control building demand-driven systems with Om Next

Traditional architectures are no longer suitable for the increasing needs of today's applications. The price is often paid in high bandwidth and reduced performance. Demand-driven design enables clients to request arbitrary data on demand. Companies like Facebook and Netflix have switched to demand-driven architectures to better embrace a great variety of continuously changing clients. Solutions like Relay and Falcor/JSONGraph distill such ideas. Om Next builds on, and extends these concepts further, to provide a Clojure(Script) based solution. In this talk, I present the motivation for a demand-driven approach and explore the benefits and tradeoffs that Om Next brings to the table.

António Monteiro

September 08, 2016
Tweet

More Decks by António Monteiro

Other Decks in Programming

Transcript

  1. Full Stack Fest - 2016
    @anmonteiro90
    Clients in control
    building demand-driven
    systems with Om Next

    View Slide

  2. View Slide

  3. REST: expectations
    • define logical “resources”
    • identified by URIs
    • clients request them

    View Slide

  4. REST: reality
    • can only request / create trivial data
    • “joined” resources
    • bloat endpoint?
    • multiple requests?

    View Slide

  5. – Roy T. Fielding, PhD
    “The trade-off, though, is that a uniform
    interface degrades efficiency, since information
    is transferred in a standardized form rather
    than one which is specific to an application's
    needs.”

    View Slide

  6. Luke Wroblewski

    View Slide

  7. View Slide

  8. View Slide

  9. “Demand-driven” architecture

    View Slide

  10. 1. Demand

    View Slide

  11. 2. Composition

    View Slide

  12. 3. Interpretation

    View Slide

  13. “[…] GraphQL is a “query language”
    just like URLs are the “query language”
    of REST—it’s a contract that describes
    how to tell the API server what you’re
    looking for.”
    – Sashko Stubailo, Meteor
    http://goo.gl/qR9szX (Medium)

    View Slide

  14. Demo

    View Slide

  15. https://facebook.github.io/react/

    View Slide

  16. https://facebook.github.io/relay/ http://graphql.org/

    View Slide

  17. “used to hit a RESTful API server at Facebook
    […]. In transitioning to GraphQL, we deleted
    tons of code. […] it ended up being
    dramatically simpler from the client's point of
    view.”
    – Lee Byron, GraphQL Engineer
    https://javascriptair.com/episodes/2016-05-18

    View Slide

  18. https://netflix.github.io/falcor/

    View Slide

  19. View Slide

  20. Transit
    http://clojurescript.org/
    https://github.com/cognitect/transit-format
    http://clojure.org/
    http://www.datomic.com/

    View Slide

  21. om.next
    https://github.com/omcljs/om

    View Slide

  22. 1. clients can request the exact total
    response they need
    2. clients can communicate novelty
    atomically
    • without sacrificing relational queries on
    the server

    View Slide

  23. Om Next opinions
    • Single source of truth
    • Minimize flushing to DOM
    • No (visible)
    • asynchrony
    • event model

    View Slide

  24. Checkpoint
    • Precise requests?
    • Client
    • Server
    • Communicate novelty?
    • Communicate
    identity back?
    • Data over the wire?
    • Client-only state
    • Testing
    • Caching
    • Pluggable client /
    server storage?

    View Slide

  25. View Slide

  26. [:person/name]

    View Slide

  27. (defui Person
    static om/IQuery
    (query [this]
    [:person/name])
    Object
    (render [this]
    ...))

    View Slide

  28. Query expressions

    View Slide

  29. :person/name
    ‘(:person/friends {:sort :asc})
    {:person/address
    [:address/street :address/zip]}

    View Slide

  30. (increment/users!)
    (delete/friend!
    {:me 1
    :friend 2})

    View Slide

  31. Parser

    f (query) = data
    [:person/name]
    {:person/name “António”}

    View Slide

  32. Parser
    • reads & mutations
    • Runs on front- & backend
    • Hydrate queries
    • no reshaping!
    • Edge of the system

    View Slide

  33. [(person/add!
    {:person/name “António”
    :person/address
    {:address/street
    “Hochschulstraße”
    :address/zip “01069”}})]

    View Slide

  34. [(delete/friend! {:me 1
    :friend 2})
    :friends/list]
    Re-read this key

    View Slide

  35. Creating information
    • Create temporary information
    on client
    • Remote mutation hits server
    • Server replies with mappings
    • tempids → real ids

    View Slide

  36. View Slide

  37. Client-only state
    • First-class support
    • Storage: merged with remote
    state
    • Parser distinguishes local / server
    • able to pick remote queries

    View Slide

  38. View Slide

  39. Normalization

    View Slide

  40. Normalization
    • Also in Relay, Falcor
    • Om Next can automatically
    • Normalize
    • Denormalize

    View Slide

  41. {:people [{:person/name “Alice”
    :person/age 25}
    {:person/name “Bob”
    :person/age 34}]
    :favorites [{:person/name “Bob”
    :person/age 34}]}

    View Slide

  42. {:people [[:person/by-name “Alice”]
    {:person/name “Bob”
    :person/age 34}]
    :favorites [{:person/name “Bob”
    :person/age 34}]
    :person/by-name
    {“Alice” {:person/name “Alice”
    :person/age 25}}}

    View Slide

  43. {:people [[:person/by-name “Alice”]
    [:person/by-name “Bob”]]
    :favorites [[:person/by-name “Bob”]]
    :person/by-name
    {“Alice” {:person/name “Alice”
    :person/age 25}
    “Bob” {:person/name “Bob”
    :person/age 34}}}

    View Slide

  44. React render
    Transaction
    Re-render

    View Slide

  45. Incremental rendering
    (Om Next)
    Transaction
    Re-render

    View Slide

  46. View Slide

  47. Testing
    • global state + parser = awesome
    • Pure components

    f (data) = UI
    • We can just test the UI data tree!

    View Slide

  48. Property-based testing
    • example-based
    • specify input / output pairs
    • property-based
    • write invariants
    • generate random input
    • attempt to falsify invariants, shrinking

    View Slide

  49. Om Next + test.check
    • queries / mutations are data
    • generate transactions
    • run against the parser
    • check invariants in resulting state

    View Slide

  50. Demo

    View Slide

  51. Testing recap
    1. Generate random transactions
    2. Shrink failures
    3. Use minimal failure to reproduce bugs

    View Slide

  52. Testing recap
    1. Generate random transactions
    2. Shrink failures
    3. Use minimal failure to reproduce bugs

    View Slide

  53. More Om Next
    • Recursive UIs
    • Heterogeneous
    UIs
    • HTTP Caching
    • Custom storage
    • Streaming
    • Server-side
    rendering

    View Slide

  54. Server
    • Clojure preferred / less boilerplate
    • Other languages -> implement parser logic
    • easier for languages with Transit
    • Datomic supported by default
    • other DBs work as well

    View Slide

  55. Project status
    • Beta next week
    • documentation
    • github.com/omcljs/om/wiki
    • awkay.github.io/om-tutorial/
    • anmonteiro.com

    View Slide

  56. Takeaways
    • we can radically simplify UI
    programming
    • regardless of library / framework
    • strive for simple systems
    • with these 2 properties

    View Slide

  57. github.com/anmonteiro/talks

    View Slide

  58. Questions?

    View Slide