0

So I have been working on my mobile app for a while and it is live and in production.

Because we released the app prematurely and are continuously improving current features and making them more thorough it means at every version there's a high change that database schemas will change.

The problem that I have is:

how do I make sure that when 1.3 is released, all the users who still have 1.2 installed on their phone are still able to use the app without problem?

Whenever 1.3 is released, some API endpoint changes and so does the database schema underneath.

So when my mobile app running 1.2 makes a request to api/users/all:

// Instead of getting data like this:
users = [
 {
   name: 'John Cena',
   category: 'Professor'
 },
 ...
]

// The new data is like this:
[
 {
   name: 'John Cena',
   category_id: 4,
   category: {
     id: 4,
     name: 'Professor',
   }
 },
 ...
]

So now my mobile on 1.2 breaks because category is an object not a string.

I have tried to do research on backward compatibility but the material I find doesn't speak to the problem I have.

Solutions I have found:

  • Version your API
  • Version your DB schema and run update scripts

I do can add versioning to my API /api/v1.2/users/all but how does that help me with my data problem?

I have seen mentions of schema versioning or even database version numbers but I'm unsure on how to execute that concept properly.

I don't want to have ausers_v1.2 and users_v1.3 table.

If a new user signs up he will be inserted in users_v1.3 and users on 1.2 won't know of his existence and vice versa. Having different databases as well would be synonymous to the same problem.

  • Unless you want to force every single client to break and then upgrade, you have to design in some backward compatibility. When designing the new updated API, you design in backward compatibility for the existing clients that haven't yet upgraded. You detect that they're using the older API and you still support that older API. Newer clients use the newer API. There are no shortcuts here - break your existing clients or design in backward compatibility to still support the older API alongside the newer API. – jfriend00 Sep 15 at 3:48
  • 1
    FYI, your API should not be hard bound to the table design. You should be able to modify your table and still support the older API (by writing new code to make the older API work with the new table). – jfriend00 Sep 15 at 3:56
3

all the users who still have 1.2 installed on their phone are still able to use the app without problem?

Not being an expert of mobile dev, but it seem to me forcing updates is the regular workflow for phone apps in these cases, if such breaking change would happen the v1.2 should have a mechanism to refuse launching until it is updated. This is at least how I see it handled in major vendor apps.

Without such mechism, you are doomed to support old versions of the app for a very long time, as you would for any kind of long term native software (OS, web browser...), which is considerably heavier as a development workflow.

That being said, you seem to imply supporting both v1.2 and v1.3 API require data duplication if the underlying data model changes, which is very likely wrong. Your data model should be to some degree abstract in regard to how your endpoints serve data. You probably simply lack a translation layer in your backend.

Taking your example of data model migration, what you would do is change your v1.2 endpoint have code similar to this:

app.get('api/v1.2/users/all', (err, res) => {
    users = get_users_from_db();
    users.forEach(function(user, index, arr) {
        if (typeof user.category == 'object' && 'name' in user.category){
            user.category = user.category.name
        }
    })
    res.status(200);
    res.json(users);
    res.end();
});

The workflow is then as follow:

  • Test the api code to return v1.2 compatible data, with and without migration
  • Push to production
  • Migrate your data
  • Optionally, remove support for v1.2 data model by getting rid of the if, always replacing user.category and assuming a user.category.name.

Then you are done, your endpoint is serving 1.2 api with 1.3 model. Translating data in your backend is how you should be maintaining old APIs compatibility while still moving forward with your data model.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.