1[[serializers]]
2== Serializers
3
4The client has three serializers available.  You will most likely never need
5to change the serializer, unless you have special requirements or are
6implementing a new protocol.
7
8The job of the serializer is to encode the outgoing request body and decode
9the incoming response body.  In 99% of cases, this is a simple conversion
10to/from JSON.
11
12The default serializer is the `SmartSerializer`
13
14=== SmartSerializer
15==== Serialize()
16The `SmartSerializer` inspects the data to be encoded.  If the request body
17is provided as a string, it is passed directly to Elasticsearch as a string.
18This allows users to provide raw JSON, or raw strings for certain endpoints that
19dont have structure (such as the Analyze endpoint).
20
21If the data is an array, it is converted to json.  If the data provided was an
22empty array, the serializer manually converts the JSON from an empty array (`[]`)
23to an empty object (`{}`) so that it is valid JSON for Elasticsearch request
24bodies.
25
26==== Deserialize()
27When decoding the response body, the `SmartSerializer` introspects the
28`content_type` headers to determine the appropriate encoding.  If the data is
29encoded as JSON, it is decoded into an array using `json_decode`.  Otherwise,
30it is returned as a string.
31
32This functionality is required to cooperate with endpoints such as the `Cat`
33endpoints, which return tabular text instead of JSON.
34
35==== Selecting the SmartSerializer
36
37The SmartSerializer is selected by default, but if you wish to manually configure it for explicitness, you can
38do so by using the `setSerializer()` method on the ClientBuilder object:
39
40[source,php]
41----
42$client = ClientBuilder::create()
43            ->setSerializer('\Elasticsearch\Serializers\SmartSerializer');
44            ->build();
45----
46
47Note that the serializer is configured by specifying a namespace path to the serializer.
48
49=== ArrayToJSONSerializer
50==== Serialize()
51The `ArrayToJSONSerializer` inspects the data to be encoded.  If the request body
52is provided as a string, it is passed directly to Elasticsearch as a string.
53This allows users to provide raw JSON, or raw strings for certain endpoints that
54dont have structure (such as the Analyze endpoint).
55
56If the data is an array, it is converted to json.  If the data provided was an
57empty array, the serializer manually converts the JSON from an empty array (`[]`)
58to an empty object (`{}`) so that it is valid JSON for Elasticsearch request
59bodies.
60
61==== Deserialize()
62When decoding the response body, everything is decoded to JSON from JSON.  If
63the data is not valid JSON, `null` will be returned.
64
65==== Selecting the ArrayToJSONSerializer
66
67You can select  `ArrayToJSONSerializer` by using the `setSerializer()` method on the ClientBuilder object:
68
69[source,php]
70----
71$client = ClientBuilder::create()
72            ->setSerializer('\Elasticsearch\Serializers\ArrayToJSONSerializer');
73            ->build();
74----
75
76Note that the serializer is configured by specifying a namespace path to the serializer.
77
78=== EverythingToJSONSerializer
79==== Serialize()
80The `EverythingToJSONSerializer` tries to convert everything to JSON.
81
82If the data provided was an empty array, the serializer manually converts the
83JSON from an empty array (`[]`) to an empty object (`{}`) so that it is valid
84JSON for Elasticsearch request bodies.
85
86If the data was not an array and/or not convertible to JSON, the method returns
87`null`.
88
89==== Deserialize()
90When decoding the response body, everything is decoded to JSON from JSON.  If
91the data is not valid JSON, `null` will be returned.
92
93==== Selecting the EverythingToJSONSerializer
94
95You can select  `EverythingToJSONSerializer` by using the `setSerializer()` method on the ClientBuilder object:
96
97[source,php]
98----
99$client = ClientBuilder::create()
100            ->setSerializer('\Elasticsearch\Serializers\EverythingToJSONSerializer');
101            ->build();
102----
103
104Note that the serializer is configured by specifying a namespace path to the serializer.
105
106=== Implementing your own Serializer
107If you want to use your own custom serializer, you need to implement the `SerializerInterface` interface.  Please
108keep in mind that the client uses a single Serializer object for all endpoints and all connections.
109
110
111[source,php]
112----
113class MyCustomSerializer implements SerializerInterface
114{
115
116    /**
117     * Serialize request body
118     *
119     * @param string|array $data Request body
120     *
121     * @return string
122     */
123    public function serialize($data)
124    {
125        // code here
126    }
127
128    /**
129     * Deserialize response body
130     *
131     * @param string $data Response body
132     * @param array  $headers Response Headers
133     *
134     * @return array|string
135     */
136    public function deserialize($data, $headers)
137    {
138        // code here
139    }
140}
141----
142{zwsp} +
143
144To then use your custom serializer, you can specify the namespace path in the `setSerializer()` method of the ClientBuilder
145object:
146
147[source,php]
148----
149$client = ClientBuilder::create()
150            ->setSerializer('\MyProject\Serializers\MyCustomSerializer');
151            ->build();
152----
153
154Alternatively, if your serializer has a constructor or further initialization that should occur before given to the
155client, you can instantiate an object and provide that instead:
156
157[source,php]
158----
159$mySerializer = new MyCustomSerializer($a, $b, $c);
160$mySerializer->setFoo("bar");
161
162$client = ClientBuilder::create()
163            ->setSerializer($mySerializer);
164            ->build();
165----
166
167
168