Our Generic Service Interface (GSI) represents a convenient way to connect to Service Objects products via an API interface. In particular, it facilitates retrieving data via SOAP without having to do reprogramming when new features are added from our end. It is now available in some of the new services we offer such as DOTS Address Detective International and DOTS Address Geocode International, and this article discusses how to integrate it with your applications.
When clients are connecting to our APIs, they most often choose GET requests as their preferred way to get their data validated. RESTful services are far and away the most popular way to connect to our services, but we do end up seeing a few inquiries to connect to our services via SOAP. SOAP was very popular in years past, but has seen a decline in popularity among developers since the rise of RESTful ways to connect to APIs.
One of the downsides (or upsides depending on your perspective) of SOAP is the strict data contract that it requires the server and client to adhere to when sending and receiving data. This can be an issue for us at Service Objects, because we are constantly updating our services and oftentimes with traditional SOAP calls, these updates require our services to return some new values or fields to provide new information. Adding these fields to an existing operation in one of our APIs would break the typical SOAP data contract and cause quite a few headaches and gray hairs from developers trying to keep an application working.
Traditionally, adding output values to one of our services with a typical SOAP contract would essentially require a new endpoint and operation for clients to hit. This would require clients to put in development time to hit this new endpoint. But our developers are a creative bunch, and they have found a way to update and add features to some of our services while continuing to uphold existing data contracts held in place by SOAP. This is how GSI came into existence.
What is special about the GSI?
The GSI is basically an array of Key Value pairs that our service returns that allows the structure of the service to be flexible and add new values, but still keep the output structure on which SOAP relies. So the output structure of the SOAP request will look different from the GET output response, but all the expected values will be present in the response. With most things, it’s easier to show what this looks like rather than describe it.
For this example, we’ll be using C# and our DOTS Address Geocode International (AGI) to highlight what integration may look like. The actual syntax of integrating will differ by development language and service you use, but the idea should be the same. Should you run into any difficulties, we’re happy to help troubleshoot and get you up and running.
To start, we’ll need to add a service reference to a C# project that will build the necessary classes from the WSDL definition that will allow us to call the AGI service. To do this, right-click references and select “Add Service Reference”. In the dialog that pops you, paste the WSDL URL into the address field and give an appropriate Namespace.
Select OK to create the service reference.
Calling the Service
To call the service, you’ll need to create the SOAP client object along with the response object. We’ve just used a simple console app for this project, so we’ll use our office address as the example. Setting up the call to the service should look something like the following:
With any integration, we always recommend making sure failover is properly setup. To check for conditions where failover should be called, we recommend checking if the response object is null or if the response contains a fatal error, which is designated by a TypeCode value of 3.
When these conditions are met, the code will throw an exception and a call should be made to the wsbackup.serviceobjects.com endpoint. To do this a string can be passed into the SOAP client constructor that corresponds to a web config entry as shown below.
Note: If you are using a trial key, the primary WSDL and endpoints in the webconfig will have to point towards trial.serviceobjects.com
Processing the Response
Now that the service has been successfully called, let’s do the exciting work and actually process the response object. We accessed the error object when checking for a fatal error above, but we’ll go ahead and process the expected output values.
For any response that AGI returns, its safe to assume that the SearchInfo object will be returned in the response. The SearchInfo object will hold a Status field that will give a piece of text that will give high level information on how the record was processed. Please see the developer’s guide for all possible values the Status field can return.
To access a nested object in the response, simply pass in the name of the object followed by a 0 indexer and then the name of the property to be displayed. Below, we’ll access Status and NumberOfLocations, as these can be reliably returned and won’t be null.
Other fields in the SearchInfo object may not be present in the output response, so we recommend checking to ensure that the desired keys are present within the output. Something similar to what is shown below would be a good null check for these values.
All of the other fields in the service can be accessed much in the same way. The above method can be used the LocationInfo* objects that are returned. One thing to note is that the NumberOfLocations field will be important in determining how many LocationInfo objects will be present in the response. For example, if NumberOfLocations is equal to 3 in the SearchInfo object, then there will be 3 of the LocationInfo objects present in the response with keys Locations1, Locations2 and Locations3. This will be helpful for knowing how many LocationInfo objects are present in the response and allow you to target specific response objects.
Below is an output of the debugger in Visual Studio when searching the city “Venice” with the country input as “USA” in the PlaceSearch operation. This is a limited location search, and as such many different location objects will be returned. Note that there are 10 LocationInfo objects and the NumberOfLocations returned is equal to 10.
As you can see, the LocationInfo key values range from Locations1 to Locations10 to reflect the number of locations indicated.
*Note: the LocationInfo object described in the developer’s guide notes a nested object called AddressComponents. In the GSI, the LocatoinInfo object will be flat so the AddressComponent values will be in the LocationInfo object.
Iterating Through Returned Objects
One of the nice benefits of the GSI is that it provides an easy way to iterate through all the values in each object of the response. Using foreach statements in C#, that would look like the following:
In the above screenshot we exclude the SearchInfo object, which contains the Status and NumberOfLocations info and proceeds to iterate through all the LocationInfo objects returned and then write all the containing key values pairs to the console. Obviously, you would want to do something a little more advanced than simply display the values to the screen. From here, you can create and fill your own custom objects, write these values to a database or use these values in an UI element.
The individual elements in the LocationInfo objects can also be accessed much in the same way that the SearchInfo objects were accessed above.
While integrating with the GSI might take a little more work to get started with, it does allow us and our clients to easily get updates from the service when we push out new features to our services.
With any integration, there are always “gotchas” and other things to account for that may not have been mentioned in this tutorial. Please reach out to us! We have a team of engineers that are ready to help with whatever integration needs you have.