Kontakt
stefan.bente[at]th-koeln.de
+49 2261 8196 6367
Discord Server
Prof. Bente Personal Zoom
Adresse
Steinmüllerallee 4
51643 Gummersbach
Gebäude LC4
Raum 1708 (Wegbeschreibung)
Sprechstunde nach Vereinbarung
Terminanfrage: calendly.com Wenn Sie dieses Tool nicht nutzen wollen, schicken Sie eine Mail und ich weise Ihnen einen Termin zu.

Microservice Architectures (MSA), WS21

Microservices sind ein Architekturstil, der die Entwicklung großer Softwaresysteme in weitgehend autarken Teams ermöglich. In diesem Kurs lernen Sie die wichtigsten Konzepte dazu kennen. Innerhalb eines relativ großen Projekts implementieren Sie selbst einen Service mit synchroner (REST) und asynchroner (Kafka-Events) Kommunikation.

Studiengang und Modulbeschreibung
Code & Context (Bachelor) (siehe auch Modulbeschreibung auf der Studiengangs-Seite)
Zeitraum und zeitliche Organisation der Veranstaltung
03.01.2022 - 14.01.2022. Organisiert als Blockkurs mit definierten Präsenzzeiten. Siehe unten für die genauen Daten.
Ort der Veranstaltung
Die Veranstaltung findet im Regelfall rein online statt.
Videokonferenz-Link: https://th-koeln.zoom.us/j/85846750101?pwd=THVKQjJGU2tRQ2hqQ1YzSSsrekxJdz09 (nur in Ausnahmefällen und wenn explizit vorher für den Tag kommuniziert)
ILIAS/ILU-Kurs zur Veranstaltung
https://ilias.th-koeln.de/ilias.php?ref_id=2122372&cmdClass=ilrepositorygui&cmdNode=wc&baseClass=ilrepositorygui
Anmeldung zur Veranstaltung
Bitte werden Sie Mitglied in diesem ILIAS/ILU-Kurs. Die Deadline ist 20.12.2021.

Learning Outcome

Als Software-Entwickler:in kann ich mittlere bis große Software- und IT-Systeme konzipieren und umsetzen,

indem ich ...

  • die Fachlichkeit der Anwendung gemäß der Methoden des Domain-Driven Design analysiere und dekomponiere,
  • diese in Services schneiden, deren Kernfunktionalitäten über REST-APIs und Messaging nach außen angeboten werden,
  • dazu eine unter Anwendung von gebräuchlichen Architekturpatterns eine Microservice-Applikationsarchitektur entwerfe,

damit ich auf diese Weise große digitale Produkte entwickeln kann, die ein komplexes, verteiltes Backend erfordern.

Organisation der Veranstaltung

Microservice Architectures (MSA) ist eine Blockveranstaltung in Code & Context in der Zeit von 03.01. bis 11.06.2021. Dabei wird es folgende Struktur geben:

  • Die Tage sind als Workshop angelegt und gehen von 10:00 bis 16:00, mit einer Mittagspause, die wir je nach Tages-Agenda aushandeln.
    • Ich versuche, jeweils immer jede Stunde 5 min Pause einzuhalten. Sollte es mir durchgehen, erinnern Sie mich bitte daran.
  • Die Workshops bestehen aus Inhaltsimpulsen, selbstständigen praktischen (Programmier- und Modellier-)Übungen und Gruppenreflektionen.
  • Die meisten Inhalte der Veranstaltung sind als Lehrvideos verfügbar. Für einige Videos ist während des Tages Zeit vorgesehen, um diese zu schauen; andere schauen Sie bitte nach 16:00, vor Beginn des nächsten Tages.
  • Siehe auch Zeitplan mit Inhalten unten, dort sind die Videos direkt verlinkt.
  • Der Mittwoch ist als Selbstlern-Tag konzipiert. An diesem Tag gibt es kein Workshop-Programm.

Ein Feedback ist auch außerhalb der Workshop-Zeiten möglich, bevorzugt über Discord (siehe unten).

Fragen an Sie …

  • Bevorzugter Kommunikations-Channel … Discord ist gut wegen des Dungeon-Projekts. Außerdem Mattermost? Präferenz?
  • Die Case-Study (Implementierung des eigenen Players im The Microservice Dungeon Projekt) soll als Gruppenarbeit (3-4 Personen) ausgeführt werden. Wollen Sie die Gruppen selbst zusammenstellen, oder soll ich das tun?

Vorbereitung auf den Kurs

  • ILIAS-Kurs MSA beitreten
  • Videos schon mal ansehen - s.u. unter “Zeitplan”
  • Wer will: Literaturliste anschauen und sich das eine oder andere schon mal besorgen (ebenfalls s.u.)

Benotung

Die Benotung erfolgt in diesem Kurs in Teilgruppen, basieren auf einem Code Review des eigenen Players.

Minimalanforderungen an den Player

  • Der Player kann Robots kaufen und jeden von ihnen eigenständig im “Serendipity”-Modus (läuft rum und versucht, neue Planeten zu finden) umherlaufen lassen.
    • Alternativ kann man einem Robot befehlen, eigenständig “nach Hause” zu gehen (gehe zu einer Space-Station)
  • Es gibt ein Steuerungs-REST-API, das die folgenden Kommandos an den eigenen Player erlaubt:
    1. Kaufe Robot in der nächsten Runde
    2. Gebe Zustand eines Robots aus
    3. Gebe Zustand aller Robots aus
    4. Versetze einen bestimmten Robot in den Modus “Serendipity”
    5. Versetze einen bestimmten Robot in den Modus “Go Home”
    6. Gebe eine Übersicht aller bekannten Planeten mit den Positionen der eigenen Robots aus

Sonstiges

  • Natürlich darf der Robot auch mehr können. Die obigen Anforderungen stellen den bewerteten Umfang dar - alles darüber hinaus ist Bonus.
  • Die Ausgaben müssen nicht “schön” sein, es genügt z.B. ein JSON-Objekt oder ein String.
  • Bei der Ausgabe der Planeten sind nur die Positionen der eigenen Robots gefordert, alles andere (Ressource, fremde Robots, …) ist Bonus.
  • Für den Player herrscht Technologiefreiheit. Sie können auf dem Generic Player aufsetzen, müssen das aber nicht.
  • Wenn Sie eine Technologie verwenden, die in der jetzigen Infrastruktur nicht vorkommt (andere Sprache als Java, Kotlin oder Ruby; andere DB als Maria, MySql oder PostgreSQL - kein Anspruch auf Vollständigkeit), dann sind Sie selbst für alles verantwortlich - möglicherweise wird Ihnen niemand aus dem restlichen Projekt helfen können.

Bewertung

Maximal sind 100 Punkte (+ 60 Bonus) zu erreichen. Zum Bestehen müssen 40 Punkte erreicht werden, eine 1,0 gibt es ab 90 Punkten.

  Max. Punkte Kriterien Max. Bonus Bonus-Kriterien
Player-Strategie und -Umsetzung 30 - geforderte Funktionalität umgesetzt 20 - originelle Steuerungs-/Strategie-Idee
- Grad der “Sophistication”
- ggfs. Clients oder sonstige “schöne” Ausgaben zur Visualisierung
Tactical DDD 30 - Entities und Value Objects richtig gewählt
- Business-Logik ist, wo möglich, im Domain Layer (nicht zu viel in den Services)
- Domain Primitives existieren, wo sinnvoll
- Aggregates sinnvoll geschnitten
- Alles in einem kompakten Domain Model dokumentiert
- Sinnvolle Application Services definiert
- Domain- und Application Layer in der Package-Struktur sauber getrennt
- -
REST API zur Player-Steuerung 15 - REST APIs bilden Aggregates ab
- REST APIs entsprechen REST-Standards
- Controller sind DDD-konform ausgelegt (keine Business-Logik, Aufruf von Application Services)
- alle geforderten REST-APIs umgesetzt
10 - deutlich mächtigeres REST-API als gefordert umgesetzt
Inter-Service-Kommunikation 15 - Synchrone Player-Commands an Game-Service umgesetzt
- Events zu den Kommando-Antworten sauber verarbeitet
10 - Events zu den Aktionen anderer Player abgehorcht und verarbeitet
Tests 10 - Wesentliche Teile der Funktionalität getestet 10 - sehr hohe Testabdeckung
- originelle Tests und Mocking
DevOps - - 10 - Build-Pipeline für Player definiert
- Player kann tatsächlich beim Codefight dabei sein
Summe 100   60  

Der Erfolg oder Misserfolg des eigenen Players beim Codefight zählt ausdrücklich NICHT für die Note. Hier geht es nur um den Spaß und die Ehre!

Zeitplan

Mo 03.01.22 - Motivation: Bearbeitung eines großen Softwareprojekts im Team

Ziel des Tages

Verstehen, wieso der richtige Schnitt bei großen Software-Systemen wichtig und schwierig ist. Am Beispiel des Microservice Dungeon Projekts einmal selbst durchspielen, wie man das machen könnte.

Agenda

  • 10:00 Orga, Fragen zur Veranstaltung
  • 10:30 Inhaltsimpuls: Motivation - Verteilte Softwaresysteme und Bearbeitung in Teams
    • PDF liegt hier in ILAS
    • “Traditionelle” Architekturen
    • Heutige Anforderungen: agile Teams, schnelle Time2Market
    • Conway’s Law
    • Microservices als unabhängige Einheiten
  • 11:15 Übung: Serviceschnitt eines großen IT-Systems, am Beispiel von “The Microservice Dungeon”
    • Wie kann man für ein größeres Softwaresystem sicherstellen, dass mehrere Teams parallel daran arbeiten können, ohne sich dauernd in die Quere zu kommen? Dies wird anhand des Online-Games “The Microservice Dungeon” in dieser Übung durchgespielt.
    • darin 12:30 Mittagspause
    • danach um 13:30: schauen Sie sich die Lösungen und bisherigen Implementationen an. Vergleichen Sie das mit “Ihren” Clustern.
    • gegen 14:00 Rundlauf im Plenum: Ergebnisse? Was hat überrascht? Was würden Sie anders machen?
  • 14:30 Inhaltsimpuls: Konzept des Bounded Context und der Context Map
  • 14:45 Übung: Context Map für ein verteiltes IT-Systems, am Beispiel von “The Microservice Dungeon”
    • Die Context Map zeigt an, welche Entities (eigentlich Aggregates) welchem Service “gehören”, und welche anderen Services diese Entities aber redundant speichern und ggfs. mit eigenen Attributen ergänzen. In der Übung spielen wir diese Methode einmal für das “Microservice Dungeon”-Projekt durch.
    • Rundlauf im Plenum: Wo passt es, wo nicht? Was hat Sie überrascht?
  • 16:00 Ende

Aufgabe für den nächsten Tag (freiwillig)

  • Finden Sie sich zu Teams zusammen, um einen eigenen Player zu implementieren (falls wir im Kurs entscheiden, dass Sie die Teams lieber selbst wählen.)
  • Treten Sie dem Discord-Server für das Projekt bei und schauen Sie in die Historie der Kommentare dort, um das Projekt besser kennenzulernen und Fragen für den Di Vormittag zu haben.
    • ArchiLab-Discord-Server findet sich unter https://discord.gg/YYNYb5whU8.
    • Im Channel “Rollenzuweisung” einfach bitte die Rollen Informatikprojekt und Code & Context anwählen
    • Dann sieht man die entsprechenden Kanäle

Di 04.01.22 - Ihr eigener (Player-)Service

Ziel des Tages

“Ankommen” im The Microservice Dungeon Projekt. Grobe Planung (Todos) für den eigenen Player-Service fertig haben.

Agenda

  • 10:00 Einführung in das Gameplay (vom Project Launch Team für das Gameplay)
  • 10:30 Gruppenarbeit: Planung des eigenen Players
    • Der Player sollte folgendes können:
      1. Ist als Microservice deploybar
      2. Nimmt Ihre Kommandos via REST an (z.B. über Postman, oder - wenn Sie das wollen - einen eigenen Client)
      3. Horcht auf Events der Kern-Services, um etwas über andere Player und deren Robots zu erfahren (soweit Sie das umsetzen wollen und können)
      4. Steuert die eigenen Robots per REST-Aufrufe des Game-Commands-Endpoint (entweder als vollständig manuelle Steuerung, oder semi-automatisch, indem man von Hand z.B. Strategiewechsel eingibt)
    • Ihre Aufgabe in dieser Gruppenarbeit:
      • überlegen Sie sich, wie Sie den Player steuern wollen
      • Welche Strategie wollen Sie umsetzen?
      • Entwerfen Sie (erstmal informell) die Steuerungskommandos, die Sie selbst dem Player geben wollen, z.B. …
        • “Jetzt maximal aggressiv - alles angreifen, was sich bewegt”
        • “Alle Robots nach Süden!”
        • “Robot A move to planet X, robot B move to planet Y”
      • Dokumentieren Sie das in einem Miroboard
  • 12:00 Rundlauf: Stand der Planung
  • 12:30 Mittagspause
  • 13:30 Inhaltsimpuls: der Generic Player als Template, wenn Sie nicht bei Null starten wollen
  • 13:45 Gruppenarbeit: Technologiestack und DevEnv aufsetzen
    • Legen Sie sich ein Github-Repo an
    • Legen Sie einen Technologiestack fest
      • Bedenken Sie: Sie müssen das selbst in die Pipeline integrieren. Nur deployte Player können am Codefight teilnehmen!
      • Bisherige Technologien sind Java, Kotlin und Ruby on Rails.
      • Für Java gibt es einen Generic Player, den Sie als Startpunkt nehmen können
      • Wenn Sie viel Hilfe von mir brauchen werden (auch bei der Technologie), dann sollten Sie Java + Spring nehmen
    • Denken Sie daran, dass Sie nur wenig Zeit haben!
    • Machen Sie einen Arbeitsplan
    • Formulieren Sie Issues in Github
  • 15:30 Abschlussrunde: Rundlauf mit Rückmeldung aus allen Teams
  • 16:00 Ende

Aufgabe für den nächsten Tag (freiwillig)

  • Den ArchiLab-Youtube-Channel durchblättern, ob das interessante Inhalte für diese Veranstaltung drin sind.
  • Die Recap-Videos zu Entities etc. gucken (siehe Programm für den Mittwoch).

Mi 05.01.22 - Selbstlerntag

Den Selbstlerntag haben Sie zur freien Gestaltung. Daher ist der Tag nicht verplant. Wenn Sie aber trotzdem etwas tun wollen, dann machen Sie doch das folgende:

  • Schauen Sie sich die folgenden beiden Videos als Recap des Kurses Application Design an:
  • Überlegen Sie schon mal: Wie sieht Ihr Domain Model für den eigenen Player aus? Welche Entities, Value Objects, Domain Primitives haben Sie?
    • Orientieren Sie sich an Ihrer Gruppendiskussion zum Thema “Player-Strategie” und an der Context Map

Do 06.01.22 - Synchrone Kommunikation: Aggregates & REST

Ziel des Tages

Konzepte der synchronen Kommunikation in verteilten System (Aggregates, REST) verstanden und für den eigenen Player spezifiziert.

Agenda

  • 10:00 Retrospektive
    • Wasserstandsabfrage - wie hoch steht jedem:r das Wasser?
    • Fragensammlung: Welche Frage muss dringend geklärt werden?
      • Diskussion der offenen Fragen (Zielsetzung des Kurses, dieses Tages, beste Herangehensweise, etc.)
  • 10:45 Recap: Wiederholung der Themen aus Application Design (Entities, Repositories, Value Objects, Domain Primitives, …)
    • Kurzvorstellung des Generic Players mit Fokus auf Wiederholung der Themen aus Application Design
  • 11:30 Inhaltsimpuls: Aggregates
  • 12:15 Mittagspause
  • 13:15 Übung: Aggregates bestimmen (am Beispiel eines Campus-Management-Systems CAMS)
    • In dieser Übung geht es darum, Aggregates zu identifizieren. Dazu nutzen Sie die aus Videos bekannte Checkliste.
  • 14:15 Inhaltsimpuls: REST
    • REST-APIs sind der gängigste Weg, um Clients an ein Backend anzubinden. REST-APIs lassen sich sehr gut anhand von Aggregates herum konzipieren.
    • REST ist ein Architekturstil mit gewissen Regeln, kein Protokoll!
    • Schauen Sie sich bitte die folgenden Videos an:
    • Gibt es Fragen dazu?
  • 15:15 Übung: REST-API spezifizieren (am Beispiel eines Campus-Management-Systems CAMS)
    • In dieser Übung geht es darum, für die in einer vorangegangenen Übung gefundenen Aggregates jeweils ein REST-API zu spezifizieren.

Aufgabe für den nächsten Tag (freiwillig)

Schauen Sie mal die Repos der Services in der Microservice-Dungeon-Organisation auf Github durch. Wie “REST-konform” sind die REST APIs dort?

Fr 07.01.22 - Implementing REST API

Ziel des Tages

Verstehen, wie man einen REST-Controller schreibt (der einen REST-Endpunkt zur Verfügung stellt).

Agenda

Aufgabe für den nächsten Tag (freiwillig)

Schauen Sie sich im Nachgang auch noch einmal die folgenden Lehrvideos zum Thema “REST-Implementierung” an:

Mo 10.01.22 - Inter-Service-Kommunikation

Ziel des Tages

Verstehen, wie man 1) aus dem Backend heraus einen anderen REST-Endpunkt ruft (und das testet), und 2) mehr Klarheit, was Apache Kafka ist, und wie man einen Kafka-Event im eigenen Code konsumiert.

Agenda

  • 10:00 Fragen
    • Fragen zu Player-Anforderungen, technischen Schwierigkeiten, Architektur
  • 10:15 Gruppenarbeit: Umsetzen der bisherigen Inhalte für den eigene Player
    • Individuelle Beratung bei Problemen und Fragen
  • 12:30 Mittagspause
  • 14:00 Gesamte Gruppe: Stand der Dinge
    • Wo sollten Sie mit Ihrer Arbeit anfangen? 4 Optionen, die auch parallel in der Gruppe bearbeitet werden können. Die nachfolgede Liste ist im Schwierigkeitsgrad aufsteigend.
      1. Implementieren der “Serendipity”
        • Robot sucht sich zufällig einen Planeten aus, auf dem er noch nicht war
        • Welche Datenstrukturen braucht man dafür (Entities, VOs, Aggregates, Domain Primitives, zusätzliche Attribute in schon bestehenden Klassen)
        • Wie kann man das lokal testen? Erzeugen Sie sich eine Map und Robots und lassen Sie den Robot laufen :-)
      2. Implementation eines REST-Endpoints, z.B. Ausgabe aller Robots / eines bestimmten Robots
      3. Kommandos an GameService absenden
        • Wenn Sie einen Move des Robots machen wollen (siehe 1.), dann müssen Sie ein Kommando an den GameService senden
        • Schauen Sie sich an, wie das RestTemplate benutzt wird, am Beispiel von GameServiceRESTAdapter
        • Dito lokale Tests: siehe PlayerBearerTokenTest.
        • Am Di wird es dazu einen Inhaltsimpuls geben
      4. Events empfangen, insbesondere Antworten auf Kommandos
        • Antworten auf Commands werden per Event verschickt und müssen über die transactionId zugeordnet werden
        • Schauen Sie sich den Event Listener am Beispiel GameEventConsumerService. an, im Generic Player
        • … und ebenfalls die entsprechenden lokalen Tests
    • Bringen Sie das lokale Dev Env ans Laufen.
      • Das können Sie sehr gut zum “Integrationstest” einsetzen
  • 14:30 Gruppenarbeit: Umsetzen der bisherigen Inhalte für den eigene Player
    • Individuelle Beratung bei Problemen und Fragen
  • 15:45 Gesamte Gruppe: Aktueller Stand
  • 16:00 Ende

Aufgabe für den nächsten Tag

Bitte schauen Sie sich unsere drei Kafka-Videos an.

Di 11.01.22 - Intra-Service-Architektur

Ziel des Tages

Grundsätzlich verstanden, was der Unterschied synchron / asynchron bedeutet, und vor allem auch, wieso asynchrone Kommunikation zu einer losen Kopplung führt. Recap: Was sollte ich beachten, wenn ich einen Service implementiere.

Agenda

  • 10:00 Fragen
    • Fragen zu Player-Anforderungen, technischen Schwierigkeiten, Architektur
  • 10:15 Inhaltsimpuls: Implementation eines REST-Calls zu einem anderen Service
  • 11:00 Gruppenarbeit: Umsetzen der bisherigen Inhalte für den eigene Player
  • 12:30 Mittagspause
  • 13:30 Inhaltsimpuls: Umsetzung eines Event-Listeners
  • 14:00 Gruppenarbeit: Umsetzen der bisherigen Inhalte für den eigene Player
  • 15:45 Rundlauf
  • 16:00 Ende

Aufgabe für den nächsten Tag (freiwillig)

(to be done)

Mi 12.01.22 - Selbstlerntag

Den Selbstlerntag haben Sie zur freien Gestaltung. Daher ist der Tag nicht verplant. Wenn Sie aber trotzdem etwas tun wollen, dann arbeiten Sie am besten an Ihrem Player Service weiter

Do 13.01.22 - Hosting von Microservices

Ziel des Tages

Klarheit gewonnen, was DevOps ist und warum man als Coder:in auch das Hosting im Griff haben sollte. Verstanden, wie die Pipeline im The Microservice Dungeon Projekt funktioniert, und den eigenen Player-Service dort integriert. Außerdem die lokale Testumgebung (basierend auf Docker) startbereit.

Optional: Einen groben Überblick gewonnen, was in der Kommunikation bei verteilten Systemen alles schief gehen kann - und was man (so ungefähr) dagegen tun kann.

Agenda

(to be done)

Aufgabe für den nächsten Tag (freiwillig)

(to be done)

Fr 14.01.22 - Codefight Teil 1

Ziel des Tages

Eigener Player ist soweit lauffähig, dass er zumindest mal ein bisschen mitlaufen kann!

Agenda

(to be done)

Literatur

Hier finden Sie bewusst eine längere Liste zum Weiterlesen. Die aus meiner Sicht wichtigsten Titel sind fettgedruckt.

  1. Bente, S., Deterling, J., Reitano, M., & Schmidt, M. (2020, March 27). Sieben Weggabelungen—Wegweiser im DDD-Dschungel. JavaSPEKTRUM, 2020(02), 28–31.
  2. Dowalil, H. (2019). Modulith First! Der angemessene Weg zu Microservices. Informatik Aktuell. URL
  3. Evans, E. (2015). Domain-Driven Design Reference—Definitions and Pattern Summaries. Domain Language, Inc. URL
  4. Evans, E. (2003). Domain-Driven Design: Tackling Complexity in the Heart of Software (1st edition). Addison-Wesley Professional.
  5. Fielding, Roy Thomas. (2000). Architectural styles and the design of network-based software architectures, University of California, Irvine. URL
  6. Fowler, M. (2010, March 18). Richardson Maturity Model. martinfowler.com. URL
  7. Fowler, M. (2014, January 15). Bounded Context. martinfowler.com. URL
  8. Fowler, M. (2017, February 7). What do you mean by “Event-Driven”? martinfowler.com. URL
  9. Gauder, S. (2019, April 1). A competitive food retail architecture with microservices. microxchg 2019. URL
  10. Graca, H. (2017, November 16). DDD, Hexagonal, Onion, Clean, CQRS, … How I put it all together. @hgraca. URL
  11. Levin, G. (2017, March 25). Internal vs. External APIs. REST API and Beyond. URL
  12. Lilienthal, C. (2019, March 25). Von Monolithen über modulare Architekturen zu Microservices mit DDD. JAX 2020. URL
  13. Massé, M. (2011). REST API Design Rulebook (1st ed.). O’Reilly and Associates.
  14. Newman, S. (2021). Building Microservices: Designing Fine-Grained Systems (2nd ed.). O’Reilly and Associates.
  15. Richardson, C. (2015, May 19). Introduction to Microservices. NGINX. URL
  16. Samokhin, V. (2018, January 18). DDD Strategic Patterns: How to Define Bounded Contexts - DZone Microservices. Dzone.Com. URL
  17. Steinacker, G. (2016, March 20). Why Microservices? Dev.Otto.De. URL
  18. Sturgeon, P. (2017, January 24). GraphQL vs REST: Overview. Phil Sturgeon. URL
  19. Tilkov, S., Eigenbrodt, M., Schreier, S., & Wolf, O. (2015). REST und HTTP: Entwicklung und Integration nach dem Architekturstil des Web (3., akt. u. erw. Aufl.). dpunkt.verlag GmbH.
  20. Vernon, V. (2013). Implementing Domain-Driven Design (01 ed.). Addison Wesley.
  21. Wolff, E. (2015). Microservices: Grundlagen flexibler Softwarearchitekturen (1., Auflage). dpunkt.verlag.
  22. Wolff, E. (2016b, November 29). Self-contained Systems: A Different Approach to Microservices. InnoQ Blog. URL