Post data

edit

The low level client allows you to post a string or byte[] array directly. On top of this, if you pass a collection of string or object they will be serialized using Elasticsearch’s special bulk/multi format.

Implicit Conversion

edit

Even though the argument for PostData on the low level client takes a PostData<object>, You can rely on implicit conversion to abstract the notion of PostData completely. You can implicitly convert from the following types

  • A string
  • A collection of string
  • An object
  • A collection of object
  • A byte[] array

Let’s demonstrate each with some assertive examples

PostData<object> fromString = @string;
PostData<object> fromByteArray = bytes;
PostData<object> fromListOfString = collectionOfStrings;
PostData<object> fromListOfObject = collectionOfObjects;
PostData<object> fromObject = @object;

fromByteArray.WrittenBytes.Should().BeSameAs(bytes); 

WrittenBytes will always be set if it originated from byte[]

The Type property is representative of the original type from which post data is constructed

fromString.Type.Should().Be(PostType.LiteralString);
fromByteArray.Type.Should().Be(PostType.ByteArray);
fromListOfString.Type.Should().Be(PostType.EnumerableOfString);
fromListOfObject.Type.Should().Be(PostType.EnumerableOfObject);
fromObject.Type.Should().Be(PostType.Serializable);

and passing a PostData<object> instance to a method that accepts PostData<object> as an argument does not wrap it again

fromString = MethodThatAcceptsPostData(fromString);
fromByteArray = MethodThatAcceptsPostData(fromByteArray);
fromListOfString = MethodThatAcceptsPostData(fromListOfString);
fromListOfObject = MethodThatAcceptsPostData(fromListOfObject);
fromObject = MethodThatAcceptsPostData(fromObject);

fromString.Type.Should().Be(PostType.LiteralString);
fromByteArray.Type.Should().Be(PostType.ByteArray);
fromListOfString.Type.Should().Be(PostType.EnumerableOfString);
fromListOfObject.Type.Should().Be(PostType.EnumerableOfObject);
fromObject.Type.Should().Be(PostType.Serializable);

Each of the implicitly converted types behaves slightly differently.

For string, the UTF-8 bytes are sent in the request and the WrittenBytes property is assigned the bytes

await Post(() => @string, writes: Utf8Bytes(@string), writtenBytesIsSet: true, settings: settings);

Similarly, for byte[], the bytes are sent verbatim and the WrittenBytes property is assigned the bytes

await Post(() => bytes, writes: bytes, writtenBytesIsSet: true, settings: settings);

When passing a collection of string, the client assumes that it’s a collection of valid serialized json, so joins each with newline feeds, ensuring there is a trailing linefeed. As with string and byte[], the WrittenBytes property is assigned the UTF-8 bytes of the collection of strings

await Post(() => collectionOfStrings, writes: utf8BytesOfListOfStrings, writtenBytesIsSet: true, settings: settings);

When passing a collection of object, the client assumes that it’s a collection of objects that needs to be serialized individually to json and joined with newline feeds. As with the collection of strings, the client ensures that there is a trailing linefeed.

await Post(() => collectionOfObjects, writes: utf8BytesOfCollectionOfObjects, writtenBytesIsSet: false, settings: settings);

In all other cases, Post data is serialized as is and WrittenBytes is not assigned

await Post(() => @object, writes: utf8ObjectBytes, writtenBytesIsSet: false, settings: settings);

Forcing WrittenBytes to be set

edit

If you want to maintain a copy of the request that went out, you can set DisableDirectStreaming on ConnectionConfiguration. In doing so, the serialized bytes are first written to a private MemoryStream so that the client can get hold of the serialized bytes

settings = new ConnectionConfiguration().DisableDirectStreaming();

await Post(() => collectionOfObjects, writes: utf8BytesOfCollectionOfObjects, writtenBytesIsSet: true, settings: settings);

This behavior can also be observed when serializing a simple object using DisableDirectStreaming enabled

await Post(() => @object, writes: utf8ObjectBytes, writtenBytesIsSet: true, settings: settings);