406 - error during API call when I add Accept : text/xml to request

406 - error during API call when I add Accept : text/xml to request

  

Hi,


I am having a problem which follows on from a previous post " https://www.outsystems.com/forums/discussion/39185/exposed-api-need-to-return-content-type-as-text-xml/ that I was having. I managed to get the API to return the correct header by ussing HTTPRequestHandler and added the method of : AddHeader to the Request callback.

Now however, when I include the Accept : text/xml header into my request from postman, I get a 406 error saying that the requested media type is not supported. I have created a small diagram below to illustrate the scenario and remove any ambiguity. I am not sure if there is something obviously wrong, or there is some small detail I am overlooking. 

HI Johann,

Are you able to succesfully send a message with Postman? If so, you should check what OutSystems is sending via the integration logging (if you haven't set the logging level to "Full", see this post), and compare that to what Postman sends (and you're expecting).

Great, thanks for the advice I will try and give an update. Can I just ask from an explanation point of view. How does Outystems know to give a 406 error ? 

My current understanding of the Accept http header is that the requester tells the API that it expects text/xml in the response load by specifying  header , Accept : text/xml (any) and that the API puts a header of , Accept : text/xml into the reponse to say, yes this api can return and supports that response type and it is in this exchange that the 406 error is avoided. Can anyone verify that this reasoning is correct, I am very new to Http. 


According to the built in error response codes : https://success.outsystems.com/Documentation/10/Reference/Extensibility_and_Integration/REST_APIs/Exposed_REST_API/Built-in_HTTP_Status_Codes


it means that  "The 'Accept' header of the request requires a response media type that is not supported.


The only documentation I could find talks about the supported media types is this : https://success.outsystems.com/Documentation/10/Reference/Extensibility_and_Integration/REST_APIs/Exposed_REST_API/Supported_Media_Types_in_REST_API_Requests

However this seems to talk more about what Content-Type headers can be made towards the exposed api. 

My question really is, is it definitely possible to expose a REST API on Outsystems which can respond with text/xml where the requester has placed a Content-Type: text/xml , and, Accept : text/xml header into the request.

Or is it a possibility that there is some limitation in Outsystems that is resulting in the error? 

Or is it possible that there is some other error unrelated to the Accept header which is tricking outsystems into thinking that is the issue. 




Hi Johann,

The OutSystems Platform does not support text/xml, so any response with that type (or any other unsupported type) will result in a 406. However, you can probably use the On Response of the consumed REST API to change the text/xml to text/plain, so that OS will except the payload.

Hi Kilian, 


Good to know. I just want to try understand how you know that. Is there perhaps some reference material on what data formats are and are not supported or do you just know this from trial and error. 


Just to make sure that we are on the same page again. I am making a request to an API I exposed in Outsystems. The request is made in post man and is to emulate the request which will be made from a third part service I am using.

The request has header
Accept : text/xml (which I understand as - "the response I am expecting from this request is a body of format text/xml")


My response has header :

Content-Type: text/xml (Which I understand as - "The Content Type I am sending you is text/xml - which agrees with your requested content type of Accept : text/xml" 


Is there really no way this can happen without a 406 error occurring ? 

PS: it is not OS that needs to accept the payload as txt/xml it the Postman (or the third part service I am acting as while using postman)

** In the case where it really is impossible to have this HTTP conversation using the exposed API, could you or someone else possibly suggest an alternative or work around? Are there alternative ways to set up an API in Outsystems. Or is it possible to redirect an API request to node js on AWS server or something along those lines?

Thanks for your help so far, your responses are always useful. 

Hi Johann,

As for "how do you know that", I recalled it from some experimentation, but my memory may have failed me. The 2nd link you posted above is about the recevied Content-Type header, but in this case there is no Content-Type in the request as you are issuing a GET request (which, by definition, doesn't have a body, and therefore no Content-Type).

Also, I have created a simple Exposed REST API, and I can call it from Postman just fine (with a GET and an Accept of "text/xml") without getting errors, but also, I cannot set the "Content-Type" even with AddHeader from HTTPRequestHandler, the Platform always sends the content type it deems correct (overriding any header added).


Hi Kilian, 

Do you mind sharing this exposed REST API get request with an Accept API. 

Perhaps I could look at that and spot what I have don't differently. It really just needs to meet the following criteria. 

  • Responds to a Get request (containing an Accept Header) made from post man without a 406 error. 
  • Returns a body of text/xml (any sample xml) (even if it is not returning the Content-Type header in the response). 

As for the GET request having a Content-Type which describes the data type of the body. (Even though GET requests by definition do not have a body). I agree with the logic completely. It is very strange that the third part service that is sending this header with their GET request. I have looked at their log and it shows all the headers being written and this is one of them. 


As for getting the Content-Type header returned in the response, did you see my final post here: 

https://www.outsystems.com/forums/discussion/39185/exposed-api-need-to-return-content-type-as-text-xml/

For some reason I was told by the Outsystems support that you could add it - On Request. This did not really make sense to me, because my understanding was that on request was for modifying the request, not the response. Anyway I checked it and I did get the Content-Type: header in the response being text/xml. I am not sure if this logical but it seemed to work. 


Thanks for the responses so far, if you could send that exposed rest API that would be greatly appreciated. 

Ah, indeed, adding in the Request... Really, really weird. Can't explain it. Anyways, the headers should be available just like when consuming, really strange that's not possible.

As for an exposed REST API, I just did the very simplest possible:

  1. Select "Expose REST API" from the REST context menu;
  2. Select "Add REST API Method" from the new REST API's context menu;
  3. Define a single Output Parameter, Data Type "Text", Send In "Body";
  4. Create an OnRequest with an AddHeader that adds "Content-Type" with "text/xml";
  5. Use Postman to call the method, with a single added header "Accept" with "text/xml".

That works fine.

Hi Kilian, 

Any chance you could upload OLM of this. For me it simply does not work - I think there may be something stupid I am doing. 

Here it is.

And here's the Postman collection I used:

{
"info": {
"_postman_id": "0de6ee5f-0df5-4f3d-9dbc-3064633c59a1",
"name": "XmlGet",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "https://YOURURL/RestXml/rest/GimmeXml/Xml",
"request": {
"method": "GET",
"header": [
{
"key": "Accept",
"value": "\"text/xml\""
}
],
"body": {},
"url": {
"raw": "https://YOURURL/RestXml/rest/GimmeXml/Xml",
"protocol": "https",
"host": [
"YOURURL"
],
"path": [
"RestXml",
"rest",
"GimmeXml",
"Xml"
]
}
},
"response": []
}
]
}

In you postman request, you wrap you text/xml in "" -> making it "text/xml" - is this typically done?


Your request (works)  - But I think by default postman already puts "" around the value. So adding again would make it "Accept" : " "text/xml" " (I think) 


Without the ""

Hi Johann,

You are right, it shouldn't be there, I was just copy/pasting from Service Studio. If I remove the quotes, I also get a 406. Remarkably, even when turning debugging on, the call isn't logged, so it's stopped dead even before that, it seems. I'd suggest asking OutSystems Support for help, as this seems undocumented behaviour.

Interestingly enough though. 

This suggests to me (although I may be mistaken) that Outsystems needs the Accept (in the client request) Content-Type(in the APIs response) to be exactly the same. 

Option 1:

So now my question could be, is there a way to remove charset=utf-8 from the response. Does it even make sense that doing this would work ?


Option 2:

Would it be possible to edit the clients request to add an Accept header of charset=utf-8. 


Question: 

Is it possible that this is an encoding problem ? This link talk about encoding problems, but I am not sure if this is relevant here. 

https://www.outsystems.com/forums/discussion/16634/rest-encoding-problem/

How I understand this situation is.

- Client request is saying "I Accept text/xml only"

- the api response is saying " I am giving you content type text/xml and it is utf-8 encoded" 

- Outsystems error logic is going "I have compared the request and the response and determined that the conversation is not compatible - therefore there is a 406 error and which means it relates to the accept header"


Unfortunately up till now I assumed the accept header had to be talking about the text/xml, but the Accept also relates to the encoding. Do you agree ?

Hi Johann,

"charset=utf-8" is doing just that, telling the receiver what charset is used. It'll never lead to 406 errors, so forget that line of thought. Again, please contact OutSystems Support, they will likely be able to tell you where that 406 is coming from.

I have contacted Ousystems support and am awaiting their reply :) I will post it asap. 

Please note, though when I do specify the character set accepted the 406 error does go away.  

I think specifying the same header twice, as you seem to do, overrides the first header, so OutSystems only reacts to the "charset=utf-8" (and defaulting to text/plain or the like, at least ignoring the text/xml). If you'd specify the correct "text/xml; charset=utf-8", you still get a 406.

Yes. You are 100% right about that. I have contacted support, but still waiting to hear back.