PHP GetEventStore Http Client

Hi,

I just wanted to share an http client for the event store written in PHP.

https://github.com/rayrutjes/php-geteventstore-client

Actually, the client has the following interface: https://github.com/rayrutjes/php-geteventstore-client/blob/master/src/ClientInterface.php

Feel free to give me some feedback.

Cheers!

Very cool.

Not sure if you have seen it but this could pretty trivially support
competing consumers as well (slightly modified atom feed)

You are right, I am gonna dig into the competing consumers to provide a more complete implementation.

It shouldn't be much work really (its just a few added rel links
(ack/nak/ack group/etc)

I am working on it.

Could you please correct my affirmations regarding the nack request actions, and tell me if some actions may not make sense in an http client context:

  • Park: Removes the message from the queue and adds it to the park queue whatever the maxRetryCounter was set at?

  • Retry: Increases the attemptedCounter so that the server can park it automatically if the maxRetryCounter threshold is reached?

  • Skip: Leave the message untouched, and the next pooling will re-send it?

  • Stop: Drops open connections to the subscription group? Does this make sense in an http client context?

Stop does not make sense.

Ok thx, I have just clarified the others in my head right now.

The only other rel link is at the top "ack all" which lowers message traffic.

The other thing you will likely want to do is to use the description
document (/streams/foo no accept or there is a
vnd.eventstore.mediatype as well) as it lists the subscriptions
available + rel links for a given stream (it also links to atom feeds
etc btw)

See http://docs.geteventstore.com/http-api/3.5.0/description-document/

Ok, what about liveBufferSize & bufferSize, what does these really stand for?

they dont matter over http most of the time (basically its talking
about internal buffers of the subscription which is very important for
performance over tcp but much less so over http)

Ok that’s what I thought, I’ll leave those out for now. Thx for the quick replies.

Here is one last not competed consumers related.
Is there a way to embed metadata in the feed, actually even when using embed body, I do not get the metadata back. Is this on purpose?

I am actually relying only on rich feeds which allows me to considerably reduce the number of requests, but I am missing metadata, which makes the rich embed feature useless as I still need to request metadata for each event.

https://github.com/EventStore/EventStore/blob/release-v3.6.0/src/EventStore.Core/Services/Transport/Http/Convert.cs#L268

=body should include metadata

Here is a test showing it...
greg@clown:~/Downloads$ cat myevent.txt
[
  {
    "eventId": "fbf4a1a1-b4a3-4dfe-a01f-ec52c34e16e4",
    "eventType": "event-type",
    "metadata" : {"test" : "metadata" },
    "data": { "a": "1" }
  }
]

greg@clown:~/Downloads$ curl -i [email protected]
"http://127.0.0.1:2113/streams/newstream" -H
"Content-Type:application/vnd.eventstore.events+json"
HTTP/1.1 201 Created
Access-Control-Allow-Methods: POST, DELETE, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-Requested-With,
X-Forwarded-Host, X-PINGOTHER, Authorization, ES-LongPoll,
ES-ExpectedVersion, ES-EventId, ES-EventType, ES-RequiresMaster,
ES-HardDelete, ES-ResolveLinkTo, ES-ExpectedVersion
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location, ES-Position
Location: http://127.0.0.1:2113/streams/newstream/0
Content-Type: text/plain; charset=utf-8
Server: Mono-HTTPAPI/1.0
Content-Length: 0
Keep-Alive: timeout=15,max=100

greg@clown:~/Downloads$ curl -i
http://127.0.0.1:2113/streams/newstream?embed=body -H "Accept:
application/json"
HTTP/1.1 200 OK
Access-Control-Allow-Methods: POST, DELETE, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-Requested-With,
X-Forwarded-Host, X-PINGOTHER, Authorization, ES-LongPoll,
ES-ExpectedVersion, ES-EventId, ES-EventType, ES-RequiresMaster,
ES-HardDelete, ES-ResolveLinkTo, ES-ExpectedVersion
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location, ES-Position
Cache-Control: max-age=0, no-cache, must-revalidate
Vary: Accept
ETag: "0;1391431453"
Content-Type: application/json; charset=utf-8
Server: Mono-HTTPAPI/1.0
Content-Length: 1647
Keep-Alive: timeout=15,max=100

{
  "title": "Event stream 'newstream'",
  "id": "http://127.0.0.1:2113/streams/newstream",
  "updated": "2016-03-03T19:08:35.416529Z",
  "streamId": "newstream",
  "author": {
    "name": "EventStore"
  },
  "headOfStream": true,
  "selfUrl": "http://127.0.0.1:2113/streams/newstream",
  "eTag": "0;-2060438500",
  "links": [
    {
      "uri": "http://127.0.0.1:2113/streams/newstream",
      "relation": "self"
    },
    {
      "uri": "http://127.0.0.1:2113/streams/newstream/head/backward/20",
      "relation": "first"
    },
    {
      "uri": "http://127.0.0.1:2113/streams/newstream/1/forward/20",
      "relation": "previous"
    },
    {
      "uri": "http://127.0.0.1:2113/streams/newstream/metadata",
      "relation": "metadata"
    }
  ],
  "entries": [
    {
      "eventId": "fbf4a1a1-b4a3-4dfe-a01f-ec52c34e16e4",
      "eventType": "event-type",
      "eventNumber": 0,
      "data": "{\n \"a\": \"1\"\n}",
      "metaData": "{\n \"test\": \"metadata\"\n}",
      "streamId": "newstream",
      "isJson": true,
      "isMetaData": true,
      "isLinkMetaData": false,
      "positionEventNumber": 0,
      "positionStreamId": "newstream",
      "title": "0@newstream",
      "id": "http://127.0.0.1:2113/streams/newstream/0",
      "updated": "2016-03-03T19:08:35.416529Z",
      "author": {
        "name": "EventStore"
      },
      "summary": "event-type",
      "links": [
        {
          "uri": "http://127.0.0.1:2113/streams/newstream/0",
          "relation": "edit"
        },
        {
          "uri": "http://127.0.0.1:2113/streams/newstream/0",
          "relation": "alternate"
        }
      ]
    }
  ]
}

You are right, my confusion came from the fact that you push the event with “metadata” and you get it back as keyed “metaData”.
Can you confirm there is no way of adding metadata when pushing a single event with media type application/json?

There is not (there is no way to specify it)

How does namedConsumerStrategy relate to preferRoundRobin? What is the underlying behaviour?

Originally there were only two strategies (preferRoundRobin and
preferSingle) later a mechanism was built in for custom strategies
(named) to be allowed to be used if people wanted to extend the logic
of how dispatching worked with custom mechanisms

There seems to be an issue with MaxSubscriberCount which can not be customized when creating a persistentSubscription nor when updating one.
This can also be observed in the UI.

The value isn't being accepted?