#mule #dataweave
#mule #поток данных
Вопрос:
У меня есть достаточно простой RESTful API, написанный на Mule 4.1.5, который может создавать XML или JSON на основе заголовка Accept запроса GET.
В сценариях happy days, когда данные извлекаются и преобразуются из источника, преобразования достаточно различны, чтобы оправдать отдельные сценарии потока данных для каждого типа носителя. Но для стандартных ситуаций с ошибками (HTTP 400, 404, 405, 406 и т.д.) В обработчике ошибок API Kit в основном возвращается просто готовый ответ, который может быть создан для любого типа носителя одним и тем же сценарием.
Возможно ли иметь один скрипт, который имеет динамический тип выходного носителя на основе заголовка Accept?
Мой текущий подход (который действительно работает) заключается в выборе на основе заголовка accept (который был сохранен в переменной). Но это немного неуклюже, и если есть более разумный способ сделать это, это было бы здорово.
<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>
Ответ №1:
Для достижения этого есть несколько вариантов.
Сначала вы можете использовать компонент динамической оценки. Вот документы: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 общий тип носителя. Скажем, приложение / java.
А затем в конце вызовите flow-ref, который выполняет только сопоставление типа носителя:
<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" />
Также обратите внимание, что при использовании динамического сопоставления типов носителей вам нужно будет убедиться, что ваше тело всегда совместимо с XML и JSON. Не все полезные нагрузки JSON совместимы из-за корневых элементов и т.д. в XML.
Комментарии:
1. Спасибо, Райан, отличные ответы. Я не знал о компоненте динамической оценки, это довольно интересно. Немного смущен тем, что я не подумал о втором варианте!