19

I have a logistical question: I'm trying to figure out the best way to manage APIs getting out of sync with an app. The best way to explain it is with an example:

Let's say MyApp Version 1.0 posts to a "submit_feedbacK" API that requires first_name, last_name, and email.

I then submit MyApp Version 2.0 to the App Store. That version is designed to post first_name, last_name, gender, and email to the API. All of these are required fields on the API.

The problem I have: - If I update the API before the new App is live, it will break Version 1.0 - If I wait until Version 2.0 is live and remotely cripple 1.0, I have to time it correctly.

I'm going to guess that the 'right answer' is to maintain two different APIs. But if both APIs post to the same live database, that makes things a bit awkward.

Does anyone have suggestions on how to model this?

Anthony
  • 5,275
  • 11
  • 50
  • 86
  • 2
    I believe the general idea is to try and design the API and database structure so it won't need breaking changes for a while to minimise the net total of awkwardness. If the value of `gender` wasn't absolutely necessary throughout the lifetime of 1.0, you can probably make do without the users who haven't updated yet submitting it during the version transition as well. – millimoose Jun 27 '12 at 00:16
  • That's true - the new field could also default to "male" if a value isn't provided, since the legacy app wouldn't provide it. I think I'm more concerned about complex changes, like if a concept needs to be re-approached. But like you said, if major changes are kept rare, the rest can probably be addressed through down-time announcements. I also just remembered that it possible to choose when an app goes live, so that will help with controlling updates. Anyway, thanks for the feedback! – Anthony Jun 27 '12 at 03:02

3 Answers3

8

This question may share some aspects with iOS consuming API design.

The right answer is definately to provide two APIs (at least for a short period of time while users adjust). You do not have to maintain two versions at the same time, as once a newer version is released you can maintain that one, and simply provide the old one for legacy users. The only real changes you may have to make to it are things like security patches or major issues. Major changes (such as you deciding to restructure your entire database) may lead to the old version not working any more, however update to newer API versions should be designed to allow previous versions to still function.

The other question I linked you to gives an answer about how you can have different version of your app access the correct version of the API.

Another note is that it may be easier for you (depending on what framework you're using) to design your APIs as engines or subapps, and simply mount them at different end points. I know that this is easily do-able in Rails by using Engines, and in Node with Express using app.use() with sub-applications.

Community
  • 1
  • 1
Nick Mitchinson
  • 5,452
  • 1
  • 25
  • 31
0

I would use a webservice/http endpoint for the communcation with your app. If you preferer to maintain the same URL in all versions of the app, then include a version number in all the requests/posts to the server so it knows how to handle them. This will also make the development and tests easier as new versions can test against the new api on the server.

So on any function you can call in the webservice/server add a single variable with version number. a BYTE ought to be enough as I think you could start over and "kill support for v1.0" once you hit 256 versions of the same function (if ever).

Once the server receives a request/post with data, you can just code a simple switch/case structure in the server API so support works for both versions.

If they do similar, but eg. swaps the parametres or something, you can handle all these serverside and the BAL/DAL (n-tier structure) can be maintained on the server part of the solution.

Btw. my answer is not just for iOS or smartdevices, but merly a client/server approach for a "work-in-progress" production setup where everything has to be online, while still being under development and maintanance.

Hope it makes sense, otherwise, comment on it and I shall try to explain it further.

BerggreenDK
  • 4,915
  • 9
  • 39
  • 61
0

just FYI, I use CodeIgniter. I'm using the REST Controller provided at https://github.com/philsturgeon/codeigniter-restserver. I ultimated ended up settling on having different end-points for every version. Basically I'd check out a new repository for each release and put it into a unique directory. (i.e. http://www.mysite.com/1.0/api/method, http://www.mysite.com/1.1/api/method, etc) Trying to maintain multiple versions of an API under one code-base just sounded too scary. At least when I released a version, I would know it is locked in stone and I don't have to worry about breaking it. (Note: I had to use a special .htaccess tweak to get multiple CodeIgniter instances running from the same domain. I can share it if you like)

Anthony
  • 5,275
  • 11
  • 50
  • 86
  • You're saying that when you release a version (say, 2.0), you effectively fork your 2.0 into a new repo for 2.1? This approach seems to give a final result similar to sub-apps/engines – Nick Mitchinson Mar 11 '13 at 23:55
  • Exactly. I thought about trying to keep it as one big codebase, but the question I posed was: When I have 100 versions of this API (1.0.0, 1.0.1, 1.0.2, 1.1.0, etc..), do I really want to have all of those versions in one giant codebase? The simple answer was no - that'd be a nightmare. Better just to fork each API and tuck it away so I don't have to worry about damanging it. Each app release can point to its own specific API and not worry about preceeding or future versions, unless I purposely disable one and force people to migrate to the latest app. – Anthony Mar 12 '13 at 05:30
  • Versioning the database is still an issue, but I've found that almost all of my DB changes add columns. Not many change the structure of what I've already done. If that's the case, then it is time to consider that change a new type of model, like "user_v2" and migrate old data to the new structure. Anywho, that was my approach. – Anthony Mar 12 '13 at 05:31