prooph / event-store-http-api

Prooph EventStore HTTP API
http://getprooph.org/
BSD 3-Clause "New" or "Revised" License
18 stars 3 forks source link

RFC event source JavaScript API #32

Open basz opened 6 years ago

basz commented 6 years ago

Bas Kamer @basz Jan 19 23:36 Anyone worked with the event source JavaScript API Sounds like a really simple alternative to webstomp

Alexander Miertsch @codeliner Jan 20 11:07 @basz indeed! But I've only planed to use it. You need a backend that manages the event source clients. So far rabbit + webstomp was easier, but there is a SSE server available built on top of reactPHP. This combined with a projection would be a nice alternative compared to rabbit + webstomp

Bas Kamer @bweston92 z Jan 20 15:57 I would say its more efficiënt compared to our https://github.com/prooph/event-store-http-api package. But yes you would need something that makes sure a client only gets relevant events. Then you would be able to reconsitute the Same AR on the client. Http://bla.com/stream-of-AR-events/uuid ? This works with a ‘php -S 0.0.0.0:8080’ https://github.com/html5rocks/www.html5rocks.com/tree/master/content/tutorials/eventsource/basics/static/demo I like it

Bas Kamer @basz Jan 20 16:02 No extra Apache mods, didnt test with nigx but i think it should work. All browsers (edge with a polyfill)

You need a backend that manages the event source clients.

I'm interested to hear what would be needed to manage event sourced clients. http://bla.com/stream-of-AR-events/uuid would work if the client already knows the uuid of the aggregate. Also I'm wondering if this repo would be the place to add such a feature...

prolic commented 6 years ago

@basz Interessting idea. I have to play a little with some options we have, let me get back to this soon.

codeliner commented 6 years ago

@basz I'm thinking about client side ARs for some time now and yes it is an interesting idea. Question is, what do you want to do with the AR in the client? I mean if more than one client has the same AR in memory and work with it you run into concurrency issues very quickly. Same for read models: It is nice to forward events to the client for real time updates BUT keeping a read model in the browsers local storage is maybe not that easy.

Let's say you populate a clientside read model and then the user closes the browser and clears local storage. A client side projection would need to rebuild the entire read model again before it can start working. Ideally it would be that way: JS application is opened and bootstraps itself. The app fetches inital state from a read model on the server and then connects to the SSE backend for real time updates during the user session. No further backend GET requests needed other then the SSE connection

This would be a very interesting setup BUT you would need to keep projection logic in two places and this only makes sense when using Node.js in the backend (maybe only for projections) and use the same projection code in the client.

codeliner commented 6 years ago

Security is another thing to consider: important business rules should be enforced in the domain model on a server and not in an AR living in memory on a users laptop

codeliner commented 6 years ago

Here is a PHP Lib for SSE with a short readme describing how it works. Clean and simple: https://github.com/igorw/EventSource

basz commented 6 years ago

Security is another thing to consider: important business rules should be enforced in the domain model on a server and not in an AR living in memory on a users laptop

I image commands to the server will result in events if all is well. These events are used to update an client side (read) model not an internal Aggregate Root. But even if they would UI business rules may exists.

BUT you would need to keep projection logic in two places In a one page applications you probably have that anyway

We for example, have an web socket open that transmits updates from doctrine changeset (fired of via the read model updates) into clients. The client is an ember app that simply uses it's Ember Data Store to upset models. It works for some of our models. Other models are simply fetched.

https://github.com/igorw/EventSource Indeed simple enough. The hard part would be logic to route the correct events to the corrects clients I guess. Which does touch on security issues.

codeliner commented 6 years ago

Just found some interesting details regarding events consumed by JS clients: https://community.risingstack.com/integrating-legacy-and-cqrs/#selectingatransportchannel

SSE seems to be a problem because you cannot send http headers so token auth cannot be used. JSON streaming is listed as the best alternative