DRY January #1
- thim90
- 4 days ago
- 4 min read
Don’t repeat yourself begint bij bewust kiezen waar logica leeft
In januari doen veel mensen een Dry January. Een maand geen alcohol, maar 0.0 IPA’s op de vrijdagmiddagborrel. Soms voor de kerstkilo’s, soms als uitdaging, soms gewoon om patronen te doorbreken.
Deze maand krijgt ook mijn blog een Dry January-thema.
Niet in de kroeg, maar in het Power Platform.
DRY staat voor Don’t Repeat Yourself.
En dat gaat minder over minder code, en veel meer over bewuste architectuurkeuzes.
Het patroon dat je overal ziet
In veel Power Platform oplossingen zie je hetzelfde patroon ontstaan. Een regel begint in een app, duikt later op in een flow en eindigt soms zelfs in backend-logica.
Dat gebeurt zelden expres. Vaak groeit het zo. Soms door gebrek aan platformbrede kennis, soms omdat water nu eenmaal de weg van de minste weerstand kiest.
Het werkt allemaal prima... totdat het aangepast moet worden.
Dan blijkt dat dezelfde regel meerdere keren bestaat, net anders geïnterpreteerd wordt en geen duidelijke eigenaar heeft.
En dat is geen Power Apps-probleem.
Dat is geen Flow-probleem.
Dat is een architectuurprobleem.
DRY gaat niet over hergebruik, maar over verantwoordelijkheid
DRY betekent niet: “zo min mogelijk regels code”.
DRY betekent: “één plek die verantwoordelijk is voor een regel”.
Binnen het Power Platform heb je meerdere lagen:
Client (Canvas App, Model-Driven Apps, Custom Pages, Portal Pages etc..)
Orchestratie
Server
De kernvraag is niet hoe je iets hergebruikt, maar waar een regel thuishoort.
Daarbij spelen ook non-functional requirements een rol. Wat acceptabel is voor een kleine interne app, is dat vaak niet voor een bedrijfskritische oplossing.
Het Power Platform bestaat uit meerdere lagen. Daarom begin ik deze serie bewust aan de rand van het platform, bij de client. Deze serie gaat over DRY op meerdere niveaus. Vandaag start ik expres klein: DRY binnen één Canvas app.
Voor Model-Driven Apps bestaan vergelijkbare afwegingen, bijvoorbeeld tussen JavaScript en Business Rules.
Maar dat is stof voor een andere keer.
Waarom starten met User Defined Functions
User Defined Functions (UDF’s) zijn een eenvoudige manier om herhaling binnen één Canvas app te stoppen.
En dat is meteen een belangrijke nuance.
Een UDF is géén platform-brede oplossing.
Een UDF:
leeft binnen de context van één Canvas app
is niet beschikbaar voor andere apps
draait volledig client-side
Zie het dus niet als “gecentraliseerde Power Platform logica”, maar als één duidelijke definitie binnen één app.
Dat verschil is essentieel.

Wat een User Defined Function wél is
Een UDF is een herbruikbare Power Fx functie die leeft binnen één Canvas app.
In de praktijk zijn UDF’s bedoeld voor beslis- en berekeningslogica, maar ze kunnen ook gedrag bevatten en dus geen waarde retourneren.
In de meeste gevallen zijn UDF’s het meest leesbaar en onderhoudbaar als ze zich gedragen als input → output functies.
Zodra een UDF vooral gedrag gaat uitvoeren, moet je jezelf afvragen of dat gedrag niet beter thuis hoort in een component, een event of elders. Al zijn er natuurlijk ook voldoende situaties denkbaar waarbij dit een prima oplossing is.
Samengevat, UDF zijn geschikt voor:
Validaties
Beslislogica
Eenvoudige businessregels
Consistente berekeningen
En minder geschikt voor:
Het afdwingen van regels
Data-integriteit
Logica die altijd moet gelden
Voorbeeld: één definitie, geen wildgroei
Stel je hebt een app waarin je op verschillende schermen of momenten dezelfde validatie uitvoert.
Bijvoorbeeld bij het invullen van velden, bij het opslaan van het formulier en bij het indienen ervan.
Zonder structuur eindigt dit vaak in Power Fx-spaghetti verspreid over meerdere controls, met de stille hoop dat alles hetzelfde valideert.
Met een UDF maak je de intentie expliciet:
fxValidRequest(type: Text; amount:Number) : Boolean =
{
!IsBlank(amount) And Switch(
type;
"CategoryA";
amount > 0 And amount <= 1000;
"CategoryB";
amount > 1000 And amount <= 5000;
"CategoryC";
amount > 5000
)
};;Vervolgens kan je deze functie aanroepen vanuit meerdere controls. In dit voorbeeld het tonen van een notificatie op het moment dat de combinatie van Amount en Type niet klopt.

In theorie had de UDF function ook de notificatie kunnen sturen.
fxValidRequest(type: Text; amount:Number) : Void =
{
With(
{
valid: !IsBlank(amount) And Switch(
type;
"CategoryA";
amount > 0 And amount <= 1000;
"CategoryB";
amount > 1000 And amount <= 5000;
"CategoryC";
amount > 5000
)
};
If(
!valid;
Notify(
"Invalid";
NotificationType.Error
)
)
)
};;In dat geval was de aanroep vanuit de control nog simpeler:

Echter, in het scenario dat beschreef zou dat een niet wenselijk zijn. Waarschijnlijk omdat je afhandeling bij het indienen anders zou willen dan puur een notificatie. Bijvoorbeeld omdat je de indienen knop alleen beschikbaar wilt maken als de combinatie valide is.
Door deze logica te verplaatsen naar een UDF ontstaat er één duidelijke definitie.
Dit levert concreet op:
één plek om (validatie) logica te onderhouden
voorspelbaar gedrag binnen de App
betere leesbaarheid en beheersbaarheid
Dat laatste wordt vaak onderschat. Voor een collega of nieuwe ontwikkelaar is het veel eenvoudiger om te begrijpen wat de app doet, zonder eerst een telefoonboek aan Power Fx-regels door te ploegen.
Eén duidelijke functie vertelt al veel over de logica binnen een app.
UDF’s zijn bewust lokaal
En dit is belangrijk om hardop te zeggen.
User Defined Functions lossen geen platformprobleem op. Ze lossen een lokaal probleem op.
Maar juist daardoor doen ze iets waardevols: ze centraliseren functies die meerdere malen in de app gebruikt worden.
Als je merkt dat dezelfde UDF in meerdere apps nodig is en dezelfde regel steeds terugkomt dan is dat geen reden om te kopiëren. Dat is een signaal dat deze kennis waarschijnlijk niet langer thuishoort in de client. Wellicht dat Custom API/Plugins of component libraries dan een betere oplossing zijn.
Stay tuned for more!


Comments