The Design of Web Service Applications and Performance

4 minute read time.

My hope is that if you have attended any of my presentations about the Web Services interface for Sage CRM you will have taken away with you an impression of the importance of the design of the client application and how this would affect performance.

The source code for the sample application which I use for my training session is available to be downloaded from the resources section of this website and shows how to code using the different exposed methods and objects.

General Observations about Web Services

It is a fair generalization to say that web Service requests are considerably slower than the equivalent COM or .NET requests. This may not matter when only small messages are sent. But Web Services are XML based. This is both a strength and a limitation. The messages in XML that are passed are easy for humans to read, but are verbose. COM has a much smaller binary message format.

SOAP overheads include: extracting the SOAP envelope; parsing the contained XML information; The XML parser will also have to carry out type checking and conversion, wellformedness checking, or ambiguity resolution, and this all affects speed. The Web Service SOAP messages move much more data than the average HTTP GET or POST call, adversely impacting network performance. Repeated SOAP-client calls to access the server could start to degrade the performance. So you may have to consider the design of the web service client application.

There are a range of factors that will affect performance such as: web server response time and availability; client application execution time; database views and indexes that are implicitly referenced in CRM. The creation of views are discussed elsewhere on this site.

The application design is critical. You have to design a web services application from the priority of performance.

General Transaction and 'Session' Design.

I have found even when in a straight forward teaching environment a strong difference can be demonstrated between a system that has to logon, do a task, logoff and one that maintains a session.

The Logon and Logoff methods generate quite a bit of SQL and so take this time. If you open the SQL Logs you should be able to see the hit in terms of the web service logon and logoff. When a session is created then at least half a dozen SQL statements are generated. These are mainly select statements but some are updates which are used to assemble the users security rights as well as updating information on the users table. When a web service user logs off this also creates 3 or 4 update and select SQL statements.

So depending on what you are needing the web service application to accomplish the basic design that you follow could have unnecessary inefficiencies if you have it perform a login, and a log off, any time you want to access anything from the CRM system.

If you are using the web service to carry out an autonomous action, like uploading a piece of data from a program, and then stopping. You should login, do it and log out.

If you are accessing the system to carry out a number of actions in quick succession, on one screen, or as part of one business process, like setting up a customer, You should log in, get the session id, keep that session id and use it for all actions within that business process, and then log out when you are finished.
By doing the later you will save time on the login and logout which could be a second or more each depending on the network, traffic etc., on each action within the business process.

Comparing the Main Query Methods

The Sage CRM web services interface have a range of method to allow for data to be retrieved but if you use the wrong one for the wrong purpose then you can severely impact performance because these then interrogate the database and assemble the XML in different ways. The main choice of query methods are: queryentity(), query() and queryrecord().

The recorded developer training sessions are pretty clear about the usage of each method.

  • The queryentity() method returns the entity e.g. Company with all its subordinate data (All the Persons, All the Addresses, All the Persons' Addresses, All the Phone Numbers for both the Company and the listed Person records etc). Because this is retrieving a single entity like the Company Gatecom, the load of retrieval is not too bad and speed of getting Gatecom's data up in the web services test harness project is about the same as retrieving Gatecoms details in the main interface.
  • The query() method returns the set of entities with all their subordinate data. So if you ask for all companies being with 'A' then you will have to wait a long time as the SQL is fired and the response XML is assembled. Compared with the main interface this method is excruciating and should only be used in very particular circumstances.
  • The queryrecord() method allows you to specify the fields returned in the XML and will only return data for the table referenced and not the subordinate records. So a QueryRecord run against the company table will not retrieve person or address info. This is the preferred method for getting specific data back quickly.

But you also need to consider other ways of identifying records that you need to work on. For example the queryid() and queryidnodate() methods allow you to get lists of record ids that match your criteria and to then use with the queryrecord or queryentity methods.