Ga naar hoofdinhoud

Kwaliteitseisen aan een Container diagram

In de les ga je aan de slag aan de hand van voorbeelden van Container diagrammen.

In beginsel is er natuurlijk al de C4 checklist, maar het is goed zelf na te denken over kwaliteit. In het algemeen kun je vaak het best tot concrete kwaliteitseisen komen als je voorbeelden bekijkt; ook later als je ze moet opstellen voor iets nieuws in de snel veranderende wereld van softwareontwikkeling. Een slecht voorbeeld is dan ook vaak beter dan geen voorbeeld, mits het je helpt om erna iteratief tot een (voldoende) goed diagram te komen.

"Don't let perfect be the enemy of good." - Voltaire

Voorbeelden: Uber Eats C4 Container diagrammen

Voorbeeld Container diagrammen van Uber Eats

Hieronder vind je vier uitgewerkte voorbeelden van C4 Container diagrammen voor Uber Eats. Het is iets ('eats'? ;), maar er is het nodige op aan te merken. Gebruik deze om de kwaliteitseisen aan Container diagrammen te oefenen en onderling te bespreken.

Voorbeeld 1: WebApp

4122e89247d2feb28dbf50020f98f232

PlantUML broncode voor "Uber Eats WebApp Container diagram"
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml

' Uber Eats WebApp Component Diagram (voorbeeld 1)

LAYOUT_WITH_LEGEND()

Person(user, "Gebruiker", "Bestelt eten via de app of website")
System_Boundary(c1, "Uber Eats WebApp") {
Component(orderUI, "Order UI", "React", "Gebruikersinterface voor bestellingen")
Component(authService, "Auth Service", "Node.js", "Authenticatie en autorisatie")
Component(apiClient, "API Client", "Axios", "Communicatie met backend API")
}
Rel(user, orderUI, "Gebruikt")
Rel(orderUI, apiClient, "Doet API-aanroepen")
Rel(apiClient, authService, "Gebruikt voor login")
@enduml

C4 Component diagram with:

  • 3 components: Order UI, Auth Service, API Client
  • 3 relationships:
    • Gebruiker gebruikt Order UI
    • Order UI doet API-aanroepen API Client
    • API Client gebruikt voor login Auth Service

Voorbeeld 2: Backend

c329a8f6ef3adb85e42a8aa8e1cd4815

PlantUML broncode voor "Uber Eats Backend Container diagram"
@startuml

!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml

LAYOUT_WITH_LEGEND()

System(system, "Uber Eats", "Bezorgplatform voor eten")
Container(api, "Backend API", "REST API", "Verwerkt bestellingen en gebruikersdata")
Container(auth, "Auth Service", "OAuth2 Service", "Beheert authenticatie en autorisatie")
Container(payment, "Payment Service", "Betaalservice", "Verwerkt betalingen")
Container(notification, "Notification Service", "Notificaties", "Stuurt push/sms notificaties")
ContainerDb(db, "Database", "SQL Database", "Slaat bestellingen, gebruikers en restaurants op")

Rel(api, auth, "OAuth2 tokens")
Rel(api, payment, "Betaalverzoeken")
Rel(api, notification, "Stuurt notificaties")
Rel(api, db, "Leest/Schrijft")
Rel(api, system, "Verwerkt bestellingen voor")

@enduml

' Uber Eats Backend Component Diagram (voorbeeld 2)

LAYOUT_WITH_LEGEND()

System_Boundary(c2, "Uber Eats Backend") {
Component(orderService, "Order Service", "Java/Spring Boot", "Afhandelen van bestellingen")
Component(paymentService, "Payment Service", "Go", "Verwerken van betalingen")
Component(notificationService, "Notification Service", "Node.js", "Versturen van notificaties")
Component(db, "Database", "PostgreSQL", "Opslag van data")
}
Rel(orderService, paymentService, "Vraagt betaling aan")
Rel(orderService, notificationService, "Stuurt status updates")
Rel(orderService, db, "Leest/schrijft bestellingen")
Rel(paymentService, db, "Leest/schrijft betalingen")
@enduml

C4 Component diagram with:

  • 4 components: Order Service, Payment Service, Notification Service, Database
  • 9 relationships:
    • Backend API oAuth2 tokens Auth Service
    • Backend API betaalverzoeken Payment Service
    • Backend API stuurt notificaties Notification Service
    • Backend API leest/Schrijft Database
    • Backend API verwerkt bestellingen voor Uber Eats
    • Order Service vraagt betaling aan Payment Service
    • Order Service stuurt status updates Notification Service
    • Order Service leest/schrijft bestellingen Database
    • Payment Service leest/schrijft betalingen Database

Voorbeeld 3: Mobile App

ae466d023a351cbdb774e3310e4755aa

PlantUML broncode voor "Uber Eats Mobile App Container diagram"
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml

' Uber Eats Mobile App Component Diagram (voorbeeld 3)

LAYOUT_WITH_LEGEND()

Person(customer, "Klant", "Gebruikt mobiele app om te bestellen")
System_Boundary(c3, "Uber Eats Mobile App") {
Component(mobileUI, "Mobile UI", "Flutter", "Mobiele gebruikersinterface")
Component(locationService, "Location Service", "Swift/Kotlin", "Locatiebepaling en tracking")
Component(apiClient, "API Client", "Retrofit", "Communicatie met backend API")
}
Rel(customer, mobileUI, "Gebruikt")
Rel(mobileUI, apiClient, "Doet API-aanroepen")
Rel(mobileUI, locationService, "Gebruikt locatie")
@enduml

C4 Component diagram with:

  • 3 components: Mobile UI, Location Service, API Client
  • 3 relationships:
    • Klant gebruikt Mobile UI
    • Mobile UI doet API-aanroepen API Client
    • Mobile UI gebruikt locatie Location Service

Voorbeeld 4: Volledig platform

2057ca70207cad9867ae17364369a33f

PlantUML broncode voor "Uber Eats Volledig Platform Container diagram"
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml

LAYOUT_WITH_LEGEND()

System(system, "Uber Eats", "Bezorgplatform voor eten")
Container(api, "Backend API", "REST API", "Verwerkt bestellingen en gebruikersdata")
Container(monitoring, "Monitoring Service", "Monitoring", "Houdt systeemgezondheid in de gaten")
Container(logging, "Logging Service", "Logging", "Verzamelt en analyseert logs")
ContainerDb(db, "Database", "SQL Database", "Slaat bestellingen, gebruikers en restaurants op")

Rel(api, monitoring, "Stuurt metrics")
Rel(api, logging, "Stuurt logs")
Rel(api, db, "Leest/Schrijft")
Rel(api, system, "Verwerkt bestellingen voor")

@enduml

C4 Container diagram with:

  • 4 containers:
    • Backend API (REST API)
    • Monitoring Service (Monitoring)
    • Logging Service (Logging)
    • Database (SQL Database) [database]
  • 4 relationships:
    • Backend API stuurt metrics Monitoring Service
    • Backend API stuurt logs Logging Service
    • Backend API leest/Schrijft Database
    • Backend API verwerkt bestellingen voor Uber Eats
Voorbeeld: Dynamic Container Diagram (Uber Eats bestelproces)

Twee varianten van een dynamic diagram

Er zijn verschillende manieren om een dynamisch proces te visualiseren die je moet kennen. Hieronder zie je twee varianten: een standaard UML sequence diagram (zoals studenten vaak al kennen) en een C4-PlantUML dynamic diagram (volgens de C4-standaard, aansluitend bij de andere containerdiagrammen).

UML Sequence Diagram (standaard)

Dit is een klassiek UML sequence diagram, géén C4-PlantUML. Je ziet deze stijl vaak in eerdere vakken of in algemene UML-tools.

befe52f0d7da5005eb22f2e5f9d71185

PlantUML broncode voor "Dynamic Container Diagram: Bestelproces Uber Eats (UML sequence diagram)"
@startuml
' Dynamic Container Diagram: Bestelproces Uber Eats
' Zie ook: https://c4model.com/example/#Dynamic-Collaboration

actor Klant
participant "Uber Eats App" as App
participant "Backend API" as API
participant "Restaurant Portal" as Restaurant
participant "Payment Service" as Payment
participant "Database" as DB

== Bestelling plaatsen ==
Klant -> App : 1. Voert bestelling in
App -> API : 2. Plaatst bestelling (REST/JSON)
API -> Restaurant : 3. Stuurt bestelling door
Restaurant -> API : 4. Bevestigt ontvangst
API -> Payment : 5. Start betaling
Payment -> API : 6. Betaalstatus terug
API -> DB : 7. Slaat bestelling op
API -> App : 8. Status update
App -> Klant : 9. Toont bevestiging
@enduml

Sequentiediagram met 6 deelnemers: Klant, Uber Eats App, Backend API, Restaurant Portal, Payment Service en Database.

Interacties:

  • Klant roept Uber Eats App.1. Voert bestelling in() aan
  • Uber Eats App roept Backend API.2. Plaatst bestelling (REST/JSON) aan
  • Backend API roept Restaurant Portal.3. Stuurt bestelling door() aan
  • Restaurant Portal roept Backend API.4. Bevestigt ontvangst() aan
  • Backend API roept Payment Service.5. Start betaling() aan
  • Payment Service roept Backend API.6. Betaalstatus terug() aan
  • Backend API roept Database.7. Slaat bestelling op() aan
  • Backend API roept Uber Eats App.8. Status update() aan
  • Uber Eats App roept Klant.9. Toont bevestiging() aan

In dit diagram zie je de belangrijkste stappen:

  1. De klant voert een bestelling in via de app.
  2. De app stuurt de bestelling naar de backend API.
  3. De backend stuurt de bestelling door naar het restaurant.
  4. Het restaurant bevestigt ontvangst.
  5. De backend start het betaalproces.
  6. De betaalservice geeft de status terug.
  7. De backend slaat de bestelling op in de database.
  8. De backend stuurt een statusupdate naar de app.
  9. De app toont de bevestiging aan de klant.

C4-PlantUML Dynamic Diagram

Het onderstaande diagram gebruikt de C4-PlantUML dynamic syntax (C4_Dynamic.puml) zodat de elementen en relaties aansluiten bij de C4-standaard. Hier is de Restaurant Portal als extern systeem (grijs) gemodelleerd, wat correcter is volgens de C4-regels.

2b117e27b95ffb9d33a364477779a645

PlantUML broncode voor "Dynamic Container Diagram (C4-PlantUML): Bestelproces Uber Eats"
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml

' Dynamic C4 Container Diagram: Bestelproces Uber Eats
' Zie ook: https://c4model.com/example/#Dynamic-Collaboration

Person(customer, "Klant")
Container(app, "Uber Eats App", "Mobiele app")
Container(api, "Backend API", "REST API")
System_Ext(restaurant, "Restaurant Portal", "Webapplicatie")
Container(payment, "Payment Service", "Betaalservice")
ContainerDb(db, "Database", "SQL Database")

Rel_D(customer, app, "1. Voert bestelling in")
Rel_D(app, api, "2. Plaatst bestelling (REST/JSON)")
Rel_D(api, restaurant, "3. Stuurt bestelling door")
Rel_D(restaurant, api, "4. Bevestigt ontvangst")
Rel_D(api, payment, "5. Start betaling")
Rel_D(payment, api, "6. Betaalstatus terug")
Rel_D(api, db, "7. Slaat bestelling op")
Rel_D(api, app, "8. Status update")
Rel_D(app, customer, "9. Toont bevestiging")

@enduml

C4 System Context diagram with:

  • 0 actors
  • 1 system: Restaurant Portal

De genummerde pijlen geven de volgorde van interacties weer, en de gebruikte elementen zijn gelijk aan de statische C4-containerdiagrammen.

Reflectievragen:

  • Wat klopt er NIET in het dynamische diagram? (Tip: kijk kritisch naar systeemgrenzen, rollen, interacties, consistentie met het statische diagram)
  • Welke variant vind je duidelijker: de C4-versie of de UML-variant? Waarom?