Event Store logo

Menu
Show Table of Contents

Stream Metadata

Every stream in Event Store has metadata associated with it. Internally, the metadata includes information such as the ACL of the stream and the maximum count and age for the events in the stream. Client code can also put information into stream metadata for use with projections or through the client API.

A common use of this information is to store associated details about an event that is not part of the event. Examples of these are:

  • “which user wrote the event?”
  • “Which application server were they talking to?”
  • “From what IP address did the request come from?”

This type of information is not part of the actual event but is metadata associated with the event. Stream metadata is stored internally as JSON, and you can access it over the HTTP APIs.

Methods

Reading Stream Metadata

Task<StreamMetadataResult> GetStreamMetadataAsync(string stream, UserCredentials userCredentials = null)
Task<RawStreamMetadataResult> GetStreamMetadataAsRawBytesAsync(string stream, UserCredentials userCredentials = null)

Writing Stream Metadata

Task<WriteResult> SetStreamMetadataAsync(string stream, long expectedMetastreamVersion, StreamMetadata metadata, UserCredentials userCredentials = null)
Task<WriteResult> SetStreamMetadataAsync(string stream, long expectedMetastreamVersion, byte[] metadata, UserCredentials userCredentials = null)

Reading Stream Metadata

To read stream metadata over the .NET API you can use methods found on the EventStoreConnection. You can use the GetStreamMetadata methods in two ways. The first is to return a fluent interface over the stream metadata, and the second is to return you the raw JSON of the stream metadata.

Task<StreamMetadataResult> GetStreamMetadataAsync(string stream, UserCredentials userCredentials = null)

This will return a StreamMetadataResult. The fields on this result are:

Member Description
string Stream The name of the stream
bool IsStreamDeleted True is the stream is deleted, false otherwise.
int MetastreamVersion The version of the metastream format
StreamMetadata Metadata A StreamMetadata object representing the metadata JSON

You can then access the StreamMetadata via the StreamMetadata object. It contains typed fields for well known stream metadata entries.

Member Description
int? MaxAge The maximum age of events in the stream. Items older than this will be automatically removed.
int? MaxCount The maximum count of events in the stream. When you have more than count the oldest will be removed.
int? TruncateBefore When set says that items prior to event 'E' can be truncated and will be removed.
TimeSpan? CacheControl The head of a feed in the atom api is not cacheable. This allows you to specify a period of time you want it to be cacheable. Low numbers are best here (say 30-60 seconds) and introducing values here will introduce latency over the atom protocol if caching is occuring.
StreamAcl Acl The access control list for this stream.

If instead you want to work with raw JSON you can use the raw methods for stream metadata.

Task<RawStreamMetadataResult> GetStreamMetadataAsRawBytesAsync(string stream, UserCredentials userCredentials = null)

This will return a RawStreamMetadataResult. The fields on this result are:

Member Description
string Stream The name of the stream
bool IsStreamDeleted True is the stream is deleted, false otherwise.
int MetastreamVersion The version of the metastream (see Expected Version)
byte[] Metadata The raw data of the metadata JSON

If you have security enables, reading metadata may require that you pass credentials. By default it is only allowed for admins though you can change this via default ACLs. If you do not pass credentials and they are required you will receive an AccessedDeniedException.

Writing Metadata

You can write metadata in both a typed and a raw mechanism. When writing it is generally easier to use the typed mechanism. Both writing mechanisms support an expectedVersion which works the same as on any stream and you can use to control concurrency, read Expected Version for further details.

Task<WriteResult> SetStreamMetadataAsync(string stream, long expectedMetastreamVersion, StreamMetadata metadata, UserCredentials userCredentials = null)

The StreamMetadata passed here has a builder that you can access via the StreamMetadata.Create() method. The options available on the builder are:

Method Description
SetMaxCount(int count) Sets the maximum count of events in the stream.
SetMaxAge(TimeSpan age) Sets the maximum age of events in the stream.
SetTruncateBefore(int seq) Sets the event number from which previous events can be scavenged.<
SetCacheControl(TimeSpan cacheControl) The amount of time for which the stream head is cachable.
SetReadRoles(string[] roles) Sets the roles that are allowed to read the underlying stream.
SetWriteRoles(string[] roles) Sets the roles that are allowed to write to the underlying stream.
SetDeleteRoles(string[] roles) Sets the roles that are allowed to delete the underlying stream.
SetMetadataReadRoles(string[] roles) Sets the roles that are allowed to read the metadata stream.
SetMetadataWriteRoles(string[] roles) Sets the roles that are allowed to write the metadata stream. Be careful with this privilege as it gives all of the privileges for a stream as that use can assign themselves any other privilege.
SetCustomMetadata(string key, string value) The SetCustomMetadata method and overloads allow the setting of arbitrary custom fields into the stream metadata.

You can add user-specified metadata via the SetCustomMetadata overloads. Some examples of good uses of user-specified metadata are:

  • which adapter is responsible for populating a stream.
  • which projection caused a stream to be created.
  • a correlation ID of some business process.
Task<WriteResult> SetStreamMetadataAsync(string stream, long expectedMetastreamVersion, byte[] metadata, UserCredentials userCredentials = null)

This method will put the data that is in metadata as the stream metadata. Metadata in this case can be anything in a vector of bytes however the server only understands JSON. Read Access Control Lists for more information on the format in JSON for access control lists.

Writing metadata may require that you pass credentials if you have security enabled by default it is only allowed for admins though you can change this via default ACLs. If you do not pass credentials and they are required you will receive an AccessedDeniedException.