Search code examples
firebasegoogle-cloud-firestoreapi-versioning

Best practices of versioning with Firestore backend


With classic REST apis it is good practice to add a version to the api url. This version can be fi. embedded in the path (api.myservice.com/v1/dataset) or as a parameter (api.myservice.com/dataset?v=1). When a new version of the api is deployed, it can live side by side with the old version as long as it is needed. Old versions of the API can be marked as deprecated and can be removed eventually.

This gives the frontend a grace period to adapt to the new version of the API, so there is no downtime between an update of the backend, adapting this by the frontend dev and updating by the frontend user.

When we use Firestore or any similar realtime database, the frontend can have direct access to the database. The structure of the database can change, columns or tables can be renamed, moved or deleted. There is no API that abstracts this underlying structure for the frontend. So, what is the best way to add some kind of versioning to frontend - backend communication using realtime databases?

Possible solutions:

  • Use a REST api anyway as an extra layer with a version included. Disadvantage: with this approach you lose the advantages from a realtime database, such as realtime updates and user management.

  • Move the abstraction layer to the frontend and expose a minimum required version. If the frontend does not meet this version, the frontend is forced to update. Disadvantage: the frontend is trusted to do the right thing, instead of enforcing it.

  • Add the version to the project name or the table names. This will result in a lot of extra redundancy, where data have to be kept in sync constantly. This may lead to extra costs and is prone to errors.

  • Any other?

Neither of these options seem like good ideas to me yet. What will be the best solution if a frontend has direct access to the data? I'm aware that this question can be quickly be flagged as 'too broad'. If it is, please advice me how to focus my question.


Solution

  • The typical approach I take is to put a version number of the data model in the database. Whenever a schema change to the database is required, I check if it can be kept backwards compatible. If not, increment the version number.

    Either way, the schema is encoded in the security rules of my database. This means that there's no way for a client to write invalid data, as it will be rejected by the security rules.

    The clients read the version number, and show a Please upgrade when the version number is higher than what they were built for.