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 these concepts to provide a Clojure(Script) based solution. Having clients be in control, we can design dynamic endpoints that run demand-driven queries directly.

In this talk, I present the motivation for a demand-driven approach and explore the solutions that Om Next brings to the table.

António Monteiro

April 29, 2016
Tweet

More Decks by António Monteiro

Other Decks in Programming

Transcript

  1. Clients in control
    building demand-driven
    systems with Om Next
    Craft Conf 2016
    @anmonteiro90

    View Slide

  2. View Slide

  3. View Slide

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

    View Slide

  5. REST: reality
    • only able to request trivial data
    • “joined” resources
    • bloat endpoint?
    • multiple requests?

    View Slide

  6. – Roy T. Fielding, PhD
    “The REST interface is designed to be efficient
    for large-grain hypermedia data transfer, […]
    resulting in an interface that is not optimal for
    other forms of architectural interaction.”

    View Slide

  7. REST

    View Slide

  8. REST

    View Slide

  9. REST

    View Slide

  10. REST

    View Slide

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

  12. Luke Wroblewski

    View Slide

  13. How to write a service that
    meets the varying demands
    of heterogeneous clients?

    View Slide

  14. View Slide

  15. View Slide

  16. View Slide

  17. Let’s keep looking…

    View Slide

  18. View Slide

  19. Desirable properties
    • clients can request the exact total
    response they need
    • clients can communicate novelty
    atomically
    • without sacrificing relational queries on
    the server

    View Slide

  20. View Slide

  21. View Slide

  22. View Slide

  23. Checkpoint
    • How to make precise
    requests?
    • Client
    • Server
    • How do clients
    communicate novelty?
    • Communicate identity
    back to client?
    • Communication over the
    wire?
    • Client-only state
    • Testing
    • Caching
    • Pluggable client / server
    storage?

    View Slide

  24. Transit

    View Slide

  25. Enter Om Next…

    View Slide

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

    View Slide

  27. View Slide

  28. [:person/name]

    View Slide

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

    View Slide

  30. Query expressions
    :person/name
    (:person/friends {:sort :asc})
    {:person/address
    [:address/street :address/zip]}

    View Slide

  31. Query expressions
    (increment/users!)
    (delete/friend! {:me 1 :friend 2})

    View Slide

  32. Parser
    • Evaluates query expressions
    • Hydrates queries
    • no reshaping!

    View Slide

  33. Parser
    [:person/name]
    {:person/name “António”}

    View Slide

  34. Parser
    • Runs on the client and server
    • Runs reads and mutations

    View Slide

  35. Demo

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  39. View Slide

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

    View Slide

  41. View Slide

  42. View Slide

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

    View Slide

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

    View Slide

  45. {: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

  46. View Slide

  47. Testing
    • global app state + immutability = awesome
    • Parser abstraction = 1 place
    • React = pure function
    • 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 tests
    • 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. 1. Generate random transactions
    2. Shrink failures
    3. Use minimal failure to
    reproduce bugs
    Testing recap

    View Slide

  53. More Om Next
    • Recursive UIs
    • Heterogeneous UIs
    • HTTP Caching
    • Custom client side storage
    • Streaming

    View Slide

  54. Server
    • Clojure preferred / less boilerplate
    • Other languages need to implement
    parser logic
    • easier for languages with Transit
    implementation
    • Datomic rocks
    • some people using other DBs

    View Slide

  55. Project status
    • very close to beta
    • 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
    • your system should support
    these properties

    View Slide

  57. – Rich Hickey
    “Programmers know the benefits of everything
    and the tradeoffs of nothing”

    View Slide

  58. github.com/anmonteiro/craftconf-demo/

    View Slide

  59. Questions?

    View Slide