Akita ist eine vielgenutzte State-Management-Bibliothek für Angular-Applikationen. Durch die Erweiterung um Akita Effects in der kürzlich veröffentlichten Version 6 ist sie eine noch attraktivere Alternative zu NgRx oder NGXS geworden.
Die State-Management-Bibliothek Akita steht durch die Reduzierung von Boilerplate-Code und Tools wie das integrierte Effects-Modul für Simplizität.
Akita wird durch das Unternehmen Datorama und einer Vielzahl von Open-Source-Entwicklern gewartet und weiterentwickelt. Die Bibliothek ist lizenziert unter der Apache-2.0-Lizenz und wird durchschnittlich 35.000 mal pro Woche über npm heruntergeladen. Das Projekt ist mit aktuell knapp 3100 Sternen auf Github gelistet.
Was ist Akita?
Akita ist eine auf RxJS (Reactive Extensions Library for JavaScript) basierende State-Management-Bibliothek, die viele Ansätze der Redux und Flux Pattern aufgreift. Im Kern besteht sie aus einem Store Objekt, das in ein Observable eingebettet ist. Abonnierte Empfänger können somit über veröffentlichte Änderungen informiert werden.
Ablaufschema von Akita State Management.
(Bild: Datorama)
Über integrierte CRUD-Methoden besteht die Möglichkeit, das Store-Objekt zu manipulieren (immutable operations). Die Bibliothek basiert auf objektorientierten Design-Prinzipien und gibt eine strikte Architektur vor. Akita nutzt TypeScript und ist vollständig typisiert.
Der Datenfluss ist unidirektional aus dem Store zum jeweiligen Empfänger und der State kann nicht direkt über einen Objektzugriff manipuliert werden. Eine Veränderung des Status erfordert, dass das gesamte Store-Objekt durch ein neues, aktualisiertes Objekt ersetzt wird.
Komponenten haben über Akita Queries die Wahl, Daten in Form so genannter Observables oder eines lesenden Direktzugriffs auf eine Objekteigenschaft zu erhalten. Um den Store zu verändern, rufen Komponenten Servicemethoden auf, die wiederum den Store über von Akita zur Verfügung gestellte CRUD-Methoden verändern können.
Asynchrone Operationen wurden vor Version 6 ausschließlich in Services ausgelagert und explizit aufgerufen. Durch die Integration von Akita Effects besteht nun die Möglichkeit, asynchrone Operationen in Effekte auszulagern. Wie der Grafik zu entnehmen ist, besteht Akita aus drei Bausteinen: Store, Queries und Services, die nun um Actions und Effects ergänzt werden.
Akita Store
Akita Store stellt zwei verschiedene Arten von Stores zur Verfügung. Der Basisstore entspricht der Form eines nutzerdefinierten Interfaces und stellt CRUD-Methoden, wie beispielsweise add, set, update und delete, zur Verfügung. Ein typischer UI State kann beispielsweise wie folgt aussehen.
Eine weitere, besondere Form des Stores ist der Entity Store. Zusätzlich zu den Funktionen des Basisstores besteht die Möglichkeit Entitäten zu speichern und zu sortieren. Ein schneller und effizienter Zugriff auf Entitäten wird über eine HashMap gewährleistet. Die Sortierung wird in Form eines Id Arrays sichergestellt. Des Weiteren kann über den Store der aktuelle Ladezustand und die derzeit aktive Entität verfolgt werden.
Über Queries können Empfänger (UI, Effects und Services) auf Daten aus dem Store zugreifen. Queries lassen sich als Observables oder als Direktzugriff auf Eigenschaften aus dem Store definieren. Komponenten sollten nicht direkt auf den Store zugreifen und stets Queries verwenden. So wird sichergestellt, dass Änderungen an Eigenschaften des States nicht in Komponenten vorgenommen werden können.
Aus dem Store können auch einzelne Eigenschaften selektiert werden, die nur bei dessen Änderung ein Veröffentlichungsevent zur Folge haben. Dadurch werden ungewollt ausgelöste Change-Detection-Zyklen in der UI verhindert. Queries sind wiederverwendbar und es besteht die Möglichkeit, sie mit anderen Queries zu kombinieren. Queries können die erhaltenen Daten aus dem Store vor der Weitergabe an einen Empfänger manipulieren und erweitern, um beispielsweise Daten für die View aufzubereiten (Instanziierung einer Klasse).
Mit Akita Version 6 bietet die Bibliothek die Möglichkeit, Seiteneffekte über RxJS Observables mittels Effects zu behandeln.
Was sind Seiteneffekte im Redux-Kontext?
Seiteneffekte sind Operationen, die als Konsequenz aus einer aufgerufenen Aktion entstehen und meist das Ziel haben, den Anwendungszustand zu verändern. Sie können synchron oder asynchron verlaufen und beinhalten häufig Logik zur Datenbeschaffung. Ein simples Beispiel ist das Laden von Serverdaten: Eine Aktion beschreibt die Absicht Daten zu laden und ein Seiteneffekt lädt die Daten vom Server, um anschließend den State über eine weitere Aktion zu verändern.
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel IT-Medien GmbH, Max-Josef-Metzger-Straße 21, 86157 Augsburg, einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von Newslettern und Werbung nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung.
Ein Effekt ist auf eine oder mehrere Aktionen des Action Streams abonniert. Sobald die Aktion versendet wird, werden alle abonnierten Seiteneffekte ausgelöst. Die Verwendung von Seiteneffekten erlaubt es explizite Servicemethodenaufrufe aus Komponenten heraus zu umgehen. Im Effekt besteht die Möglichkeit, per Dependency Injection auf weitere Services zuzugreifen, wodurch Operationen innerhalb des Effekts auf benötigte Daten von externen Quellen zugreifen können.
Seiteneffekte sind in vielen Anwendungen eine komplexe Problemstellung, da asynchrone Operationen den State zu unbestimmten Zeitpunkten verändern können. Effekte ermöglichen es asynchrone Operationen zu orchestrieren und entsprechende Handlungen nach Vollendigung vorzunehmen. Sie können sequenziell oder parallel ausgeführt werden.
Um Effekte nutzen zu können ist es notwendig Aktionen zu definieren. Effekte filtern einen Strom von Aktionen und werden ausgeführt, sobald die registrierten Aktionen emittiert werden. Aktionen sind Objekte, die einen Typ und optionale Nutzdaten enthalten.
// simplified interface Action<T> { type: string; payload: T }
Mithilfe einer Hilfsfunktion können Aktionen einfach erstellt und typisiert werden.
Ein Effekt kann entweder mit einer @Effect Annotation versehen werden oder die Hilfsfunktion createEffect verwenden. Der Effekt referenziert den Action Stream, der automatisch abonniert wird. Die Quelle des Streams ist ein Actions Observable, in dem alle Aktionen emittiert werden.
Über den ofType Operator werden die Aktionen gefiltert, die den entsprechenden Seiteneffekt auslösen sollen. Im obigen Beispiel wird bei der emittierten changeLanguage Aktion eine Variable showLoadingOverlay im Store gesetzt und eine Methode im uiService aufgerufen. Der darauffolgende switchMap Operator erstellt ein neues, inneres Observable, das den Aufruf einer API auslöst.
Über die Konfiguration {dispatch: true} wird dem Effekt-Modul mitgeteilt, dass der Effekt eine weitere Aktion auslösen soll. In diesem Fall muss dem Action Stream über einen Rückgabewert eine Aktion übermittelt werden. Standardmäßig ist der Wert false. Mithilfe des map Operators wird der Rückgabewert manipuliert und eine Aktion wird zurückgegeben.
Aktionsaufruf
Die Komponente informiert die Applikation lediglich darüber, dass der Nutzer eine Aktion vornehmen möchte, beziehungsweise ein Event ausgelöst wurde. Die daraus entstehende Konsequenz wird im Effekt definiert.
this.actions$.dispatch(UiAction.changeLanguage({ locale: language }));
Wenn benötigt, kann auch der Effekt wiederum eine Aktion auslösen. Eine solche Verkettung von Effekten lässt sich dazu verwenden, einzelne Effekte wiederverwendbar zu machen. Ein Effekt mit gekapselter, zielgerichteter Logik kann auf mehrere Aktionen reagieren und wiederum eine weitere Aktion auslösen, die über die Vollendigung informiert. Es ist empfehlenswert, kleine, prägnante Effekte zu definieren. Überladene Effekte, die mehrere Operationen mit verschiedenen Zielen ausführen sind häufig limitiert in ihrer Wiederverwendbarkeit.
Ablaufschema von Akita State Management inklusive Akita Effects.
(Bild: Boetzkes / Datorama)
Im Gegensatz zu einem expliziten Aufruf einer Servicemethode aus einer Komponente heraus sind die Komponente und der Effekt vollständig voneinander entkoppelt. Es wird ausschließlich über veröffentlichte und abonnierte Events kommuniziert.
Registrierung
Jede Effekt-Klasse muss im AkitaNgEffectsModule registriert werden. Das Modul stellt die Methoden forRoot und forFeature zur Verfügung. Alle vorab geladenen Effektklassen sind wiederum in der forRoot-Methode, Lazy-loaded-Module in der forFeature-Methode zu registrieren.
Je mehr Effekte nachträglich über die forFeature-Methode, anstatt vorab über die forRoot-Methode geladen werden, desto kleiner ist das Main Bundle. Effekte, die zum Anwendungsstart unabhängig des geladenen Moduls benötigt werden, müssen in der forRoot-Methode registriert werden.
AkitaNgEffectsModule.forRoot([UiEffects])
Fazit
Yannick Boetzkes
(Bild: adesso SE)
Akita 6 ist durch die Integration von Akita Effects eine noch attraktivere Alternative zu NgRx. Da die Bibliothek auf einige bekannte Muster aus NgRx zurückgreift, ist die Lernkurve für Entwickler mit Redux/NgRx-Vorwissen nicht allzu groß. Ein Vorteil von Akita ist, dass weniger Code benötigt wird, um ein strukturiertes State Management zu implementieren, da keine Reducer definiert werden müssen und einige Funktionalitäten durch generische Hilfsmethoden bereits integriert sind.
* Yannick Boetzkes ist Software Engineer bei adesso SE in Dortmund und Open Source Contributer. Er ist Full Stack Entwickler mit mehrjähriger Erfahrung im professionellen Umfeld. Seine Schwerpunkte liegen auf der Konzeption und Entwicklung von Web Anwendungen mit JavaScript-Technologien.