Ensemble web service and xml schemas
This might be a very simple rookie question but I'm trying to create couple of web services in Ensemble and using document below as my tutorial, I do manage to do it:
http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...
But instead of doing it as described above, where method signature is like this:
Method GetCustomerInfo(ID As %Numeric) As ESOAP.SOAPResponse [WebMethod]
I would like it to be:
Method GetCustomerInfo(valid XML against schema1) As valid XML against schema2 [WebMethod]
because I'm trying to replicate a web service from another non-Intersystems platform and I have schema that web service request should follow and schema that web service response should follow.
I know how to import these schemas in Ensemble and can then use them as source and target types in data transformations but I have no idea how to use these schemas to define format of my web service's request and response?
Any help much appreciated!
You may take this approach:
create an object based on Schema1: My.Schema1
create an object based on Schema2: My.Schema2
HowTo: => XML Schema Wizzard
http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...
Then you may use this method.
My.Schema1 is checked as input parameter according tothe generated class
inside your Method you transform it to My.Schema2
and return it.
The most tricky thing might be how to reply to a request that doesn't match Schema1.
Example Schema2
<?xml version="1.0" encoding="UTF-8"?>
<s:schema xmlns:s="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<s:complexType name="Schema2">
<s:sequence>
<s:element minOccurs="0" name="Results" type="ArrayOfSchema2Result"/>
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfSchema2Result">
<s:sequence>
<s:element maxOccurs="unbounded" minOccurs="0" name="Schema2Result" nillable="true" type="Schema2Result"/>
</s:sequence>
</s:complexType>
<s:complexType name="Schema2Result">
<s:sequence>
<s:element minOccurs="0" name="Home-Address" type="Address"/>
<s:element minOccurs="0" name="Office-Address" type="Address"/>
<s:element minOccurs="0" name="Person-Name" type="s:string"/>
<s:element minOccurs="0" name="Person-ID" type="s:long"/>
</s:sequence>
</s:complexType>
<s:complexType name="Address">
<s:sequence>
<s:element minOccurs="0" name="Street">
<s:simpleType>
<s:restriction base="s:string">
<s:maxLength value="80"/>
</s:restriction>
</s:simpleType>
</s:element>
<s:element minOccurs="0" name="City">
<s:simpleType>
<s:restriction base="s:string">
<s:maxLength value="80"/>
</s:restriction>
</s:simpleType>
</s:element>
<s:element minOccurs="0" name="State">
<s:simpleType>
<s:restriction base="s:string">
<s:maxLength value="2"/>
</s:restriction>
</s:simpleType>
</s:element>
<s:element minOccurs="0" name="Zip">
<s:simpleType>
<s:restriction base="s:string">
<s:maxLength value="5"/>
</s:restriction>
</s:simpleType>
</s:element>
</s:sequence>
</s:complexType>
</s:schema>
Example Schema1
<?xml version="1.0" encoding="UTF-8"?>
<s:schema xmlns:s="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<s:complexType name="Schema1">
<s:sequence>
<s:element name="Max_Results">
<s:simpleType>
<s:restriction base="s:long">
<s:minInclusive value="1"/>
</s:restriction>
</s:simpleType>
</s:element>
<s:element name="Home-State">
<s:simpleType>
<s:restriction base="s:string">
<s:maxLength value="2"/>
<s:minLength value="2"/>
</s:restriction>
</s:simpleType>
</s:element>
<s:element minOccurs="0" name="Office-State" type="s:string"/>
<s:element minOccurs="0" name="Name-Startswith" type="s:string"/>
</s:sequence>
</s:complexType>
</s:schema>
Example WebService:
Class My.SOAP Extends %SOAP.WebService [ ProcedureBlock ]
{
/// Name des WebService.
Parameter SERVICENAME = "MyService";
/// SOAP Namespace für den WebService
Parameter NAMESPACE = "http://tempuri.org";
/// Namespaces von referenzierten Klassen werden in der WSDL verwendet.
Parameter USECLASSNAMESPACES = 1;
Method GetCustomerInfo(schema1 As My.Schema1) As My.Schema2 [ WebMethod ]
{
set max =schema1.MaxResult
,home =schema1.HomeState
,office=schema1.OfficeState
,start =schema1.NameStartswith
set:'max max=1
set:office="" office=home
set schema2=##class(My.Schema2).%New()
,rs=##class(%ResultSet).%New()
,sql="SELECT top ? %ID FROM Sample.Employee "
_"WHERE Home_State = ? "
_"AND Office_state = ? "
_"AND Name %STARTSWITH ? "
,tSC=rs.Prepare(sql)
set:tSC tSC=rs.Execute(max,home,office,start)
while rs.Next()&&tSC {
set employee=rs.GetObject()
,res=##class(My.Schema2Result).%New()
,res.HomeAddress=employee.Home
,res.OfficeAddress=employee.Office
,res.Name=employee.Name
,res.pid=employee.%Id()
do schema2.Results.Insert(res)
}
quit schema2
}
}
I would just use https://jsonformatter.org/xml-viewer
??? and how do you include this in ENSEMBLE ???
Sorry for late answer but thanks, Robert! Following your example seems to work fine!