[id='hotrod-data-format_{context}']
= Hot Rod DataFormat API
Read and write operations on remote caches via the Hot Rod endpoint use the client marshaller by default.
Hot Rod provides a `DataFormat` API for Java clients that you can use to perform cache operations with different media type encodings and/or marshallers.

.Different marshallers for key and values

You can override marshallers for keys and values at run time.

For example, to bypass all serialization in the Hot Rod client and read the `byte[]` array stored in the remote cache:

[source,java]
----
// Existing RemoteCache instance
RemoteCache<String, Pojo> remoteCache = ...

// IdentityMarshaller is a no-op marshaller
DataFormat rawKeyAndValues =
DataFormat.builder()
          .keyMarshaller(IdentityMarshaller.INSTANCE)
          .valueMarshaller(IdentityMarshaller.INSTANCE)
          .build();

// Creates a new instance of RemoteCache with the supplied DataFormat
RemoteCache<byte[], byte[]> rawResultsCache =
remoteCache.withDataFormat(rawKeyAndValues);
----

[IMPORTANT]
====
Using different marshallers and data formats for keys with `keyMarshaller()` and `keyType()` methods can interfere with client intelligence routing mechanisms, causing extra network hops within the {brandname} cluster.
If performance is critical, you should use the same encoding for keys on the client and on the server.
====

.Reading data in different encodings

Request and send data in different encodings specified by a `org.infinispan.commons.dataconversion.MediaType` as follows:

[source,java]
----
// Existing remote cache using ProtostreamMarshaller
RemoteCache<String, Pojo> protobufCache = ...

// Request values returned as JSON
// Use the UTF8StringMarshaller to convert UTF-8 to String
DataFormat jsonString =
DataFormat.builder()
          .valueType(MediaType.APPLICATION_JSON)
          .valueMarshaller(new UTF8StringMarshaller())
          .build();
RemoteCache<byte[], byte[]> rawResultsCache =
protobufCache.withDataFormat(jsonString);
----

.Using custom value marshallers

You can use custom marshallers for values, as in the following example that returns values as `org.codehaus.jackson.JsonNode` objects.

In this example, {brandname} Server handles the data conversion and throws an exception if it does not support the specified media type.

[source,java]
----
DataFormat jsonNode =
DataFormat.builder()
          .valueType(MediaType.APPLICATION_JSON)
          .valueMarshaller(new CustomJacksonMarshaller()
          .build();

RemoteCache<String, JsonNode> jsonNodeCache =
remoteCache.withDataFormat(jsonNode);
----

.Returning values as XML

The following code snippet returns values as XML:

[source,java]
----
Object xmlValue = remoteCache
      .withDataFormat(DataFormat.builder()
      .valueType(MediaType.APPLICATION_XML)
      .valueMarshaller(new UTF8StringMarshaller())
      .build())
      .get(key);
----

For example, the preceding `get(key)` call returns values such as:

[source,xml]
----
<?xml version="1.0" ?><string>Hello!</string>
----

.Reference

link:{javadocroot}/org/infinispan/client/hotrod/DataFormat.html[org.infinispan.client.hotrod.DataFormat]
