|

Einführung in NestJS DMN: Geschäftsregeln parsen ohne den Verstand zu verlieren (Teil 1)

Haben Sie schon einmal versucht, komplexe Geschäftsregeln zu verwalten, die über Hunderte von if-else-Anweisungen in Ihrem Code verstreut sind? Wenn ja, haben Sie wahrscheinlich schon einmal darüber nachgedacht, ein One-Way-Ticket zu einer einsamen Insel ohne WLAN zu kaufen.

Hier kommt DMN (Decision Model and Notation) ins Spiel. Es ist ein Standard, der es Business Analysten ermöglicht, schöne Tabellen zu zeichnen, die irgendwie diktieren, was Ihre App tun soll. Das Problem? Die meisten DMN-Engines erfordern eine JVM, massive Abhängigkeiten oder einen Doktortitel im Parsen von XML.

Nicht mehr. Darf ich vorstellen: @oltionzefi/nestjs-dmn.

Was ist das?

Es ist ein kleines, vollständig typisiertes NestJS-Modul, das DMN 1.3 XML parst und Entscheidungstabellen auswertet. Es baut auf den Schultern von Giganten auf: dmn-moddle (zum Lesen von XML) und feelin (zum Interpretieren von FEEL/S-FEEL).

Das Beste daran? Keine nativen Abhängigkeiten, keine JVM, keine verrückten JSON-Formatkonvertierungen. Sie richten es einfach auf eine .dmn-Datei direkt aus dem Camunda Modeler, und los geht’s.

Die wirklich wichtigen Features

  1. Vollständige NestJS DI-Integration: Alles ist ein @Injectable. Wir verwenden die Standardmuster forRoot und forRootAsync, weil wir zivilisierte Entwickler sind.
  2. Trefferrichtlinien (Hit Policies) in Hülle und Fülle: Es verarbeitet FIRST, UNIQUE, COLLECT und RULE ORDER direkt nach der Installation.
  3. Erweiterbare Architektur: Benötigen Sie eine benutzerdefinierte Dekodierung von Ausgabezellen? Möchten Sie Labels anders auf Variablen abbilden? Kein Problem.
  4. Typen, Typen, Typen: Kein einziges any in der öffentlichen API. Es bringt sogar seine eigenen dmn-moddle-Deklarationen mit.

Erste Schritte

Sagen Sie npm zunächst, wo es meine Pakete finden kann (falls Sie dies noch nicht getan haben, fügen Sie dies der .npmrc Ihres Projekts hinzu):

@oltionzefi:registry=https://npm.pkg.github.com

Dann installieren Sie die Magie:

npm install @oltionzefi/nestjs-dmn dmn-moddle feelin

(Hinweis: Stellen Sie sicher, dass Sie @nestjs/common (v10 oder v11) und reflect-metadata installiert haben, da dies Peer-Abhängigkeiten sind.)

Die Einrichtung

Nehmen wir an, Sie haben eine schicke DMN-Datei (tier.dmn), die basierend auf den monthlyMinutes und dem country entscheidet, ob ein Benutzer ein “power”-, “standard”- oder “trial”-Abonnement erhält.

Importieren Sie das Modul einfach in Ihre App:

import { Module } from '@nestjs/common';
import { DmnModule } from '@oltionzefi/nestjs-dmn';

@Module({
  imports: [DmnModule.forRoot()],
})
export class AppModule {}

Und injizieren Sie die Dienste in Ihren Router:

import { Injectable } from '@nestjs/common';
import { DmnEvaluatorService, DmnParserService } from '@oltionzefi/nestjs-dmn';

@Injectable()
export class SubscriptionRouter {
  constructor(
    private readonly parser: DmnParserService,
    private readonly evaluator: DmnEvaluatorService,
  ) {}

  async route(xml: string, input: any) {
    const decisions = await this.parser.parseDmnXml(xml);
    const [decisionId] = Object.keys(decisions);
    
    return this.evaluator.evaluateDecision(decisionId, decisions, input);
  }
}

Boom. router.route(xml, { monthlyMinutes: 2400, country: 'DE' }) spuckt auf magische Weise { plan: 'power', discount: 0.2 } aus.

In Teil 2 werden wir tiefer in erweiterte Konfigurationen eintauchen und zeigen, wie Sie das Modul an Ihre genauen, möglicherweise chaotischen, Enterprise-Anforderungen anpassen können. Bleiben Sie dran!