API Connect

API Connect

Join this online group to communicate across IBM product users and experts by sharing advice and best practices with peers and staying up to date regarding product enhancements.

 View Only
  • 1.  When transforming from JSON -> XML, the content-type for the outgoing request is not set to xml

    Posted Mon April 15, 2024 07:46 AM

    Hi guys,

    we are using the built-in REST proxy for a SOAP API (as shown in screenshot below) with an existing WSDL:

    The transformation of the incoming JSON request payload is done correctly.

    However when sending the outgoing message/payload to the backend, the content-type header reaching the backend is still set to application/JSON instead of text/XML. This leads to an error with the payload not getting processed correctly at the backend (SAP).

    We have already tried setting the content-type header explicitly in the flow before the invoke with a set-variable policy to no effect. We have also tried setting the backend type in the invoke policy to XML. 

    Is there something we are missing here? Are there any suggestion on how to set the content-type header to text/XML for the outgoing message?

    Thank you.

    Best regards

    Henri



    ------------------------------
    Henri Unruh
    ------------------------------


  • 2.  RE: When transforming from JSON -> XML, the content-type for the outgoing request is not set to xml

    Posted Wed April 24, 2024 09:50 AM

    Hi Henri,
    I just tried a simple test case of an API that posted JSON with a content-type request header of application/json.  The API does a parse policy to parse the JSON in the request.body to a parsed JSON object in message.body, followed by the JSON2XML policy which always consumes message.body.  The end result is an XML payload with a response content-type header of application/xml, so I am unable to recreate your use case.  As for invoke, it will always use the contents of message.  The JSON2XML policy should update message.headers.content-type to application/xml and place the XML body in message.body.  If that isn't happening for you, your set variable policy prior to your invoke should set message.headers.content-type to application/xml (type string) but that really shouldn't be needed.  What version of DataPower are you using? I'm not aware of any firmware fixes to this policy, so I'd suggest you open a support ticket to determine if there is anything specific to your API that is causing this behavior.
    Regards,

    Steve



    ------------------------------
    Steve Linn
    Senior Consulting I/T Specialist
    IBM
    ------------------------------



  • 3.  RE: When transforming from JSON -> XML, the content-type for the outgoing request is not set to xml

    Posted Wed April 24, 2024 10:05 AM

    Hi Steve,

    thank you for your message and investigation.

    We use the following configuration in the API definition as part of the assembly:

          - switch:
              title: switch
              case:
                - condition: (($httpVerb() = 'POST'))
                  execute:
                    - parse:
                        version: 2.0.0
                        title: parse
                        parse-settings-reference:
                          default: apic-default-parsesettings
                        input: request
                        output: message
                        use-content-type: true
                    - map:
                        title: 'OrderConfirmationRequest_Out: input'
                        inputs:
                          request:
                            schema:
                              $ref: '#/definitions/ORDERS05_element_n1'
                            variable: message.body
                            content: application/json
                        outputs:
                          content-type:
                            schema:
                              type: string
                            variable: message.headers.content-type
                          body:
                            schema:
                              $ref: >-
                                #/x-ibm-configuration/targets/OrderConfirmation_service/definitions/OrderConfirmationRequest_OutInput
                            variable: message.body
                            content: text/xml
                          SOAPAction:
                            schema:
                              type: string
                            variable: message.headers.SOAPAction
                        actions:
                          - set: content-type
                            default: text/xml
                          - set: SOAPAction
                            default: ''
                          - set: body.Envelope.Body.ORDERS05
                            from: request
                        options:
                          includeEmptyXMLElements: false
                          inlineNamespaces: false
                          mapEnablePostProcessingJSON: true
                          mapResolveXMLInputDataType: true
                          mapResolveApicVariables: false
                        version: 2.0.0
                    - gatewayscript:
                        version: 2.0.0
                        title: Remove_header_variable_cookie
                        source: context.message.header.remove('Cookie');
                    - switch:
                        version: 2.0.0
                        title: switch
                        case:
                          - condition: ($header("x-region") = "01")
                            execute:
                              - set-variable:
                                  version: 2.0.0
                                  title: set-variable
                                  actions:
                                    - set: message.headers.content-type
                                      value: text/xml
                                      type: string
                              - invoke:
                                  title: 'OrderConfirmationRequest_Out: invoke'
                                  target-url: >-
                                    $(target-url-XYZ)
                                  timeout: 60
                                  verb: POST
                                  cache-response: protocol
                                  cache-ttl: 900
                                  stop-on-error:
                                    - ConnectionError
                                    - OperationError
                                  version: 2.0.0
                                  header-control:
                                    type: blocklist
                                    values: []
                                  parameter-control:
                                    type: blocklist
                                    values: []
                                  persistent-connection: true
                                  backend-type: xml

    However we can still observe at the backend, that the value of the content-type header is application/json. Maybe you see something in the code above that would cause this behaviour?

    We are using DataPower version IDG.10.5.0.5.

    In any case, we will open a support ticket and provide the full YAML API spec to rule out any other configuration errors.

    Best regards

    Henri



    ------------------------------
    Henri Unruh
    ------------------------------



  • 4.  RE: When transforming from JSON -> XML, the content-type for the outgoing request is not set to xml

    Posted Wed April 24, 2024 10:36 AM

    Hi Henri,
    So a key detail! The JSON2XML is really a map policy, not the actual JSON2XML policy! I think I've seen this once a few years ago with a migrated API where the customer reordered their map outputs which resolved the issue and they closed their PMR.  In your case you have three map outputs:
    1. content-type
    2. body
    3. SOAPAction

    Please modify in your source of your map policy outputs to make the body output the first of the three and see if that makes a difference.

                        outputs:
                          body:
                            schema:
                              $ref: >-
                                #/x-ibm-configuration/targets/OrderConfirmation_service/definitions/OrderConfirmationRequest_OutInput
                            variable: message.body
                            content: text/xml
                          content-type:
                            schema:
                              type: string
                            variable: message.headers.content-type
                          SOAPAction:
                            schema:
                              type: string
                            variable: message.headers.SOAPAction

    and please let me know if that resolves your issue.
    Thanks,
    Steve



    ------------------------------
    Steve Linn
    Senior Consulting I/T Specialist
    IBM
    ------------------------------



  • 5.  RE: When transforming from JSON -> XML, the content-type for the outgoing request is not set to xml

    Posted Mon April 29, 2024 10:26 AM

    Hi Steve, 

    our developers tested it now as follows:

                   - map:
                        title: 'OrderConfirmationRequest_Out: input'
                        outputs:
                          body:
                            schema:
                              $ref: >-
                                #/x-ibm-configuration/targets/OrderConfirmation_service/definitions/OrderConfirmationRequest_OutInput
                            variable: message.body
                            content: text/xml
                          content-type:
                            schema:
                              type: string
                            variable: message.headers.content-type
                          SOAPAction:
                            schema:
                              type: string
                            variable: message.headers.SOAPAction
                        inputs:
                          request:
                            schema:
                              $ref: '#/definitions/ORDERS05_element_n1'
                            variable: message.body
                            content: application/json
                        actions:
                          - set: content-type
                            default: text/xml
                          - set: SOAPAction
                            default: ''
                          - set: body.Envelope.Body.ORDERS05
                            from: request
    
    


    But unfortunately the result is still the same. Or do you see anything wrong in our definition?

    Thank you for looking into it so far. Maybe the IBM support can provide help.

    Best regards

    Henri



    ------------------------------
    Henri Unruh
    ------------------------------



  • 6.  RE: When transforming from JSON -> XML, the content-type for the outgoing request is not set to xml

    Posted Mon April 29, 2024 11:09 AM

    Hi Henri,
    I used a very simple wsdl to create an API from the same wizard you used From existing WSDL service (REST proxy) and the request map policy it generated was very similar to yours.

                    - map:
                        title: 'sayHello: input'
                        description: ''
                        inputs:
                          request:
                            schema:
                              $ref: '#/definitions/sayHelloInput'
                            variable: message.body
                            content: application/json
                        outputs:
                          content-type:
                            schema:
                              type: string
                            variable: message.headers.content-type
                          body:
                            schema:
                              $ref: >-
                                #/x-ibm-configuration/targets/HelloService/definitions/sayHelloInput
                            variable: message.body
                            content: text/xml
                          SOAPAction:
                            schema:
                              type: string
                            variable: message.headers.SOAPAction
                        actions:
                          - set: content-type
                            default: text/xml
                          - set: SOAPAction
                            default: sayHello
                          - set: body.Envelope.Header
                            from: request.header
                          - set: body.Envelope.Body
                            from: request
                        options:
                          includeEmptyXMLElements: false
                          inlineNamespaces: false
                          mapEnablePostProcessingJSON: true
                          mapResolveXMLInputDataType: true
                          mapResolveApicVariables: false
                        version: 2.1.0
    

    When I sent a request to this API, the invoke backend did receive a content-type request header of text/xml as expected.  I also do not understand why your workaround attempts to set message.headers.content-type in a set-variable policy to text/xml didn't work either.  I apologize for asking the obvious, but you were modifying message.headers and not request.headers?  Your initial statement indicates you tried to update this header with a set-variable policy but didn't mention the message name used in the set variable policy.

    I'd open a support ticket.  Ultimately it will come back to me as I'm the map policy developer amongst many other API Gateway duties :-) , but it's best to debug this through the support channel and not in the community forum.  
    Regards,
    Steve



    ------------------------------
    Steve Linn
    Senior Consulting I/T Specialist
    IBM
    ------------------------------



  • 7.  RE: When transforming from JSON -> XML, the content-type for the outgoing request is not set to xml

    Posted Tue April 30, 2024 09:58 AM
    Edited by Henri Unruh Tue April 30, 2024 11:05 AM

    Hi Steve,

    yes, this seems to be standard map policy generated when using From existing WSDL service (REST proxy).

    Maybe the error does actually originate from the backend, because as you say the workaround via set-variable should work too. But from what I've seen the content-type header value reaching the backend was clearly application/json

    We manipulated message.headers.content-type right before the invoke policy as follows:

                                  version: 2.0.0
                                  title: set-variable
                                  actions:
                                    - set: message.headers.content-type
                                      value: text/xml
                                      type: string

    There is already a support ticket (#TS016056878) in which I am now asked to provide a full trace via API probe. I'll try to collect the probe this week.

    Good to know that you are working on the map policy among other duties :) 

    Regards,

    Henri



    ------------------------------
    Henri Unruh
    ------------------------------