Séparé!
En fait, j'aurais probablement trois référentiels, un pour le client et les bibliothèques client uniquement correspondantes, un pour le serveur (et les bibliothèques correspondantes) et un pour les bibliothèques partagées (incorporant les interfaces API qui exposent la fonctionnalité entre les deux , plus tout autre code partagé). Je pense que c'est vraiment la clé, le code partagé devrait aller dans un référentiel séparé. De cette façon, vous pouvez vous assurer que l'interopérabilité entre votre client et votre serveur est toujours à la même version ET est isolée de la conception de chacun de ses consommateurs.
Évidemment, cela n'est pas toujours possible, selon le cadre de communication particulier que vous utilisez, mais il y a probablement du code partagé qui dicte le format des objets de transfert de données ou les étapes de la négociation dans votre protocole personnalisé (ou un autre exemple) .
En supposant que vous avez une intégration continue et une configuration d'AQ assez décentes (une hypothèse assez large, d'après mon expérience, mais je vais néanmoins la faire. Si vous n'avez pas de service d'assurance qualité, vous devriez au moins obtenir un CI), vous ne devriez pas pas besoin d'utiliser le modèle de repo unique comme défense contre d'éventuelles erreurs de correspondance de code, soit votre serveur CI signalera l'interopérabilité de la bibliothèque, soit votre équipe QA détectera les erreurs d'exécution (ou, mieux encore, vos tests unitaires le feront).
Les avantages des référentiels fractionnés résident dans la possibilité de versionner séparément des parties distinctes d'un système. Vous voulez prendre une copie du serveur de la semaine dernière et l'exécuter avec le client de cette semaine, pour essayer de verrouiller la racine d'un problème de performances? Pas de soucis.