11. September 2010

Service URLs should be Immutable

Service URLs are URLs where you (the client) expect a service. No surprise. Examples:

  • the URL of a SOAP WSDL is a service URL,
  • the REST URL of the Twitter timeline API: http://twitter.com/statuses/friends_timeline.xml,
  • name or URL of AJAX scripts of a web site,
  • a chat room URL provides a software bus service.
These service URLs are provided to the client. Usually they are configured. The client gets them somehow. The client uses them to access the service. BUT the client should never construct them or append to them or change them. Service URLs should be final.

Why? I don't know, but I feel, that it is a bad thing. I had several cases in real applications where constructing, appending to, manipulating service URLs made an application less extensible, more complex, less testable.

Extensibility: if the client constructs the service URL from parts, then future server changes must take the client URL construction into account. The server can not just supply a different service URL, because the client also does something and might prevent the server from changing the service URL stucture or the URL altogether. For example, if the client appends the path of a URL to a host name and if the client assumes, that the server language is PHP, then the service URL might always look like a PHP script, even if the server technology changes. Imagine the unfortunate sysadmin who has to configure a Java application server to serve ".php" URLs. The client will have to be changed when the server changes. This is bad.

Complexity: Constructing URLs in the client is more processing than doing nothing. It introduces IFs, methods, more constants. This is usually not a big issue, but it rare cases the additional complexity can be quite significant. I have seen these cases.

Testability: Service URLs point to resources. Resources are dependencies. A very important concept of unit testing is inversion of control by dependency injection. But if the client generates its dependencies, then inversion of control is more difficult, if not impossible. It is much better to let the server be in control by configuring the client for production and test cases.

Do not...
  • combine host name and path to URLs
  • append or decide on filename extensions
  • append query parameters
  • decide the protocol
  • insert or remove port numbers
...in the client. Just leave it as you get it. The server knows what's good for you.

Exceptions: however, you may...
  • decide the protocol (http vs. https) in AJAX clients for JS security reasons,
  • replace query arguments by treating the service URL as a template,
  • append URL parameters if (and only if) the service protocol consists of URL parameters (thanks Allan)
  • (any other exceptions?)

1 Kommentar:

Allan Wegan hat gesagt…

"Why? I don't know, but I feel, that it is a bad thing."
You know it. You wrote it all down below that statement - and you are right. ;)

For parameters there is an exception: For requests delivered to the service using HTTP GET, i would expect the data to be appended to the service URL.
It is possible to use templates here. But just appending the parameters is simpler. And you can append a version identifier too.