I learned the term Inner-platform effect the other day and it perfectly describes an API that I have touched upon.
First of all, what is the Inner-platform effect? It basically means that in attempt to make an application as flexible as possible it is implemented so that it creates a new platform that abstracts the original platform. I immediately associated to the API described below.
Let’s see if you can spot the Inner-platform effect in this URL, heavily anonymized but if you have been exposed to it you will probably recognize it immediately.
//server/execute/clientSystemConnector ?service=createUser&key=id&value=97580 &key=name&value=David%20Eriksson&key=city&value=Ronneby
There are actually three examples of the Inner-platform effect in the above URL. The first is example is the “service” parameter. Instead of having separate URLs for separate services, the service name is a parameter. This means that the server platform first figures out what to about the /execute/clientSystemConnector path component of the URL, then the Inner Platform need to figure out how to handle the different possible values of the service parameter. (Anyone thinking about a giant “switch” statement?) To avoid the Inner-platform effect, each service should have its own path in the URL.
The second example is blatantly obvious: having key and value parameters that specifies the names and values of the actual parameters. The impact of this “feature” is that the platform provides a list of keys and a list of values to the inner platform, which must extract the actual parameters for use in the application. Without the Inner-platform effect the application could have received the parameters directly from the original platform.
It is probably not so easy to spot the third example, but it concerns authentication. Authentication (if it could be called that) for the services in this API is based on using different paths for different clients. So the above URL is used by the “clientSystem”. If “anotherClientSystem” need to execute the same service, the URL would be:
//server/execute/anotherClientSystemConnector ?service=createUser&key=id&value=97580&...
So instead of using the built-in authentication mechanism (HTTP Basic Auth) in the platform, the Inner platform goes its own way.
How would I build an API to avoid the Inner platform? Except addressing the above issues I would also make it a POST (or PUT) request, as it handles the creation of a resource.
POST //server/user/create HTTP/1.1 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== Content-Type: application/x-www-form-urlencoded id=97580&name=David%20Eriksson&city=Ronneby
Goodbye, Inner Platform!
PS. The origins of the API is probably 8-10 years old by now, and maybe it was a good idea at the time.
PPS. See the Inner-platform effect article on wikipedia for more examples.
Isn’t the “create” part of the URL the fourth example? Why not just //server/user instead of //server/user/create and use the HTTP verbs to decide if its a createUser request?
POST //server/user (create a new user and let the API decide the id)
Then if you need support for “getUser”, “updateUser” or “deleteUser”, you have the possibility to use:
GET //server/user/97580 (get information about user with id=97580)
PUT //server/user/97580 (create, update or replace user with id=97580)
DELETE //server/user/97580 (delete user with id=97580)
Absolutely Per, much better!
My suggested version of the API did not take full advantage of the available HTTP verbs.
By the way Per, what is your opinion about the Inner-platform API above?