We're working with ASP.NET Core web API and looking for a couple of doubts that we have.

The versioning documentation recommended creating multiple controllers:

└ Api
  ├─ v1
  │  └ Controllers
  ├─ v2
  │  └ Controllers
  └─ v2_5
     └ Controllers

We faced difficulties and challenges to manages multiple versions in a single solution.

  1. There is a lot of code duplication
  2. There are many other things instead of just controllers, and if there is any change version specific, it becomes a puzzle.
  3. Even there is no change in the previous version, we re-deploying it with the newer version. Which could be error-prone.

Hence, we come with the solution to run separate instances for each version and use path-based routing using the application load-balancer.

enter image description here

This works fine, but the actual problem starts here on which we need help.

Assume that we're using the MSSQL server to manage the database. Now there is schema and SP changes into a newer version v1.1. Now, this becomes difficult as we have a single database and multiple versions to manage. Any changes into a newer version need to be compatible with the previous one; otherwise, an older version would break.

For example, we want to make mandatory phone-number for users while registering if they are using an updated app version(API version internally), so in schema level, we have to make it not null. But in this case, the older version would break. Thus we anyway need to make it nullable field.

So, here are the two main questions

  1. Which is the best practice to in case of DB changes.
  2. If we use separate databases with each version, how data of each version synced with each other?

Or any good recommendation to handle this situation; I am wondering, how these big app providers are managing app, API, and DB versions.

2 Answers 2

  1. If you want to maintain one database and support multiple API versions, then you should handle this kind of validations in API and model layer. Just before the request hits the DB. Leave the schema untouched and flexible as much as possible. Else, you will break the API for existing customers and you will be forced to migrate them (which no customer likes).
  2. If you use separate databases, then it is like a completely different application. No need to sync data across versions. You may still need migration tasks to move customers over to newer releases.

IMHO, it is better to go with #1 above. Interested to see what others think.

  • superb answer. thanks for writing. Commented Mar 8, 2023 at 4:27

Half of computer science problems are solved by introducing one more level of indirection. Here, we wish to distinguish between logical and physical implementation.

This comes up all the time. A logical www address might have multiple physical servers implementing it:

www.time.com.  IN  CNAME  time.com.
time.com.      IN  A
time.com.      IN  A
time.com.      IN  A
time.com.      IN  A

A logical pathname might be backed by "web2" or by a shorter "web2a" file:

lrwxr-xr-x  1 root  wheel  4 Oct 12 03:16 /usr/share/dict/words -> web2

The analagous notion for tables can look like

  SELECT * FROM users_v1_0;

And then a DBA could switch to a users_v1_2 table without changing a line of code.

But for your "transitioning" use case, we might wish to take advantage of UNION ALL:

  SELECT * FROM users_v1_0
  SELECT * FROM users_v1_2;

This presupposes that each user was enrolled exactly once, either during the v1.0 epoch or else when v1.2 code was running. We'll probably want another table on the side, with UNIQUE index, to enforce such constraint.

mandatory phone-number for users while registering if they are using an updated app version, so in schema level, we have to make it not null. But in this case, the older version would break.

I am proposing that the users_v1_0 table admits NULLs, and users_v1_2 would impose a NOT NULL constraint.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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