mattkrick / cashay

:moneybag: Relay for the rest of us :moneybag:
MIT License
453 stars 28 forks source link

RFC: Upgrading/Downgrading transports #81

Closed mattkrick closed 8 years ago

mattkrick commented 8 years ago

what's the most eloquent way to upgrade the Cashay's transport to websockets when we establish a socket connection?

Option A: call cashay.create({transport: new SocketTransport(sendToServer)}) on upgrade and cashay.create({transport: new HTTPTransport(authToken)}) on downgrade. The awkward part about this is that we'll need access to the redux state to grab the authToken when we downgrade. I can add the store to redux-socket-cluster easily enough, though.

Option B: Store each transport separately in Cashay: cashay.create({httpTransport: x, socketTransport: y, serverTransport: z}). Then, always try to use the best (priority is http, socket, server). Then, cashay.query and cashay.mutation both take an optional argument {setTransport: ENUM('http', 'socket', 'server')} for overrides.

@jordanh would love your thoughts on this. 89142cfde3c2864520dfda7d5a805cb3

jordanh commented 8 years ago

I like, and prefer, the second option. If you have multiple ways of communicating at your disposal and one fails – allow the user to use it. Plus, I think it's just simpler.

mattkrick commented 8 years ago

yeah, i can dig it. BREAKING API HERE WE COME!

jordanh commented 8 years ago

That's (paradoxically) a sign of maturity. (Haa!) ​

mattkrick commented 8 years ago

While writing this, I realized with a little massaging I could combine SocketTransport and ServerSideTransport, and that HTTPTransport is just an extension of that generic Transport.

Realistically, I think it makes sense that only 2 global transports ever be present at 1 time (have an HTTP fallback & 1 for sockets). If you need another transport, there's always the local override. Maybe that'll come in handy if/when Cashay supports multiple backends, but we'd have to handle multiple schemas before we cross that bridge (or joining schemas across backends, which would be really fun).

So, that leaves us with an API like: httpTransport, priorityTransport. If a certain query wants to use the httpTransport, that's fine, but you gotta do something like cashay.query(fooString, {transport: cashay.httpTransport}).

Under the hood, we'll have a getTransport that prioritizes like:

  1. query-specific transport
  2. priorityTransport
  3. httpTransport