reactive hypermedia apis

49
Reactive Hypermedia APIs Kevin Swiber CODEMASH V2.0.1.5

Upload: kevin-swiber

Post on 12-Jul-2015

482 views

Category:

Technology


1 download

TRANSCRIPT

  • Reactive Hypermedia APIs

    Kevin Swiber

    CODEMASH V2.0.1.5

  • I Like Buzzwords

  • Open source platform for the Internet of Things

    http://zettajs.org

  • APIs Suck

  • /data.cgi

  • /data.cgiN0

    0BIE

  • .NET Remoting

  • .NET RemotingBR

    OKEN

  • SOAP

  • SOAPSTU

    PID

  • RESTful?

  • RESTful?WR

    ONG

  • Hypermedia!

  • Hypermedia!NERD

  • Whats the problem?

  • The real world is complex

  • Feedback can be vicious

  • We fool ourselves into thinking all problems are the same

  • There is no silver bullet

  • Love the bomb

  • The 15th Standard

  • Back to Zetta (IoT)

  • Reaching the Edge

    DevicesDevicesDevices

    Zetta

    Zetta

    DevicesDevicesDevices

    Zetta

    ClientsClientsClients

    ClientsClientsClients Local Network

    Data Center

    Internet

    The only thing we control

  • Desired Architectural Properties

    Decoupling of implementations

    Independent evolution

    Scale

    Load balancing

    Centralize complexity, distribute simplicity

    Reduce latency

    Support event streams

  • Architectural Constraints Client-server, stateless, cacheable, layered

    system, uniform interface, etc.

    Wait, isnt that REST?

  • The hypest of all media!

    http://sirenspec.org

  • What about event streams?

  • How streams are done over HTTP today

    WebHooks

    Chunked Transfer-Encoding

    HTTP Pipelining

    Long Polling

    Server Sent Events

    XXXXX

  • Just upgrade

  • Connection info is in the action parameters or link URI

    mqtt://example.org:8863/topic

    stomp+ws://example.org/topic

    amqp://example.org/topic { href: ws://example.org, protocol: custom }

  • It works!

  • Model resources as finite state machines

    LED.prototype.init = function(config) { config .type('led') .state('off') .when('off', { allow: ['turn-on'] }) .when('on', { allow: ['turn-off'] }) .map('turn-on', this.turnOn) .map('turn-off', this.turnOff); };

  • Transitions are represented as affordances in the message.

    "actions": [ { "name": "turn-on", "method": "POST", "href": ..., "fields": [ { "name": "action", "type": "hidden", "value": "turn-on" } ] } ]

  • We need to consume an object stream.

    links: [ { title: pulse, rel: [http://rxapi.org/object-stream], href: ws://... } ]

  • We need to consume an object stream.

    wscat -c ws://... connected (press CTRL+C to quit) < {"topic":"heartbeat/1/pulse","timestamp":1411757412119,"data":61} < {"topic":"heartbeat/1/pulse","timestamp":1411757412620,"data":65} < {"topic":"heartbeat/1/pulse","timestamp":1411757413121,"data":69} < {"topic":"heartbeat/1/pulse","timestamp":1411757413622,"data":71} < {"topic":"heartbeat/1/pulse","timestamp":1411757414124,"data":66} < {"topic":"heartbeat/1/pulse","timestamp":1411757414626,"data":64} < {"topic":"heartbeat/1/pulse","timestamp":1411757415128,"data":68} < {"topic":"heartbeat/1/pulse","timestamp":1411757415629,"data":63} < {"topic":"heartbeat/1/pulse","timestamp":1411757416130,"data":65} < {"topic":"heartbeat/1/pulse","timestamp":1411757416631,"data":63}

  • Monitor resource events before taking action.

    links: [ { title: logs, rel: [ monitor, http://rxapi.org/object-stream ], href: ws://... } ]

  • Monitor resource events before taking action.

    wscat -c ws://... connected (press CTRL+C to quit) < {"topic":"led/2/logs","timestamp":1411809676901,"transition":"turn-on","input":[],"properties":{"id":"2","type":"led","name":null,"state":"on"}} < {"topic":"led/2/logs","timestamp":1411809677548,"transition":"turn-off","input":[],"properties":{"id":"2","type":"led","name":null,"state":"off"}} < {"topic":"led/2/logs","timestamp":1411809678483,"transition":"turn-on","input":[],"properties":{"id":"2","type":"led","name":null,"state":"on"}} < {"topic":"led/2/logs","timestamp":1411809679126,"transition":"turn-off","input":[],"properties":{"id":"2","type":"led","name":null,"state":"off"}}

  • We also need binary.links: [ { rel: [http://rxapi.org/binary-stream], href: ws://..., type: video/mpeg, } ]

  • We also need binary.

    wscat -c ws://... connected (press CTRL+C to quit) Q`rCEDDIp=`"3ss79:Yk}{` 5e\`>9%J[K89\z^> 8X Gp;WqXF h1{%O;7

  • We also need binary.

    wscat -c ws://... connected (press CTRL+C to quit)

  • Reactive Clientsvar siren = require('siren'); !siren() .load('http://zetta-cloud-2.herokuapp.com') .link('http://rels.zettajs.io/peer', 'Detroit') .entity(function(e) { return e.properties.type === 'sound'; }) .link('http://rels.zettajs.io/object-stream', 'level') .monitor() .subscribe(console.log);

  • Reactive Clientsvar zrx = require('zrx'); !zrx() .load('http://zetta-cloud-2.herokuapp.com') .server('Detroit') .device(function(d) { return d.type === 'sound'; }) .stream('level') .subscribe(console.log);

  • Going Forward

  • Solve the producer-consumer problem.

  • Reactive Stream Control Protocol

    Consumer controlled streams

    Runs over WebSockets

    Multiplex streams

    URI scheme definition

    Will be supported on HTTP/2 + WebSockets.

  • What can you do with streams?

    Monitoring values over time

    Distributed data processing

    Event sourcing

    Batches

  • // TODO:

    Extract reactive hypermedia framework from Zetta internals.

    Produce a clean specification and documentation.

    Experiment with multiple languages/platform implementations.

  • Hit me up! [email protected]

    https://twitter.com/kevinswiber

    https://linkedin.com/in/kevinswiber

    https://github.com/kevinswiber