Μετάβαση στο περιεχόμενο

Επισκόπηση

Τα πακέτα @cqrs-ddd είναι δομικά στοιχεία TypeScript που λειτουργούν χωρίς δέσμευση σε framework. Χωρίζονται σε δύο ανεξάρτητες βασικές οικογένειες (το pipeline και τα στοιχεία DDD) και συμπληρώνονται από δύο runtimes εφαρμογής: το @cqrs-ddd/cqrs, χωρίς framework, και τον επίσημο adapter για NestJS, το @cqrs-ddd/nestjs.

Το @cqrs-ddd/pipeline είναι η κεντρική μηχανή εκτέλεσης: το createPipeline() ρυθμίζει τα behaviors μία φορά και το pipeline.wrap() τα εκτελεί γύρω από μια απλή συνάρτηση ή μια μέθοδο κλάσης. Ένα behavior είναι ένα αντικείμενο με μία μέθοδο, την handle(context, next), ώστε να δρα πριν από την κλήση, μετά από αυτήν ή στη θέση της.

Κάθε πακέτο @cqrs-ddd/pipeline-<name> προσφέρει μία συγκεκριμένη λειτουργία ως behavior:

Λειτουργία Πακέτο
Logging @cqrs-ddd/pipeline (LoggingBehavior, logging())
Επικύρωση @cqrs-ddd/pipeline-zod
Εξουσιοδότηση @cqrs-ddd/pipeline-casl
Caching @cqrs-ddd/pipeline-cache
Idempotency @cqrs-ddd/pipeline-idempotency
Όρια ρυθμού (rate limits) @cqrs-ddd/pipeline-rate-limit
Επανάληψη, timeout, bulkhead @cqrs-ddd/pipeline-resilience
Feature flags @cqrs-ddd/pipeline-feature-flags
Ίχνος ελέγχου (audit trail) @cqrs-ddd/pipeline-audit
Dead letters @cqrs-ddd/pipeline-deadletter
Traces και metrics @cqrs-ddd/pipeline-opentelemetry
Tenant, correlation id, context εργασιών @cqrs-ddd/pipeline-tenant, @cqrs-ddd/pipeline-correlation, @cqrs-ddd/pipeline-job-context

Ένα behavior είναι μια απλή κλάση: ο constructor του δέχεται όσες εξαρτήσεις χρειάζεται (ένα cache, ένα store, έναν client) χωρίς κανένα dependency-injection container. Τα behaviors που μετατρέπουν σφάλματα σε απαντήσεις HTTP εξάγουν το toHttpResponse(error) από ξεχωριστό entry point /http, που λειτουργεί με οποιοδήποτε HTTP framework.

Το @cqrs-ddd/core προσφέρει aggregate roots, domain events, βασικές κλάσεις για commands και queries, συμβόλαια repositories και ένα revision-fenced cache για repositories· το @cqrs-ddd/mikro-orm προσαρμόζει τα repositories του στο MikroORM.

Τα @cqrs-ddd/safe-stringify, @cqrs-ddd/untyped και @cqrs-ddd/uuidv7 είναι μικρά βοηθητικά πακέτα χωρίς εξαρτήσεις, κοινά και στις δύο οικογένειες.

Ανάλογα με την αρχιτεκτονική σας, δύο runtimes εκτελούν τους handlers μέσα από pipelines:

Το @cqrs-ddd/cqrs εκτελεί commands, queries και events χωρίς framework:

  • Χρησιμοποιεί τα @CommandHandler, @QueryHandler και @EventsHandler στις κλάσεις των handlers.
  • Δηλώνει behaviors με τα @UsePipeline και @SkipPipeline του @cqrs-ddd/pipeline.
  • Το createCqrs() δημιουργεί τα CommandBus, QueryBus, EventBus και UnhandledExceptionBus.
  • Χωρίς DI container: η εφαρμογή κατασκευάζει τους handlers με new και τους καταχωρεί. Δείτε το CQRS χωρίς NestJS. Το api/ του αποθετηρίου είναι μια πλήρης εφαρμογή φτιαγμένη με αυτόν τον τρόπο.

Το @cqrs-ddd/nestjs ενσωματώνει τα πακέτα σε μια υπάρχουσα εφαρμογή NestJS:

  • Κρατά τους επίσημους handlers και τα buses του @nestjs/cqrs, καθώς και το dependency injection του NestJS.
  • Το PipelineModule.forRoot() συνθέτει τα behaviors του @cqrs-ddd/pipeline γύρω από τους handlers του @nestjs/cqrs κατά την εκκίνηση.
  • Το ErrorFilter μετατρέπει κάθε σφάλμα των @cqrs-ddd σε HttpException του NestJS, με το τυπικό σώμα JSON απάντησης του Nest.
  • Προσφέρει τα CorrelationMiddleware και JobContextModule για tracing και ουρές εργασιών. Δείτε το NestJS & @cqrs-ddd και τη σελίδα του πακέτου @cqrs-ddd/nestjs.

Καμία από τις δύο οικογένειες δεν εξαρτάται από την άλλη. Ένα BaseCommand, BaseQuery ή DomainEvent του @cqrs-ddd/core φέρει το σύμβολο REQUEST_KIND, που λέει στα behaviors του pipeline τι είδους αίτημα είναι, ώστε οι handlers με decorators να εκτελούνται χωρίς επιπλέον ρύθμιση: δείτε το DDD χωρίς framework.