Question
· Nov 30, 2017

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!

Discussion (7)0
Log in or sign up to continue

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.

Method GetCustomerInfo(schema1 as My.Schema1) As My.Schema2 [WebMethod]


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:

/// My.SOAP
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
}
}