goes
Aggregates, commandes et projections typés — du prototypage à la production.

Qu'est-ce que goes ?
goes est un framework d'Event Sourcing pour Go qui fournit les composants nécessaires aux applications distribuées et pilotées par les événements. Aggregates, commandes et projections typés — avec des backends interchangeables pour chaque niveau de montée en charge.
Contrairement à de nombreuses bibliothèques d'Event Sourcing, soit trop académiques soit trop directives, goes s'appuie sur le Go idiomatique. Aucune génération de code, aucune annotation magique — seulement des interfaces, des generics et de la composition. Vous définissez vos aggregates comme des structs Go ordinaires, enregistrez les gestionnaires d'événements via des fonctions typées, et le framework gère la persistance, la relecture et la concurrence.
goes s'adresse aux équipes Go qui souhaitent intégrer l'Event Sourcing et CQRS dans des systèmes existants ou nouveaux, sans être liées à une infrastructure spécifique. Que vous commenciez avec un simple prototype en mémoire ou exploitiez un système distribué avec NATS, MongoDB et PostgreSQL, la logique métier reste identique.
// Define your aggregate type Order struct { *aggregate.Base Items []LineItem Status OrderStatus } // Register typed event handlers func NewOrder(id uuid.UUID) *Order { o := &Order{Base: aggregate.New("order", id)} event.ApplyWith(o, o.placed, "order.placed") event.ApplyWith(o, o.paid, "order.paid") return o } // Produce events from commands func (o *Order) Place(items []LineItem) error { aggregate.Next(o, "order.placed", OrderPlaced{Items: items}, ) return nil } // Rebuild state from events func (o *Order) placed(e event.Of[OrderPlaced]) { o.Items = e.Data().Items o.Status = Placed }
Aucune génération de code, aucune annotation — seulement des interfaces Go, des generics et de la composition. La logique métier reste propre et portable.
Pourquoi l'Event Sourcing ?
Le problème
Les systèmes CRUD traditionnels ne stockent que l'état actuel. Lorsqu'une erreur survient ou qu'un audit est requis, l'historique manque. Les données sont écrasées, le contexte est perdu. Qui a modifié quoi, quand et pourquoi ? Ces questions ne peuvent pas être résolues avec une instruction UPDATE classique.
L'approche
L'Event Sourcing stocke chaque changement d'état comme un événement. L'état actuel est reconstruit à partir de l'historique des événements. Rien n'est perdu : pistes d'audit complètes, débogage dans le temps et possibilité de construire rétroactivement de nouveaux modèles de lecture à partir d'événements existants. Votre journal d'événements devient la source unique de vérité.
Ce que goes fait différemment
goes élimine la complexité de l'Event Sourcing en Go. Aucun boilerplate, aucune DSL — uniquement des interfaces Go et des generics. Vous commencez avec des backends en mémoire et passez à MongoDB, PostgreSQL ou NATS sans modifier une seule ligne de code métier. Le framework gère le routage des événements, l'hydratation des aggregates, la gestion des snapshots et la planification des projections. Vous vous concentrez sur votre domaine.
Le pipeline d'événements
Chaque changement d'état passe par un pipeline clairement défini. Les commandes déclenchent la logique des aggregates, qui produit des événements. Les événements sont persistés et projetés dans des modèles de lecture.
Concepts clés
Aggregates basés sur les événements
Intégrez le type de base, enregistrez des gestionnaires d'événements typés. Le framework gère le versionnage, la persistance et la relecture. Les aggregates sont des structs Go ordinaires avec un aggregate.Base intégré. Les gestionnaires d'événements sont enregistrés via une fonction generic et appelés automatiquement lors de l'hydratation. Les suppressions logiques, le versionnage des aggregates et le contrôle de concurrence optimiste sont disponibles immédiatement.
Événements distribués
Publiez et abonnez-vous aux événements via NATS JetStream. MongoDB et PostgreSQL comme Event Stores. Échangez les backends sans modification du code. L'Event Bus abstrait le transport et la livraison. Votre code travaille avec des événements typés, qu'ils soient locaux, dans le processus ou distribués sur un cluster.
Commandes typées
Distribuez et traitez des commandes avec une sûreté de type complète grâce aux generics. De manière synchrone ou asynchrone, selon le cas d'usage. Le Command Bus prend en charge les middlewares, la propagation du contexte et la gestion des erreurs. Les commandes asynchrones sont distribuées via l'Event Bus, les commandes synchrones directement dans le processus.
Boîte à outils de projections
Construisez des modèles de lecture avec des planifications continues ou périodiques. Suivi automatique de progression, anti-rebond et rattrapage au démarrage. Les projections peuvent lire depuis n'importe quel Event Store et écrire dans n'importe quelle base de données de lecture. Le planificateur gère les nouvelles tentatives en cas d'erreur, le backoff et un traitement garanti.
Registre de codecs
Mappez les noms d'événements aux types Go pour une sérialisation automatique. JSON par défaut, MessagePack ou Protobuf via un changement d'une ligne. Le registre de codecs est central pour une gestion d'événements typée. Il garantit que les événements sont correctement sérialisés, désérialisés et versionnés.
Snapshots
Capturez l'état d'un aggregate à un moment donné. Rejouez uniquement les événements récents au lieu de l'historique complet. Les snapshots sont créés automatiquement selon des intervalles configurables. MongoDB, PostgreSQL et les stores en mémoire sont pris en charge, avec la même architecture de backends enfichables que l'Event Store.
Testable par conception
Assertions de test fluides pour les aggregates, backends en mémoire pour les tests d'intégration et suites de conformité pour les implémentations personnalisées. Le package de tests propose des assertions de style Expect : given Events, when Command, then Events. Les suites de conformité garantissent le comportement correct des implémentations personnalisées d'Event Store.
Conception modulaire
Utilisez uniquement ce dont vous avez besoin — système d'événements, commandes, projections — et ajoutez d'autres composants selon vos besoins. Chaque package dispose d'interfaces clairement définies et de dépendances minimales. Vous pouvez intégrer goes progressivement dans un projet existant, sans devoir tout adopter en une fois.
Backends prêts pour la production
goes suit le principe des backends interchangeables : chaque Event Store, Snapshot Store et Event Bus implémente une interface commune. Vous développez contre des abstractions, pas contre des implémentations. Cela permet de tester localement avec des backends en mémoire, d'utiliser MongoDB en préproduction et de passer à PostgreSQL avec NATS en production, sans modifier une seule ligne de code métier.
MongoDB
Event Store basé sur des documents avec prise en charge native des Change Streams pour les abonnements aux événements en temps réel. Idéal pour les architectures pilotées par les événements, où les projections doivent réagir en temps réel aux nouveaux événements. Prend également en charge les snapshots et la concurrence optimiste via le versionnage de documents.
PostgreSQL
Event Store relationnel avec transactions ACID et contrôle de concurrence optimiste. Parfait pour les équipes disposant déjà d'une infrastructure PostgreSQL et ne souhaitant pas introduire d'infrastructure supplémentaire. L'isolation sérialisable garantit des flux d'événements cohérents.
NATS JetStream
Bus d'événements distribué avec livraison au moins une fois, groupes de consommateurs et mise à l'échelle horizontale. NATS convient particulièrement aux architectures de microservices où les événements doivent être distribués entre les services. Persistance via JetStream, relecture via les offsets des consommateurs.
En mémoire
Backend sans configuration pour le prototypage et les tests. Même API que les backends de production, afin que les tests et prototypes utilisent le même code qu'en production. Aucune configuration, aucune dépendance, prêt immédiatement.
Architecture de microservices
goes constitue l'épine dorsale des systèmes de microservices pilotés par les événements. Chaque service communique via le bus d'événements central. Faites défiler pour explorer chaque composant.
Entités de domaine qui encapsulent la logique métier et appliquent les invariants. L'aggregate constitue la limite de cohérence des événements.
Faites défiler pour explorer l'architecture
1 / 8
Stack technique
Éprouvé dans de vrais projets
goes n'est pas académique. Le framework est né de la nécessité de modéliser proprement une logique métier complexe et est utilisé en production depuis 2021.
Crovillas
Plateforme de villas de luxe avec moteur de réservation basé sur les événements, architecture multi-applications et microservices gRPC.
DepositDirect
Plateforme de caution locative avec flux de paiement basés sur les événements, gestion des cautions basée sur les aggregates et modèles de lecture CQRS.
Prestige Cars
Location de voitures de luxe avec gestion de flotte basée sur les événements, aggregates de réservation et projections en temps réel.
... et de nombreux autres systèmes de production construits sur goes
FAQ
Questions fréquemment posées sur goes
Oui. goes est utilisé dans plusieurs systèmes en production et est activement maintenu. Le framework dispose d'une API stable et est utilisé en interne chez modernice pour des projets clients. Des projets tels que Crovillas, DepositDirect et Prestige Cars utilisent goes depuis 2021.
goes prend en charge MongoDB, PostgreSQL et NATS JetStream comme backends de production. Des implémentations complètes en mémoire sont disponibles pour les tests et le prototypage. Tous les backends implémentent les mêmes interfaces, ce qui permet de changer sans modification du code.
Des connaissances de base en Go suffisent. Le guide de démarrage et le tutoriel en 12 chapitres présentent progressivement tous les concepts. goes est conçu pour vous permettre d'apprendre et d'appliquer les patterns d'Event Sourcing de manière incrémentale.
Oui. goes est construit de manière modulaire. Vous pouvez utiliser indépendamment certains composants tels que le système d'événements ou les commandes, puis en intégrer d'autres selon vos besoins. Il n'existe aucune dépendance tout ou rien.
goes est conçu pour les scénarios à haut débit. Les snapshots réduisent considérablement le temps de relecture, les projections s'exécutent de manière asynchrone et parallélisée, et l'Event Store prend en charge le traitement par lots. En production, plusieurs millions d'événements sont traités sans latence perceptible.
EventStoreDB est une base de données autonome, tandis que goes utilise votre infrastructure existante (MongoDB, PostgreSQL, NATS). Axon est basé sur Java et bien plus directif. goes vous fournit les briques et vous laisse décider comment les assembler. Aucune dépendance d'exécution en dehors du backend choisi.
goes nécessite Go 1.23 ou une version ultérieure. Le framework utilise intensivement les generics Go pour garantir la sûreté des types pour les commandes, événements et aggregates. Nous recommandons toujours la dernière version stable de Go.
Les contributions sont les bienvenues. Le meilleur point de départ est le dépôt GitHub. Les issues portant le label « good first issue » sont idéales pour commencer. Les PR sont examinées et fusionnées rapidement. Pour les changements importants, nous recommandons de créer d'abord une issue afin d'aligner l'approche.
Prends contact avec nous
Tu utilises goes, ou tu te demandes si l'event sourcing convient à ton projet ? Contacte-nous, nous parlons volontiers architecture et retours de production.