Hallo RabbitMQ - 2. Routing
Tags: rabbitmq, csharp, german, beginners
Published: 2022-12-20 08:22:29

Im nächsten Schritt geht es jetzt darum ein Gesamtkonzept für das aktuelle System zu finden. Dieses umfasst folgende Komponenten (abstrahiert):

- Die UI-Applikation, über welche die Benutzer Daten anzeigen, erstellen, ändern und löschen können.
- Eine Dokumenten-API, über welche Dokumente angelegt, gelöscht und bearbeitet werden können. Außerdem kann jedes Dokument 1-n Versionen enthalten
- Ein Renderservice, der zu jeder Dokumentversion eine Vorschau rendert
- Ein Backupservice, der die erste Version jedes Dokumentes nochmal extra wegspeichert
- Ein Synchronisationsservice, der jede Dokumentänderung mit einem externen System synchronisiert

Aktuell unterteilen sich die Event-Producer und Consumer in folgende Gruppen:

![Übersicht Producer und Consumer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r19um8bauv8go6h89ox6.png)

Um diese Struktur umzusetzen, bietet RabbitMQ einige weitere Möglichkeiten an, um unsere Queues aus dem ersten Teil flexibler zu machen:

## Routing

https://www.rabbitmq.com/tutorials/tutorial-four-dotnet.html

Für das Routing bietet RabbitMQ diverse Möglichkeiten an, um unsere Queues zu befüllen.


### Direct exchange

Aus Teil 1 kennen wir ja bereits die Bindings mit dem `RoutingKey`. Direct exchange bedeutet also:

> Finde alle Queues mit dem gleichen Key wie die Nachricht und schreibe sie dort hinein.

![Beispiel Direct Exchange](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q55cy2mqblzz7ryhhbu8.png)

Es dürfen natürlich auch mehrere Queues mit demselben BindingKey vorhanden sein:

![Mehrere Queues mit gleichem BindingKey](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dcv4u1g4ursz898sbv77.png)


### Topic Exchange

Topic Exchange ist ähnlich zum Direct exchange, bietet aber die Möglichkeit mehrere Kriterien zu verwenden.

Ein Topic ist ein Textwert der 1 oder mehrere durch `.` getrennte Wörter, sowie ggf. Platzhalter enthält. Ohne Platzhalter verhält sich Topic Exchange exakt wie Direct Exchange.

Es gibt nur zwei Platzhalter:

* `*` (Stern) steht für genau 1 beliebiges Wort
* `#` (Raute) steht für 0 bis n Wörter

Wir könnten also z.B. die Konvention einführen, dass Binding Keys folgendes Format haben müssen:

`<Kontext>.<Aktion>`. 

Es wäre in unserem Fall also möglich z.B. die Topic `version.created`, sowie `document.*` zu verwenden.

![Beispiel Topic Binding Key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vjmegvt0rp2alr69ee1l.png)

* Alle Änderungen an einem Dokument gelangen immer an die UI, damit diese sich ggf. aktualisieren kann
* Alle neuen Versionen gehen an die Render-Queue, damit eine neue Vorschau gerendert wird

**Wichtig:**

* Der Binding Key muss trotzdem genau gematched werden, sonst gibt es keinen Treffer. `document` oder `document.created.today` wären somit von obigen Filtern nicht erkannt.
* `#` als Filter matched alles


## Umsetzungsmöglichkeit

Fügen wir jetzt die Teile mit den neuen Möglichkeiten zusammen, könnte sich folgendes Bild ergeben.

Topics
* document
  * created
  * restored
  * deleted
  * metadata_changed
  * version.created
* preview
  * created
  * failed

![Beispiel-Architektur der Queues mit Topics](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fbcf2p9c87fgp2tv24vd.png)

### Beispielprojekt

Ich habe mal versucht das beispielhaft mit dem minimalen Setup umzusetzen. Das vollständige Projekt findet man hier: https://github.com/weidmanngabriel/rabbitmq_topics_poc

Man kann jetzt einfach auf der Kommandozeile eingeben welches Event die Dokument-API abschicken soll. Die Events verhalten sich dann so wie im obigen Bild definiert.

---

Mit diesem Wissen kommen wir schonmal ein ganzes Stück weiter. Im nächsten Teil können wir uns dann Details wie Sende- und Empfangsbestätigung, Callbacks, etc. ansehen.