我可以在基本 DataWeave 转换中使用动态输出媒体类型吗?

Can I have a dynamic output media type in a basic DataWeave transform?

我有一个用 Mule 4.1.5 编写的相当简单的 RESTful API,它可以根据 Accept header 生成 XML 或 JSON GET 请求。

对于从源中检索和转换数据的快乐日子场景,转换的不同足以证明为每种媒体类型使用单独的数据编织脚本是合理的。但是对于 API 套件错误处理程序中的标准错误情况(HTTP 400、404、405、406 等),它主要只是返回一个固定响应,可以通过同一脚本为任一媒体类型创建。

是否可以有一个脚本具有基于 Accept Header 的动态输出媒体类型?

我目前的方法(确实有效)是根据接受 header(已保存到变量)进行选择。但这有点笨拙,如果有更聪明的方法,那就太好了。

<choice doc:name="Route by Accept Header">
    <when expression="#[lower(vars.outputType) == 'application/xml']" >
        <ee:transform doc:name="XML">
            <ee:message>
                <ee:set-payload><![CDATA[%dw 2.0
output application/xml
---
{message: "Bad request"}]]></ee:set-payload>
            </ee:message>
            <ee:variables>
                <ee:set-variable variableName="httpStatus"><![CDATA[400]]></ee:set-variable>
            </ee:variables>
        </ee:transform>
    </when>
    <otherwise>
        <ee:transform doc:name="JSON">
            <ee:message >
                <ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
{message: "Bad request"}]]></ee:set-payload>
            </ee:message>
            <ee:variables >
                <ee:set-variable variableName="httpStatus" ><![CDATA[400]]></ee:set-variable>
            </ee:variables>
        </ee:transform>
    </otherwise>
</choice>

有几个选项可以实现这一点。

首先你可以使用dynamic-evaluate组件。以下是文档:https://docs.mulesoft.com/mule-runtime/4.1/dynamic-evaluate-component-reference

在这个例子中,他们用它来决定输出媒体类型。但它仍然需要从数据库加载多个脚本。您可以定制它以从文件加载或进行一些连接等。例如,这里是使用手动连接构建脚本的粗略示例:

<set-variable value="application/xml" variableName="outputType" />
<set-variable value="#['output ' ++ lower(vars.outputType) ++ ' --- ' ++ '{message: \'Bad request\'}']" variableName="script" />

<ee:dynamic-evaluate expression="#[vars.script]" />

其次,您可以让所有转换输出 1 个公共 media-type。说 application/java.

然后在最后调用 flow-ref 只执行 media-type 映射:

     <flow name="change-media-type">
            <choice>
                    <when expression="#[lower(vars.outputType) == 'application/xml']">
                        <set-payload value="#[output application/xml --- payload]" />
                    </when> 
                    <otherwise>
                        <set-payload value="#[output application/json --- payload]" />
                    </otherwise>
                </choice>
     </flow>
     ...

    <ee:transform>
        <ee:message>
           <ee:set-payload><![CDATA[%dw 2.0
    output application/java
    ---
    {message: "Bad request"}]]></ee:set-payload>
         </ee:message>
          <ee:variables>
              <ee:set-variable variableName="httpStatus"><![CDATA[400]] />
          </ee:variables>
    </ee:transform>

    <flow-ref name="change-media-type" />

另请注意,使用动态媒体类型映射时,您需要确保您的 body 始终与 XML 和 JSON 兼容。由于 XML.

中的根元素等原因,并非所有 JSON 有效载荷都兼容