Tuesday, March 25, 2008

Pragmatic API design

In a comment on a previous post, Carfield Yim suggests an alternative style for API requests. We could dub this the URL-encoded style, since the content type associated with the request format is application/x-www-form-urlencoded. (Carfield's example involves updating a user's name, so the hypothetical service ought to require that the request be submitted using HTTP POST method rather than GET, since the action is unsafe.)

There is eternal debate in the software and web communities on the question of what APIs should look like, involving an acronym soup of terms such as SOAP, REST, SOA, POX and ROA. Without invoking too many buzzwords, we can observe that the following are both desirable properties of real-world APIs.

  1. Support for invoking an operation, and viewing the response, directly in a browser. Typically the requests would need to be submitted using an HTML form. This can be very useful to a developer trying to make use of the API, since it becomes incredibly easy to test its behavior. Learning by experiment is often easier and more effective than reading a specification.
  2. Reuse of existing data formats. For example, one of the examples in the original post was concerned with creating a user account in EKP. The body of the request message contained CSV data in the format EKP expects for files uploaded using the User Data Loader. Hence, if an organization has already written code to generate data in that format (extracted from their HR system for example), it needs relatively little work to switch between either generating files for manual upload, or submitting the data directly using the API. On the other hand, the application/x-www-form-urlencoded content type isn't normally used outside of HTTP requests.

(In passing, it's worth noting that SOAP does not satisfy either of these requirements particularly well. It fails completely with the first. As for the second, it's reasonably easy to reuse an existing format if it is XML-based and literal encoding is used rather than SOAP encoding. On the other hand, using a format that is not XML-based—because it predates XML for example—typically requires sending the data as some kind of SOAP attachment, which raises a whole other set of issues.)

In some cases, support for batch operations might also be a requirement. For example, if I need to update 1,000 user records, this will be considerably more efficient if the data can be sent in a single request. If 1,000 separate requests are required, then network latency will become a serious concern. (However, HTTP pipelining could help if supported.)

As I see it, the URL-encoded request style meets the first requirement (it supports invocation from a browser), but fails to meet the second (it fails to reuse an existing data format for the request) and third (it is not well suited to batch operations). On the other hand, the CSV request style described in the original post fails to meet the first requirement, but meets the second and third. This seems like a reasonable trade-off in this case. However, the URL-encoded style seems like a reasonable approach in cases where support for large batch updates isn't a critical requirement, and there isn't an existing data format that obviously matches the desired content of the request message.

1 comment:

Anonymous said...

The fact is, SOAP is the way the software industry has gone and there is a huge amount of tooling and reference resources that make it relatively easy. Furthermore it's a skill-set that anyone engaged in integration projects is likely to need and have. Using lower-level techniques such as HTTP POST with an authentication header is not simple in a cross-platform/cross-language project, whereas I've mixed and matched Java, C# and PHP applications via SOAP with remarkable ease.

I look forward to the day when EKP exposes its APIs via SOAP. It would certainly make my life easier.