Creating a Service Registry

Previous Step: Configuring Web Services in Business Manager

You must create a service registry so that service definitions are available when calling your web service. To create a service registry:

  1. Create a package.json entry to specify the initialization script.
  2. Create an initialization script with service definitions.
  3. For each service definition, specify callbacks. The callbacks create the service requests and handle service responses.

package.json Initialization of Web Services for Your Cartridge

Services need to be created and registered once, rather than every time a script is executed. Services are registered the first time the initialization script is run in a cartridge and any time the initialization script is changed. However, only changes to the initialization script trigger a reregistering of services, not changes to any scripts referenced by the initialization script.

You must create a package.json file for your cartridge that contains init as the key and the path to the initialization scripts that register your web services. Any changes to the initialization scripts trigger the web services registry object to be updated.

Note: It isn't possible to deregister a service. However, you can remove the web service registry entry and disable the web service configuration in Business Manager.

Example: package.json Entry for an Initialization Script

{
    "init": ["./cartridge/scripts/serviceInit.ds"]
}
You can also add multiple service initialization scripts:
{
    "init": ["./cartridge/scripts/init/httpServiceInit.ds", 
    	     "./cartridge/scripts/init/httpFormServiceInit.ds",
    	     "./cartridge/scripts/init/soapServiceInit.ds",
    	     "./cartridge/scripts/init/ftpServiceInit.ds"]
}

Creating the Service Registry and Service Definitions

The initialization scripts referenced in the package.json create a ServiceRegistry object and use the ServiceRegistry.configure method to add service definitions. In the service definiton, use ServiceCallback class methods to call the web service, parse the response, and manage error messages. An HTTP/FTP service usually has three callbacks: createRequest, parseResponse, and mockCall. A SOAP service has an additional execute callback.

The ServiceDefinition object is created and used to create Service objects. Service objects are a single-use object used to make a remote call. The ServiceRegistry maintains a map of service names to ServiceDefinition objects, which are used to make new Service objects for a specific call to the web service. The ServiceDefinition class doesn't have a constructor, so you can't create it directly. To get an instance of this class, use the ServiceRegistry class configure method.

Example: simple service Registration

This example creates a service registry with a single service definition for an FTP service. The service definition executes a single operation which is defined in the web service script

importPackage( dw.svc );
importPackage( dw.net );
importPackage( dw.io );

//the configure method creates the ServiceDefinition object for the MyFTPService 
ServiceRegistry.configure("MyFTPService", {
    //the ServiceDefinition uses methods from the ServiceCallback object
    createRequest: function(svc:FTPService, params) {
        svc.setOperation("list", "/");
    },
    parseResponse : function(svc:FTPService, listOutput) {
        var x : Array = [];
        var resp : Array = listOutput;
        for(var i = 0; i < resp.length; i++) {
            var f = resp[i];
            x.push( { "name": f['name'], "timestamp": f['timestamp'] } );
        }
        return x;
    }
    mockCall : function(svc:FTPService, params) {
        return [
            { "name": "file1", "timestamp": new Date(2011, 02, 21)},
            { "name": "file2", "timestamp": new Date(2012, 02, 21)},
            { "name": "file3", "timestamp": new Date(2013, 02, 21)}
        ];
    },
});

Creating Service Callbacks

When you invoke the web service from your web service script, using Service.call, Salesforce B2C Commerce checks the circuit breaker and rate limiter configuration and then executes the service callbacks. The callbacks are executed in logical order, not in the order in which they are defined in the registry. For example, parseResponse is never executed before createRequest.
Note: The execute callback, when specified, is always executed after the createRequest callback.

The service callbacks define how the request for the web service is constructed and how the response from the web service is parsed. Every service call back requires you to pass a Service object. The Service object is always one of the subclasses: FTPService, HTTPFormService, HTTPService, SOAPService, unless you are registering a generic service, in which case it's simply a Service object.

HTTP or HTTP Form Callbacks

For an HTTP service, pass in HTTPService objects. For an HTTP form, pass in HTTPFormService objects.

Recommended callbacks for HTTP services:
  • createRequest: Required to create a requestData object. If you need additional processing, you can pass the requestData object to the execute callback. Otherwise, the requestData object is used to call the web service when the Service object is invoked.
  • parseResponse: Gives the HTTPClient as its extra argument. Use to parse the response contained in the Service object.

FTP or SFTP Callbacks

For an FTP or SFTP service, pass in FTPService objects.
Recommended callbacks
  • createRequest: Required to create a requestData object. If you need additional processing, you can pass the requestData object to the execute callback. Otherwise, the requestData object is used to call the web service when the Service object is called.
  • parseResponse: Gives the FTPClient as its extra argument. Use to parse the response contained in the Service object.
  • execute: If the setOperation method isn't called in the web service script, operations defined in the execute callback are executed when the web service is invoked. You can use the execute method to perform multiple operations in sequence.

SOAP Callbacks

For any SOAP service, pass in a SOAPService object.

Recommended callbacks
  • initServiceClient: Use get a dw.rpc.stub and webreferences object (rpc-style) or a dw.ws.port (doc-style) and webreferences2 object.
  • createRequest: Required to create a requestData object. This object must be passed to the execute method.
  • execute: Specifies additional processing for the web service request.
    Note: If you get your stub or port in this step, instead of in the initServiceClient callback, any timeouts you set will override those set in the service configuration. This isn't recommended.
  • parseResponse: Use this method to parse the response in the Service object.

Generic Callbacks

Does not wrap any class. Used to define custom calls.

Note: You must pass a plain Service object, rather than a subclass, for this callback method.

Caching Web Service Calls

If you want to cache web service calls for HTTPService, in your createRequest callback, use the getClient method to get the underlying HTTPClient object for the service and use the HTTPClient class enableCaching method to cache the request.

ServiceRegistry.configure("yourService", {
     createRequest: function(svc:HTTPService, args) {
          svc.client.enableCaching(1000);
[...]
Note: Make sure to use getClient and any HTTPClient methods in the createRequest callback or later callbacks, not when you get the service object from the registry. This is because the underlying HTTPclient object isn't initialized until you call the service using the createRequest object. Before calling the service, using getClient only returns null.
Cached requests are seen in the dashboard and you should see lower average execution times once caching is enabled. Cached requests are counted toward rate limits, circuit breakers, and statistics, because all of these are measured at the service level and are triggered by calls to the service.

Changing or Extending the Web Service URI

You can change or extend the web service URI specified in the service configuration in Business Manager using the getURL callback.

Filtering Log Messages

You can use the FilterLogMessage callback to remove sensitive or private data from log messages. See Web Service Logging and Troubleshooting

Testing Web Services Using a Mock Response

You can mock web service responses in two ways.

Option 1: Configure the web service to use mock responses in Business Manager.

  1. Select Administration > Operations > Services. For the Service Mode, select Mocked.
  2. In the service registry, create a mockCall callback to call in mocked mode. For example, in your initialization script:
mockCall: function(svc:HTTPService, client:HTTPClient){
    return {
        statusCode: 200,
        statusMessage: "Success",
        text: "MOCK RESPONSE (" + svc.url + ")"
        };
    }

Option 2: Force a mock call, regardless of configuration:

You can add a mock method to your service definition and then call it explicitly in your web service script. However, you must then remove this method from your script when testing live web service calls.
result = ServiceRegistry.get("MyFTPService").setMock().call();

Next Step: Coding the Web Service Call