WSO2 REST API:如何在 GET 请求中 return 多行
WSO2 REST API: How to return more than one row in the GET request
请问如何获得多行?
我的 API 来源:
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<property expression="json-eval($.vendorId)" name="vendorId" scope="default" type="STRING"/>
<dblookup>
<connection>
<pool>
<dsName>MyDS</dsName>
</pool>
</connection>
<statement>
<sql><![CDATA[select * from db_view v where v.vendorId = nvl(?, v.vendorId)]]></sql>
<parameter expression="$ctx:vendorId" type="VARCHAR"/>
<result column="vendorId" name="vendorId"/>
<result column="vendorName" name="vendorName"/>
</statement>
</dblookup>
<filter xpath="boolean($ctx:vendorId)">
<then>
<payloadFactory media-type="json">
<format>{"result": { "vendorId" : "","vendorName" : ""}}</format>
<args>
<arg evaluator="xml" expression="$ctx:vendorId" literal="false"/>
<arg evaluator="xml" expression="$ctx:vendorName" literal="false"/>
</args>
</payloadFactory>
</then>
<else>
<payloadFactory media-type="json">
<format>{"response" : { "code" : "01","message" : "fail"}}</format>
</payloadFactory>
</else>
</filter>
</inSequence>
我的数据库视图 return 有 5 行,但我只从 GET 请求中得到第一行:
{"result": { "vendorId" : "123", "vendorName" : "My Vendor N1" }}
此外,如果我传递参数 vendorId = 321,api 应该 return 0 行。目前它总是return是视图的第一行。为什么以及如何让它发挥作用?
提前致谢
CALLOUT 调解员:
<resource methods="GET" uri-template="/get/supplier/{filterQuery}">
<inSequence>
<property name="operation" value="view" scope="default" type="STRING"/>
<log level="full" separator="|">
<property name="operation" expression="get-property('operation')"/>
<property name="step" value="request"/>
</log>
<property name="filterQuery" expression="get-property('uri.var.filterQuery')" scope="default" type="STRING"/>
<log level="full" separator="|">
<property name="filterQuery" expression="$ctx:filterQuery"/>
</log>
<callout serviceURL="http://...:8280/services/serviceName" action="/vendors/$ctx:filterQuery">
<source type="envelope"/>
<target key="response"/>
</callout>
<log level="custom" separator="|">
<property name="MESSAGE" expression="$ctx:response"/>
</log>
<property name="res" expression="$ctx:response" scope="default" type="OM"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<property name="contentType" value="application/json" scope="transport" type="STRING"/>
<payloadFactory media-type="json">
<format>{"vendorId": "","vendorName": ""}</format>
<args/>
</payloadFactory>
<log level="full" separator="|">
<property name="operation" expression="$ctx:operation"/>
<property name="step" value="response"/>
</log>
<respond/>
</inSequence>
<faultSequence>
<payloadFactory media-type="json">
<format>{"response" : {"code" : "01", "message" : "fail"}}</format>
<args/>
</payloadFactory>
</faultSequence>
</resource>
这是正常现象。正如您在 DBLookup Mediator documentation 中看到的:
The DBLookup mediator can set a property from one row in a result set. It cannot return multiple rows. If you need to get multiple records, or if you have a table with multiple parameters (such as URLs), you can use the WSO2 Data Services Server to create a data service and invoke that service from the ESB using the Callout mediator instead.
您不能使用提到的 dblookup madiator,但可以使用 DataSources。
获取方法数据服务的简要数据源示例;
<data name="RDBMSDataService" serviceStatus="active" transports="http https local">
<config enableOData="false" id="Datasource">
<property name="driverClassName">com.mysql.jdbc.Driver</property>
<property name="url">jdbc:mysql://localhost:3306/Employees</property>
<property name="username">root</property>
<property name="password">password</property>
</config>
<resource method="GET" path="Employee/{EmployeeNumber}">
<call-query href="GetEmployeeDetails">
<with-param name="EmployeeNumber" query-param="EmployeeNumber"/>
</call-query>
</resource>
<query id="GetEmployeeDetails" useConfig="Datasource">
<sql>select EmployeeNumber, FirstName, LastName, Email, Salary from Employees where EmployeeNumber=:EmployeeNumber</sql>
<result outputType="json">{
"Employees":{
"Employee":[
{
"EmployeeNumber":"$EmployeeNumber",
"FirstName":"$FirstName",
"LastName":"$LastName",
"Email":"$Email",
"Salary":"$Salary"
}
]
}
}</result>
<param name="EmployeeNumber" sqlType="STRING"/>
</query>
</data>
您可以创建此 .dbs 文件并进行部署。然后你可以用特定的参数调用这个组件,比如 http://localhost:8290/services/RDBMSDataService/Employee/{EmployeeNumber} 然后它将 return json :
{
"Employees": {
"Employee": [
{
"EmployeeNumber": "5012",
"FirstName": "Will",
"LastName": "Smith",
"Email": "will@smith.com",
"Salary": "13500.0"
},
{
"EmployeeNumber": "5013",
"FirstName": "Parker",
"LastName": "Peter",
"Email": "peter@parker.com",
"Salary": "15500.0"
}
]
}
}
您可以从上下文中获取值,例如:
<property expression="json-eval($.Employees)" name="EmployeeList" scope="default" type="STRING"/>
请问如何获得多行? 我的 API 来源:
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<property expression="json-eval($.vendorId)" name="vendorId" scope="default" type="STRING"/>
<dblookup>
<connection>
<pool>
<dsName>MyDS</dsName>
</pool>
</connection>
<statement>
<sql><![CDATA[select * from db_view v where v.vendorId = nvl(?, v.vendorId)]]></sql>
<parameter expression="$ctx:vendorId" type="VARCHAR"/>
<result column="vendorId" name="vendorId"/>
<result column="vendorName" name="vendorName"/>
</statement>
</dblookup>
<filter xpath="boolean($ctx:vendorId)">
<then>
<payloadFactory media-type="json">
<format>{"result": { "vendorId" : "","vendorName" : ""}}</format>
<args>
<arg evaluator="xml" expression="$ctx:vendorId" literal="false"/>
<arg evaluator="xml" expression="$ctx:vendorName" literal="false"/>
</args>
</payloadFactory>
</then>
<else>
<payloadFactory media-type="json">
<format>{"response" : { "code" : "01","message" : "fail"}}</format>
</payloadFactory>
</else>
</filter>
</inSequence>
我的数据库视图 return 有 5 行,但我只从 GET 请求中得到第一行:
{"result": { "vendorId" : "123", "vendorName" : "My Vendor N1" }}
此外,如果我传递参数 vendorId = 321,api 应该 return 0 行。目前它总是return是视图的第一行。为什么以及如何让它发挥作用? 提前致谢
CALLOUT 调解员:
<resource methods="GET" uri-template="/get/supplier/{filterQuery}">
<inSequence>
<property name="operation" value="view" scope="default" type="STRING"/>
<log level="full" separator="|">
<property name="operation" expression="get-property('operation')"/>
<property name="step" value="request"/>
</log>
<property name="filterQuery" expression="get-property('uri.var.filterQuery')" scope="default" type="STRING"/>
<log level="full" separator="|">
<property name="filterQuery" expression="$ctx:filterQuery"/>
</log>
<callout serviceURL="http://...:8280/services/serviceName" action="/vendors/$ctx:filterQuery">
<source type="envelope"/>
<target key="response"/>
</callout>
<log level="custom" separator="|">
<property name="MESSAGE" expression="$ctx:response"/>
</log>
<property name="res" expression="$ctx:response" scope="default" type="OM"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<property name="contentType" value="application/json" scope="transport" type="STRING"/>
<payloadFactory media-type="json">
<format>{"vendorId": "","vendorName": ""}</format>
<args/>
</payloadFactory>
<log level="full" separator="|">
<property name="operation" expression="$ctx:operation"/>
<property name="step" value="response"/>
</log>
<respond/>
</inSequence>
<faultSequence>
<payloadFactory media-type="json">
<format>{"response" : {"code" : "01", "message" : "fail"}}</format>
<args/>
</payloadFactory>
</faultSequence>
</resource>
这是正常现象。正如您在 DBLookup Mediator documentation 中看到的:
The DBLookup mediator can set a property from one row in a result set. It cannot return multiple rows. If you need to get multiple records, or if you have a table with multiple parameters (such as URLs), you can use the WSO2 Data Services Server to create a data service and invoke that service from the ESB using the Callout mediator instead.
您不能使用提到的 dblookup madiator,但可以使用 DataSources。 获取方法数据服务的简要数据源示例;
<data name="RDBMSDataService" serviceStatus="active" transports="http https local">
<config enableOData="false" id="Datasource">
<property name="driverClassName">com.mysql.jdbc.Driver</property>
<property name="url">jdbc:mysql://localhost:3306/Employees</property>
<property name="username">root</property>
<property name="password">password</property>
</config>
<resource method="GET" path="Employee/{EmployeeNumber}">
<call-query href="GetEmployeeDetails">
<with-param name="EmployeeNumber" query-param="EmployeeNumber"/>
</call-query>
</resource>
<query id="GetEmployeeDetails" useConfig="Datasource">
<sql>select EmployeeNumber, FirstName, LastName, Email, Salary from Employees where EmployeeNumber=:EmployeeNumber</sql>
<result outputType="json">{
"Employees":{
"Employee":[
{
"EmployeeNumber":"$EmployeeNumber",
"FirstName":"$FirstName",
"LastName":"$LastName",
"Email":"$Email",
"Salary":"$Salary"
}
]
}
}</result>
<param name="EmployeeNumber" sqlType="STRING"/>
</query>
</data>
您可以创建此 .dbs 文件并进行部署。然后你可以用特定的参数调用这个组件,比如 http://localhost:8290/services/RDBMSDataService/Employee/{EmployeeNumber} 然后它将 return json :
{
"Employees": {
"Employee": [
{
"EmployeeNumber": "5012",
"FirstName": "Will",
"LastName": "Smith",
"Email": "will@smith.com",
"Salary": "13500.0"
},
{
"EmployeeNumber": "5013",
"FirstName": "Parker",
"LastName": "Peter",
"Email": "peter@parker.com",
"Salary": "15500.0"
}
]
}
}
您可以从上下文中获取值,例如:
<property expression="json-eval($.Employees)" name="EmployeeList" scope="default" type="STRING"/>