You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apisix.apache.org by Jinhua Luo <lu...@gmail.com> on 2023/01/29 01:45:19 UTC

[DISCUSS] Proposal: APISIX: body transform plugin

Background:

This plugin is used to transform the request or response body from one
format to another format, e.g. JSON to XML.

It depends on xml2lua and lua-resty-template.

Use cases:

* simple SOAP proxy
* generic template-based transform

Demo:

curl http://127.0.0.1:9180/apisix/admin/routes/test_ws \
    -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "methods": ["POST"],
    "uri": "/ws",
    "plugins": {
        "proxy-rewrite": {
            "headers": {
                "set": {
                    "Accept-Encoding": "identity",
                    "Content-Type": "text/xml"
                }
            }
        },
        "response-rewrite": {
            "headers": {
                "set": {
                    "Content-Type": "application/json"
                }
            }
        },
        "body-transform": {
            "request": {
                "input_format": "json",
                "template": "
<soap-env:Envelope xmlns:soap-env=\"http://schemas.xmlsoap.org/soap/envelope/\">
    <soap-env:Body>
        <ns0:getCountryRequest
xmlns:ns0=\"http://spring.io/guides/gs-producing-web-service\">
            <ns0:name>{{name:escape_xml()}}</ns0:name>
        </ns0:getCountryRequest>
    </soap-env:Body>
</soap-env:Envelope>
                "
            },
            "response": {
                "input_format": "xml",
                "template": "
{% if Envelope.Body.Fault == nil then %}
{
   \"status\":\"{{_ctx.var.status}}\",
   \"currency\":\"{{Envelope.Body.getCountryResponse.country.currency}}\",
   \"population\":{{Envelope.Body.getCountryResponse.country.population}},
   \"capital\":\"{{Envelope.Body.getCountryResponse.country.capital}}\",
   \"name\":\"{{Envelope.Body.getCountryResponse.country.name}}\"
}
{% else %}
{
   \"message\":\"{{Envelope.Body.Fault.faultstring[1]:escape_json()}}\",
   \"code\":\"{{Envelope.Body.Fault.faultcode}}\"
   {% if Envelope.Body.Fault.faultactor ~= nil then %}
   , \"actor\":\"{{Envelope.Body.Fault.faultactor}}\"
   {% end %}
}
{% end %}
                "
            }
        }
    },
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "localhost:8080": 1
        }
    }
}'

curl -s http://127.0.0.1:9080/ws -X POST -d '{"name": "Spain"}' | jq
{
  "status": "200",
  "currency": "EUR",
  "population": 46704314,
  "capital": "Madrid",
  "name": "Spain"
}

# Fault response
curl -s http://127.0.0.1:9080/ws -X POST -d '{"name": "Spain"}' | jq
{
  "message": "Your name is required.",
  "code": "SOAP-ENV:Server"
}