Http Subscriptions

Hi Everyone,

Is there any guidance on subscribing to streams or all events using the http interface? Is it just a matter of polling, and if so, is there an easy/obvious way to see which items in the feed are new?

My goal is to be able to subscribe to events/streams through node.js without having to write any (or not much, at least) code. I ultimately would like to work on a nodejs client, but it will waste too much time.

Thanks,

Brian

You can use long polling for it:

https://github.com/EventStore/EventStore/wiki/HTTP-LongPoll-Header

You should only receive events on the atom feed once if you keep following the links.

Cheers,

James

I think this will help

https://github.com/eventstore/eventstore/wiki/Getting-Started-HTTP

There is code in C# for doing exactly this.

Cheers,

Greg

Thanks, I will look into it and come back with any questions. :slight_smile:

Hi All,

Back again. The links above helped and I now have replaying a full stream working, but now I have another couple of issues I can’t figure out.

First, how do I use the atom interface to do a SubscribeToAll equivalent. I’d like to be able to specify a starting position, page size, and ideally I would not have to filter out the system events. Is this possible?

I’d also like to get all events from a stream after a certain event number (or position, I suppose). I can do this by constructing the URI myself, but since the feed is ReSTful, I shouldn’t be doing that. I’m assuming if there’s an answer to the above, there will be an answer to this one too, but I wanted to specify just in case.

Thanks,

Brian

All is /streams/$all (its an atom feed and works just like any other). It will however give system events … As of now bookmarking would be the only way to read from X in a stream we can look at some other mechanism.

It’s better to make an ‘almost-all’ projection that excludes system events. This way you also only have to deal with an integer position instead of CommitPosition/PreparePosition.

Thanks, Greg.

It sounds like the C# client api is a bit more robust at this point, then? For the time being, I think I’ll just wrap the C# api in a nodejs/edge module just so I can get myself going and then revisit in the next month or so.

My ultimate goal is to get a native node.js client project written with both tcp and http transports, but I don’t have the bandwidth right now.

Thanks again,

Brian

I wouldn’t say it’s any more robust - you’ll have to deal with system events in a SubscribeToAll as well, and also have to deal with the logical transaction file positions rather than an integer. As Joao says, your best bet might be a projection writing links
to the events you’re interested in and reading the atom feed for that instead.

James

Someone started native node.js but it needs some love.

Atom has a very different set of usecases than tcp. For a node.js app you would almost always prefer to use tcp over atom (likely < 5 connections all on local area network with no intrmediaries)

@james ahh… for some reason I thought SubscribeToAll had changed behavior at some point. Whoops.

@greg I had seen that, but it’s so old I figured I’d just use it as a reference and start from scratch. You’ve helped give me some things to think about here. I’ll have to digest this and come back. :slight_smile:

I appreciate the feedback.

While we are on the topic, I have been looking at the example chat app, and the javascript being used in that app to implement the chat.

Is it useful using the javascipt in that example in production? Or am I better off producing my own library to interface with the server?

Thank you.

Matt.

The js in the app is reasonably ok there are a few things you might change such as longpolling and security depending on your situation (and making it cleaner overall) it is not however that far off from something reasonable (*note the call backs in the current ui + js can be a bit weird at times).

Hi!

I’m also working with the Http api and love it so far. There is one thing where I think it could improve and that is the way how checkpoints work.

What I’m thinking about is, that ES uses prepare and commit position internally, which as I understood it, is a unique identifier for all events in the event store, right?

So I think it would be great if I could somehow get this positions for a specific event to store it with my checkpointer and then later jump to the same logical position in the same OR a different stream.

Some system streams like $all already have these positions in their atom feed url, but when I try to use them in another stream I get a 404:

Works:

http://127.0.0.1:2113/streams/$all/000000000000AB3E000000000000AB3E/forward/20

Doesn’t work:

http://127.0.0.1:2113/streams/$et-prototype.PerformanceTestMessage/000000000000AB3E000000000000AB3E/forward/20

Any ideas, or plans to support this in the future?

Thanks!

Sebastian

Sorry, for the second url I get a “400 ‘000000000000AB3E000000000000AB3E’ is not valid event number”, not a 404.

This is because streams are using numbers not positions. While this would be pretty easy to provide it would also break huge things in the http api. The largest is that you are not supposed to bookmark uris the way you are doing there but use the rel links to navigate through the streams.

Correct. Currently I am following the rel links and to keep track of my progress I bookmark the “previous” link. I was just thinking out-of-the-box, because I think there are situations where an ES-wide position would be really helpful.

For example:

  • I have a subscriber that handles only one event type “EventType1”.

  • So I tell that subscriber to subscribe to the event-specific stream at http://127.0.0.1:2113/streams/$et-EventType1, as this is the optimal event-source.

  • The subscriber handles a couple of thousand events and always bookmarks the current position in the stream (like http://127.0.0.1:2113/streams/$et-EventType1/38430/forward/20)

  • Now I start to publish a new event type “EventType2” and I want the subscriber to also handle it.

  • As we have now two event types the subscriber needs to listen to a “bigger” stream like http://127.0.0.1:2113/streams/$all.

  • Before I can start to read events from $all I need to find the correct position where reading should start, so that I don’t handle older “EventType1” events a second time.

  • Right now the only solution is to get the Url of the last handled event in the old stream and iterate over the new stream until you find the correct position.

  • This is doable but can take a long time in a large stream

So if there was an easier/faster way to solve this problem it would be very much appreciated, but I totally understand if this out of scope to you.

Greets,

Sebastian

What kind of subscriber is it? Are the side effects (processing a credit card) or none (like a projection)? You can make a stream that’s like $all but has no system events. When your subscriber handles an event he persists that event’s position afterwards.

That’s exactly what I’m doing right now :slight_smile: We have $all (not used), a system wide and an application wide stream for our subscribers. We achieved this with JavaScript projections. For subscribers I included a strategy, that when he is only interested in one specific event type, he will listen to the $et- stream, because that would be the most optimal stream for him. Sadly this strategy has the downside, that when we later decide to subscribe to a second event type, we will have to deal with the migration of the checkpoint to the new stream. I guess there currently is no easy way to do this, so I have two options.

  1. Don’t do the optimization of using event type stream

  2. implement a “checkpoint migrator” that knows how to find the right position in a different stream (by iteration).

Thanks everyone!

Sebastian

Greg,

Sorry for bringing this old thread back to life, but I am having trouble comprehending this:

“For a node.js app you would almost always prefer to use tcp over atom”

What makes TCP better choice than Atom when using Node?

Thank you,

-Leo