views:

19

answers:

2

We have restful api over HTTP. Amongst other clients we have also mobile-device clients (e.g. iphone). The issue is that there are several iphone apps in different versions out there (1.0, 2.0). Because they are distributed we don't have control which app-version is calling us.

To identify the app-version on server-side I see following options:

  1. device must append URL parameter (e.g. /foo?iphone-app-version=1.0) : A bit yucky, but good thing is that I can see it always on server-logs (URL is always logged)
  2. we authenticate api-clients with HTTP digest. We could encode the app-version inside the username (e.g. iphone_1_0): Good thing it is logged in server logs, but only works for resources which are exposed as HTTP digest.
  3. device must use custom HTTP-header, e.g. X-IPHONE-APP-VERSION: In my view the cleanest approach, but we don't log HTTP headers in server logs (for log-noise it is switched off). So later analyzation is not possible.

Do you have a preferred approach or any other alternatives?

EDIT: With above versioning I don't mean api-versioning/content-negotiation. It is the version of the mobile-device.

+1  A: 

You can use the Accept-Header to allow a client to declare what capabilities it has by identifying what versions of media types it supports. e.g.

mobile app does:

GET /server/foo
Accept:  application/vnd.acme.fooappV1+xml

When you introduce new features that are not backward compatible you can tell the new updated clients to send,

GET /server/foo
Accept:  application/vnd.acme.fooappV2+xml

Then your server knows the capabilities of the client it is talking to. You could also get the new clients to do this:

GET /server/foo
Accept:  application/vnd.acme.fooappV1+xml, application/vnd.acme.fooappV2+xml

That way you can migrate your server resources over to the new format slowly. If the endpoints deliver application/vnd.acme.fooappV1+xml then the client will revert back to the old way. If the endpoints return application/vnd.acme.fooappV2+xml then the new code can take over.

Using this approach, no URIs need to be changed, so bookmarks and statistics remain valid. Migration to a new format can be done incrementally over time and support for old clients can be gradually phased out.

Darrel Miller
there is already versioning concept (both through headers and perma-link). What I need is to identify the mobile-device app version. This version is different to the api-server version. Motivation is to know which app-releases/versions are used by the end-users.
manuel aldana
@manuel Isn't that what the user-agent header is for?
Darrel Miller
yes, this could fit (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43). So far I've only seen this header to identify the "connection builders" (e.g. firefox, http-commons client). I will have a look what User-Agent entry iphone currently is sending. Maybe I'll just append the app-version-fingerprint to it (this would be similar to mentioned X-IPHONE-APP header). The drawback still is that I cannot see it inside production-pattern logs because it is not included inside permalink. So still any statistics from past logs won't work, only temporary switched on header-logs will show.
manuel aldana
I decided against User-Agent header but for a custom X-xxx-USER-AGENT one. Main reason is that User-Agent is already "polluted" with http-client library or mobile-device information. A custom X-xxx-USER-AGENT is easier to parse for server and does not intervent http-library which often sets it and could override a custom entry.
manuel aldana
A: 

I decided for custom X-xxx-USER-AGENT one. Main reason to decide against more standard "User-Agent" is that is already "polluted" with http-client library or mobile-device information. A custom X-xxx-USER-AGENT is easier to parse for server and does not intervent http-library which often sets it and could override a custom entry.

manuel aldana