After talking at 2020 foss4g Italy event, I was asked to publish my slides, but, since they're in italian language I decided to write a little summary of what I talked about.
GIS web viewer share often a similar architecture.
As you can see from the image above a GIS (Web) Client is a bunch of html and js files which can handle access to some Web services standardized by the Open Geospatial Consortium. There are many FOSS projects out there providing common functionalities of a web viewer. Lower level ones like Openlayers or Leaflet, and some more engineered solutions like Mapstore2, Geoadmin or Geomapfish. What happens anytime a technology upgrade occurs on the client side?
The image above, describes the classic development lifecycle. What happens when we happen to be in the green phase (Evolution) and the evolution includes an important technology upgrade (for example like when you decide to rewrite your software in a completely different programming language)? Typically you may be able to reuse Requirement Analysis, maybe some design, but all the next steps will need a complete rewrite. What can we do when such an event occurs in the development of a GIS Web Viewer?
Well in my company we have setup a software solution in order to keep as much developed software as possible. The concept is quite simple. We have a three step process:
At configuration time, in a QGis project we handle the organization of the TOC and all the OGC services we want to use in our specific context. Then via a QGis plugin, we wil enrich the configuration model by adding informations about tools we may want to enable in that specific application (like features searching, graphics specifications, feature fusion, cutting, etc.). Then all this configuration data is stored in a DBMS via a REST API. The specific configuration is identified by a UUID that will remain the same throughout the technology upgrades.
As you can see from the image above, at configuration time we have set up our viewer context and stored it in the DBMS. When a viewer needs to access the desired configuration, it has to present itself by the corresponding UUID to its specific API. So what happens behind the scenes is a Model To Model conversion: from the ER model of the DBMS to the domain specific one of the requesting viewer. Furthermore, there's a Tools api which needs some more explanation. Tools are components with a specific configuration and an optional specific API. These objects are transversal to the frontend technology, so as the supported frameworks increase in number the available tools needs the only presentation logic to be reimplemented, while the backend API remains untouched.
So, what do we gain by approaching GIS viewers development in such a way? First of all the choice of using a Model driven development makes the whole ecosystem of configurations highly reusable (for example you may want to publish different viewers displaying the same configuration). Another interesting feature is that the modular architecture enables us to increase tools and features that can be added also to older configurations as long as they're made available to the ecosystem. And now some cons too. What we are doing here is some heavy integrating duties, that said it's obvious that choosing to support someone else work (a.k.a. FOSS framework and libraries) we have to compromise to some UX/UI choices that may not be suitable to every needs. But hey, there's plenty of them to choose from so that can be an opportunity to integrate one more community! And then the worst con IMHO: this approach leads to a highly configurable system. Which means that if you don't plan a heavy integration test plan you may occur in some serious problems (like setting up a viewer for production pointing to an internal API. Real sad story…)
We are planning to publish all this ecosystem under FOSS licenses in the next months in an incremental way. When all the documentation and the code will be available I'll publish a short recap. For now you can check our organization on github for some interesting FOSS projects.