I need some best practices or experiences of developer teams who had to treat the same issues I have at the moment =)
Our company is developing a client software for years. The one and only dependency was to have an appropriate database. With each release (update) we also update (incremental) the database if necessary. The versioning schema is well-established and matches our ideology.
Now we have started developing mobile applications (act as external client). Some preliminary remarks to our architecture:
The interface between the mobile client and the database (same database as for the desktop client) is a RESTful webservice. The versioning of both clients are independent. One application is maintained by the desktop development team and the mobile part is maintained by another team.
But I don’t know how to handle the webservice. Should it be independent as well (own versioning) despite the fact that it’s using a lot of shared libraries which are maintained by the desktop development team?
How it works:
The mobile client synchronizes it’s reference data with the webservice which interacts live with the database (read-only access to database).
User data which are produced on the mobile application become also synchronized with the webservice but it’s written to some persistent temporary tables. And an asynchronous job will be started to try the import to the database (could fail in case of locking issues, permissions, ….). If the import fails the same import procedure can also be started on the desktop client (they use the same library for importing from temporary tables to the specific ones)
In general each of these three parts could change (e.g. bugfix, features, performance improvements) without affecting the other two. Therefore I need a strategy to deploy each by itself. Nevertheless most probably it will affect two of three.
Where / when should i check if all three systems are compatible? How should I check this? Having a table in the database with every single possible combination of version which work together?
If you don’t understand my question because it’s entirely ambiguous, please let me know. It’s not that easy to describe =)
1
Should it be independent as well (own versioning) despite the fact that it’s using a lot of shared libraries which are maintained by the desktop development team?
IMHO there are 2 possible models here:
-
The Web Service is seen as part of the desktop application and gets the same version number.
-
The Web Service is seen as a separate application, gets it’s own version numbering (and you have to keep track which WS version numbers match the application & database version number)
Model 1 is fine when your REST API is very stable and does not change very often, and you want to provide a new WS version every time you create a new version of your desktop application & database. That will typically include a new deployment of the WS whenever you deploy a new version of the main application. This may also imply a new release (and deployment) of the desktop application whenever you have to provide a bugfix for the WS. The latter can be avoided if you use a versioning scheme like “major.minor.patchlevel”, where only “major.minor” is equal for WS and desktop app/database, whilst the patchlevel is allowed to be different as long as arbitrary patch levels of your desktop app/database and your WS can work together. Such a versioning scheme is a “light version” of model 2..
Model 2 is better if the WS has a completely different “release cycle” as your application & database. For example, when you change your REST API much more often than the rest of the application (sounds unlikely), or when most application & database changes don’t affect the webservice, and you just don’t need to supply (and don’t want to deploy) a new WS version. This can also depend on who is developing the WS: if you have a separated team on this, it will be likely that they demand to have their own release cycle to get things done (see Conway`s law).
When your web service shares a lot of libraries with the desktop application, I guess it’s more likely that you want to deliver a new WS version whenever you provide a new desktop application’s version (model 1), otherwise you get a bunch a different versions of the same libs in production, which increases maintenance complexity.
Where / when should i check if all three systems are compatible?
Let the WS check if the database has a version number he is compatible with whenever it connects the db. In model 1 that should be simple, in model 2 you need a list of version numbers of the database he can deal with (this list must be integral part of the WS installation, so it can’t be messed up by a wrong deployment).
The mobile applications should also check if the REST API provides everything they are expecting. They could either contain an explicit version check (and stop working, or demanding an update, when the WS version is too old or too new), or individual checks for different REST api features, with different behaviour when some features are missing. What’s best depends a lot on how the REST API looks like, what your users expect, how you deploy new versions to the mobile devices etc.
It may be a good idea to keep new versions of the REST API downwards compatible to older versions (if possible without too much headaches), and use the WS as a point where the mobile applications’ version become decoupled from the versioning of the other system’s part.