Websydian v6.1 online documentationOnline documentation - Websydian v6.1

RPC Based Web Services

Introduction to RPC based web services

Please note that support for RPC web services are introduced in Websydian version 6.1 and in the TransacXML import tool version 2.0.

If you are using an earlier version of Websydian, you can still implement most RPC based services, but some of the abstract Plex objects supporting this and some of the functionality described for the SOAP generator are not available.

In the SOAP standard, two distinct ways of looking at web services are described:

  1. Document based: A web service is a function that can receive a request document - handle the document - and return a response document.
  2. RPC based: A web service is a wrapping of an existing function, where the function signature (name and parameter interface) is converted so that the request document for the service will have a top element with the name of the wrapped function. Each parameter will be converted into an XML element with the name of the parameter, this element will be scoped by the top element.

Unfortunately, this distinction has been allowed to have quite significant implications for the implementation of web services (the SOAP standard) and for the description of web services (the WSDL standard). In many cases, the implementation and descriptions of the two different kinds of web services are completely separate.

There is no real reason for this, as you can describe a RPC based service as a service that can receive a document - handle a document (by calling the function that is being wrapped) - and return a response document, which is exactly what a document based service does.

This document will describe how RPC based services are modeled in TransacXML and how you can call these services. There will also be an introduction to RPC encoded web services and how to handle these services.

This document does not provide a full explanation of RPC based web services - see the further reading section at the end of the document for more information.

Understanding this document will be helped by some experience/understanding of the implementation of document based web services in TransacXML, but it should not be a necessity.

This document will focus on how to call RPC based web services.

If you are going provide a web service, we strongly recommend that you implement a document based web service.

Examples of request and response documents

A simple example of an RPC based web service could be if you have a function GetCustomer that receives the customer number as an input field - and returns the name and address as output fields.

This means that the function signature would be like this:

Name:

GetCustomer

Input:

CustomerNumber

Output:

CustomerName

CustomerAddress

The request document created for the service would look like this:

And the response document would look like this:

The top element of the request document has the same name as the function, the one input parameter is added as a simple element that is scoped by the top element.

The top element of the response document has the name of the function, with "Response" added, the two output parameters are added as simple elements scoped by the top element.

When this service is implemented as a SOAP based service, the request and response documents will be wrapped in a SOAP envelope - but to keep this example simple, the SOAP wrapping is not shown here.

As can be seen, these are normal XML documents that could just as well have been described and handled as when using the document based web services.

Modeling for RPC based services in TransacXML

When extending the support of TransacXML to RPC based web services, we have attempted to make the implementation of these services as close to the implementation of the document based services that has been supported by TransacXML for a long time.

So just as for document based web services, what you need to do is to model the request and response documents in Plex using the TransacXML abstract entities and fields.

You can do this modeling in two ways:

  1. If you have a WSDL file or a W3C schema file describing the documents, you can use the TransacXML import tool to create the document definitions. The import tool supports RPC based web services from version 2.0.
  2. If you only have example documents, you must model the request and response documents as described in the TransacXML tutorial.

Introduction to RPC encoded services

RPC-encoding is a subset of the RPC-based services. RPC-encoded services are implemented much as described above - but each parameter also contains a definition of the type of the parameter.

As an example - the function described above, could be implemented as follows when accessing an RPC-encoded service:

The request document:

The response document:

The interesting difference is the xsi:type attributes - for each parameter this specifies the type of the data contained in the parameter.

It is important to note that the name of the parameter field isn't significant - but the sequence and the type definition are.

Modeling for RPC-encoded services in TransacXML

As for the basic RPC-based web services, you must model the request and the response documents in Plex to be able to call an RPC-encoded web service.

You can do this in two different ways:

  1. Use the TransacXML import tool if you have a WSDL describing the document.
  2. If you only have an example document, you must model the documents in Plex. To be able to model the encoded elements, you need to use some new abstract Plex objects. These objects have been introduced in Websydian 6.1. The use of these objects are described below.
Modeling where the parameters are simple elements (fields):

The first example will show how to model the response document shown above.

Define the following triples:

Source Object Verb Target Object
GetCustomerResponse is a ENT WSYXML/XMLElement
GetCustomerResponse.Fields field FLD CustomerName
GetCustomerResponse.Fields field FLD CustomerAddress
GetCustomerResponse.Fields.CustomerName is a FLD WSYXML/ElementField
GetCustomerResponse.Fields.CustomerName is a FLD WSYXML/EncodedField
GetCustomerResponse.Fields.CustomerAddress is a FLD WSYXML/ElementField
GetCustomerResponse.Fields.CustomerAddress is a FLD WSYXML/EncodedField
GetCustomerResponse has FLD GetCustomerResponse.Fields.CustomerName
GetCustomerResponse has FLD GetCustomerResponse.Fields.CustomerAddress

The new feature compared to the modeling that would have been done for the basic RPC service is the inheritance from the EncodedField field.

By specifying this inheritance, you get three source codes scoped by the field:

  1. Type - the text you enter here will be the definition used in the type attribute.
  2. TypeNamespace - this specifies the namespace that the type belongs to.
  3. TypePrefix - this specifies the prefix you want to use in the value for the type attribute.

The following values must be specified for the source codes:

GetCustomerResponse.Fields.CustomerName.Type: string

GetCustomerResponse.Fields.CustomerName.TypeNamespace: http://www.w3.org/2001/XMLSchema

GetCustomerResponse.Fields.CustomerName.TypePrefix: xsd

GetCustomerResponse.Fields.CustomerAddress.Type: string

GetCustomerResponse.Fields.CustomerAddress.TypeNamespace: http://www.w3.org/2001/XMLSchema

GetCustomerResponse.Fields.CustomerAddress.TypePrefix: xsd

The InsertRow function will create the type attributes and insert the values specified in the source code, as well as defining the necessary namespace declarations for the namespaces specified for the values. This means that the input to the InsertRow will only contain two fields (the name and the address).

Modeling where the parameters are complex elements (entities)

The example shown above is relatively simple as each parameter is a simple element (a field) - but it is also possible to implement more complex structures for each parameter.

For instance if the function reading the customer returns a structure as the return parameter, the content of this structure must be defined in the "types" section of the WSDL describing the service. The example response document could look like this:

In this case, the parameter is the CustomerData complex element - so this is where the type definition is placed. MyCustomerDataType must be defined in a schema describing the namespace http://www.MyServer/MyTypes, which must be available in the WSDL describing the service.

So in this case, it is not the fields that is encoded, it is a complex element.

This can be modeled as follows:

Source Object Verb Target Object
GetCustomerResponse is a ENT WSYXML/XMLElement
GetCustomerResponse includes ENT CustomerData
GetCustomerResponse.CustomerData is a ENT WSYXML/XMLElement
GetCustomerResponse.CustomerData is a ENT WSYXML/EncodedElement
GetCustomerResponse.CustomerData.Fields field FLD CustomerName
GetCustomerResponse.CustomerData.Fields field FLD CustomerAddress
GetCustomerResponse.CustomerData.Fields.CustomerName is a FLD WSYXML/ElementField
GetCustomerResponse.CustomerData.Fields.CustomerAddress is a FLD WSYXML/ElementField
GetCustomerResponse.CustomerData has FLD GetCustomerResponse.CustomerData.Fields.CustomerName
GetCustomerResponse.CustomerData has FLD GetCustomerResponse.CustomerData.Fields.CustomerAddress

The inheritance from EncodedElement means that the entity CustomerData will scope three new source code objects:

  1. Type - the text you enter here will be the definition used in the type attribute.
  2. TypeNamespace - this specifies the namespace that the type belongs to.
  3. TypePrefix - this specifies the prefix you want to use in the value for the type attribute.

The following values should be specified in this example:

GetCustomerResponse.CustomerData.Type: MyCustomerDataType

GetCustomerResponse.CustomerData.TypeNamespace: http://www.MyServer/MyTypes

GetCustomerResponse.CustomerData.TypePrefix: mn

When the GetCustomerResponse.CustomerData.InsertRow function is called, the values from these source codes will be used to automatically insert the type attribute and the namespace declaration needed for declaring that the mn prefix is to indicate the http://www.MyServer/MyTypes namespace.

Implementing a call to an RPC encoded web service

As mentioned above, if you are going to provide a web service, we strongly recommend that you use a document based web service.

When you are going to call (consume) a web service, you often do not have this option. In these cases you have to be able to call the service - and to create the request document according to the specifications for the service.

In most cases, the provider will provide a WSDL file describing the service. If the providers doesn't do so, you should ask for one - it is the most commonly accepted way of describing web services. When you have the WSDL, use the TransacXML import tool to create the Plex definitions for the request and response documents.

If you absolutely cannot obtain a WSDL, you must create the definitions yourself as outlined above.

The rest of the implementation is made exactly as it is described for document base web services in the tutorial, with one small exception. In most cases RPC based web services do not specify a SOAP Action for identifying the specific operation to call. Instead the name of the top element in the request document is used to identify the operation (as this will be the name of the function that is wrapped). If this is the case, just specify *Blank for the SOAP Action parameter on the call to the CallSoapGenerator function - when this is done, no SOAPAction header is sent.

Limitations

The implementation of the RPC based web services targets calling (consuming) services, not providing them. The side effect of this is that the CreateWSDL function only generates WSDLs for document based services.

The CreateWSDL function disregards the inheritance from EncodedField/EncodedElement and will define all operations and messages as document/literal.

RPC-encoded arrays are not supported by the WSDL import (See WSDL import limitiations).

Further reading