How to use json object in header and stringfy it without happens substring to it?

when i use json object as aheader and try to stringfy it.
the object will not be full object
for example

{"uniqueId":"3A1EFD82-CAA5-456E-A795-6BF14C1FD47B","height":844,"deviceBrand":"Apple","lang":"en","carrier":"Orange","timestamp":1434785,"osVersion":"15.1.0","platform":"iOS"}
it will be 
"{"uniqueId":"3A1EFD82-CAA5-456E-A795-6BF14C1FD47B"

i need stringfied object to send it to service callout


appreciate your support 

 

Solved Solved
1 1 5,725
1 ACCEPTED SOLUTION

when i use json object as aheader and try to stringfy it.
the object will not be full object

It may be that there is no problem at all. Maybe you are just seeing sometihng in the Trace output, and interpreting it as a problem, but it is not a problem.

There is a complexity that you should be aware of within Apigee when dealing with headers. According to the documentation, if you access a context variable like request.header.HEADERNAME, then you get the value of the HTTP header named HEADERNAME that is present in the request message. That seems easy enough.

But the HTTP specification allows duplicated headers. Multiple distinct header values with the same name might be present. For example there can be multiple Cookie headers in a request each with different values; likewise there may be multiple Set-Cookie headers in a response, each with different values. Another commonly-seen duplicated header is X-Forwarded-For. In general, there may be duplicated headers in an HTTP message. Also, the HTTP specification allows handlers of HTTP messages to consolidate multiple headers into one, with the values separated by comma. So for example, the following two are equivalent semantically, according to the HTTP specification.

 

X-custom-header: 123
X-custom-header: abc
X-custom-header: 123, abc

 

To handle that case, the Apigee gateway runtime helpfully parses header values that contain commas, as if they were multiple distinct values. This is the actual meaning of the header, according to the HTTP spec. In other words, this header line in a request:

 

X-custom-header: { "foo" : "bar", "baz" : "bah" }

 

...may appear to be JSON to us, but HTTP applications are instructed to treat that as two distinct values. Normalized, it would look like this:

 

X-custom-header: { "foo" : "bar"
X-custom-header: "baz" : "bah" }

 

So when you refer to a variable like request.header.x-custom-header , you will see only the text before the first comma. By default Apigee gives you the first value of a multi valued header.

If you want to get the full header, you need to refer to it differently. Use the form request.header.HEADERNAME.values.string. This is documented here.

I think you are looking in the Trace window and seeing only the first part of the header, and interpreting that as an error. But I think Apigee is transmitting all of the JSON data to the upstream system. Apigee may or may not send all of this data in multiple header lines. It MAY (according to the spec) send the data like this:

 

X-custom-header: { "foo" : "bar"
X-custom-header: "baz" : "bah" }

 

(and more lines if there are more properties in the JSON.) But I believe it does not. In that case that Apigee does send multiple header lines, it would be the responsibility of the receiving application to consolidate all the values into one JSON object. (Also in this case, I believe the ordering of the multiple header values is guaranteed, but I am not certain. If there is no strict ordering, in other words if the HTTP Specification does not require that the distinct multiple values must be kept in a particular order, then .... the re-assembled segments may not result in a valid JSON representation. Probably the ordering will be retained, but I am not certain. It's easy to test.)

If you want to avoid any issue in that regard you could encode the JSON (eg base64), which would convert commas to something else. That would mean only a single HTTP header. The receiving end would have to base64 decode that value.

You may not need to do this, though. It may be the case that the behavior you are observing and reporting is an artifact only of the Trace session in Apigee, and sending JSON in a single header will work fine for your upstream system. Please test it and see!

I just tested this myself; in the upstream system, I can retrieve the full JSON in the header.

View solution in original post

1 REPLY 1

when i use json object as aheader and try to stringfy it.
the object will not be full object

It may be that there is no problem at all. Maybe you are just seeing sometihng in the Trace output, and interpreting it as a problem, but it is not a problem.

There is a complexity that you should be aware of within Apigee when dealing with headers. According to the documentation, if you access a context variable like request.header.HEADERNAME, then you get the value of the HTTP header named HEADERNAME that is present in the request message. That seems easy enough.

But the HTTP specification allows duplicated headers. Multiple distinct header values with the same name might be present. For example there can be multiple Cookie headers in a request each with different values; likewise there may be multiple Set-Cookie headers in a response, each with different values. Another commonly-seen duplicated header is X-Forwarded-For. In general, there may be duplicated headers in an HTTP message. Also, the HTTP specification allows handlers of HTTP messages to consolidate multiple headers into one, with the values separated by comma. So for example, the following two are equivalent semantically, according to the HTTP specification.

 

X-custom-header: 123
X-custom-header: abc
X-custom-header: 123, abc

 

To handle that case, the Apigee gateway runtime helpfully parses header values that contain commas, as if they were multiple distinct values. This is the actual meaning of the header, according to the HTTP spec. In other words, this header line in a request:

 

X-custom-header: { "foo" : "bar", "baz" : "bah" }

 

...may appear to be JSON to us, but HTTP applications are instructed to treat that as two distinct values. Normalized, it would look like this:

 

X-custom-header: { "foo" : "bar"
X-custom-header: "baz" : "bah" }

 

So when you refer to a variable like request.header.x-custom-header , you will see only the text before the first comma. By default Apigee gives you the first value of a multi valued header.

If you want to get the full header, you need to refer to it differently. Use the form request.header.HEADERNAME.values.string. This is documented here.

I think you are looking in the Trace window and seeing only the first part of the header, and interpreting that as an error. But I think Apigee is transmitting all of the JSON data to the upstream system. Apigee may or may not send all of this data in multiple header lines. It MAY (according to the spec) send the data like this:

 

X-custom-header: { "foo" : "bar"
X-custom-header: "baz" : "bah" }

 

(and more lines if there are more properties in the JSON.) But I believe it does not. In that case that Apigee does send multiple header lines, it would be the responsibility of the receiving application to consolidate all the values into one JSON object. (Also in this case, I believe the ordering of the multiple header values is guaranteed, but I am not certain. If there is no strict ordering, in other words if the HTTP Specification does not require that the distinct multiple values must be kept in a particular order, then .... the re-assembled segments may not result in a valid JSON representation. Probably the ordering will be retained, but I am not certain. It's easy to test.)

If you want to avoid any issue in that regard you could encode the JSON (eg base64), which would convert commas to something else. That would mean only a single HTTP header. The receiving end would have to base64 decode that value.

You may not need to do this, though. It may be the case that the behavior you are observing and reporting is an artifact only of the Trace session in Apigee, and sending JSON in a single header will work fine for your upstream system. Please test it and see!

I just tested this myself; in the upstream system, I can retrieve the full JSON in the header.