I QuestGame-projektet har vi valgt at strukturere backenden efter Vertical Slice Architecture (VSA). I stedet for at organisere løsningen ud fra tekniske lag arbejder vi ud fra de funktioner og use cases, som systemet skal understøtte.
Det betyder i praksis, at vi forsøger at færdiggøre én use case ad gangen. Når vi eksempelvis arbejder med Create Quest, fokuserer vi på hele flowet fra requesten rammer API’et, til data bliver valideret og gemt i databasen. Først derefter bevæger vi os videre til næste use case.
Det holder udviklingsflowet nemt og overskueligt, fordi vi hele tiden ved præcist hvilken feature vi arbejder på – og nemt kan finde rundt i relevante klasser og mapper.
Hvad er Vertical Slice Architecture?
I en traditionel lagdelt arkitektur opdeles kode ofte efter teknisk ansvar:
- Controllers
- Services
- Repositories
- Domain
- Infrastructure
Vertical Slice Architecture vender i høj grad denne struktur på siden. Her organiseres kode i stedet efter den funktionalitet, den understøtter:
Features
├── Quests
│ ├── CreateQuest
│ ├── GetQuest
│ └── UpdateQuest
├── Users
│ ├── CreateUser
│ └── UpdateUser
└── QuestSessions
├── JoinQuestSession
└── StartQuestSession
Hver slice indeholder dermed det, der er nødvendigt for at gennemføre den pågældende use case.
Det kan også illustreres sådan:

En CreateQuest-slice (som vil udgøre en vertikal gul streg jf. illustrationen) kan eksempelvis indeholde request/DTO, validering, endpoint og handler samt den nødvendige kommunikation med EF Core.
Pointen er ikke, at hver slice nødvendigvis skal indeholde præcis de samme komponenter. Tværtimod bør en slice kun indeholde det, som den konkrete use case har behov for.
Én use case ad gangen
Denne tankegang passer godt sammen med vores arbejdsmetode i QuestGame.
I stedet for først at bygge alle controllers, derefter alle services og til sidst databaseadgangen, tager vi udgangspunkt i systemets use cases.
Et forsimplet flow for Create Quest kan eksempelvis være:
HTTP Request
↓
CreateQuestEndpoint
↓
Validation
↓
CreateQuestHandler
↓
AppDbContext
↓
PostgreSQL
Når dette flow fungerer, har vi en sammenhængende funktion fra API til database.
Det gør også arbejdet lettere at afgrænse. Når jeg arbejder med backend og database, kan jeg koncentrere mig om de databasebeslutninger, der faktisk er nødvendige for den aktuelle use case, frem for at forsøge at designe hele systemet på forhånd.
Vertical Slice Architecture vs. Clean Architecture
Jeg har tidligere arbejdet med Clean Architecture, hvor løsningen eksempelvis opdeles Domain, Application, Infrastructure og Presentation.
Clean Architecture har en stor fordel i sin tydelige opdeling af ansvar. Domænelogikken kan holdes uafhængig af frameworks og databaseimplementeringer, og afhængighederne mellem lagene er forholdsvis eksplicitte. Det er nyttigt i store komplekse systemer, netop fordi lagdelingen er organiseret efter ansvar.
Til gengæld kan selv en forholdsvis simpel funktion ende med at være fordelt over mange projekter og mapper, hvorved det for en relativt lille applikation kan blive en tung proces at holde styr på afhængigheder og opretholdelse af korrekt lagdeling.
En feature kan eksempelvis kræve ændringer i:
API
Application
Domain
Infrastructure
Det kan give en meget struktureret løsning, men også mere indirektion og boilerplate.
Med Vertical Slice Architecture ligger den kode, der ændrer sig sammen, i højere grad også sammen.
Jeg har med dette kunnet konstatere nogle fordele:
- Det er lettere at finde al kode til en bestemt use case.
- Features kan udvikles mere uafhængigt af hinanden.
- Der er mindre behov for generiske services og repositories.
- Arkitekturen passer naturligt til use case-baseret udvikling.
Der er dog også ulemper.
Når hver feature får større frihed, kan der lettere opstå gentagelser mellem slices. Det kræver samtidig disciplin at undgå, at forretningsregler bliver implementeret forskelligt flere steder.
VSA betyder derfor ikke, at arkitekturprincipperne fra Clean Architecture skal ignoreres. Vi kan stadig beskytte domænet, holde infrastrukturen adskilt, anvende dependency injection og sørge for tydelige ansvarsområder.
Forskellen ligger primært i, hvordan vi organiserer systemet og udviklingsarbejdet.
Vores valg i QuestGame
Til QuestGame oplever jeg Vertical Slice Architecture som et godt match, fordi projektet består af relativt tydelige use cases som Create Quest, Join QuestSession og Update User.
Vi kan tage én funktion ad gangen og følge den hele vejen gennem systemet. Det giver korte feedback-loops og gør det samtidig lettere at dokumentere, hvad der faktisk er implementeret.
Jeg ser derfor ikke nødvendigvis VSA og Clean Architecture som direkte modsætninger. Flere af principperne fra Clean Architecture kan stadig anvendes, mens Vertical Slice Architecture bestemmer den overordnede organisering omkring features og use cases.
