0 Developer: Design keuzes
Tibo De Peuter edited this page 2025-05-21 09:19:49 +02:00

Architectuur

RESTful API

Dit project implementeert een RESTful API. Hoewel dit een vereiste was van de klant, gaan wij akkoord met deze beslissing om volgende redenen:

  • RESTful API's zijn stateless, waardoor het project beter schaalt, doordat er geen staat moet opgeslagen worden voor elke client.
  • Door voor een RESTful API te kiezen kan er tijdens de ontwikkeling van de API teruggevallen worden op een bestaande set aan regels en richtlijnen.
  • REST API's zijn een standaard.

Een alternatief zou bv. GraphQL kunnen zijn.

Object Relational Mapping (ORM) Patroon: Data Mapper

Data Mapper Patroon in plaats van Active Record Patroon

Dit project maakt gebruik van het Data Mapper Patroon.

  • De backend is zo meer ontkoppeld van de database, waardoor die in de toekomst eenvoudiger uitgewisseld kan worden.
  • Gebruik maken van het Data Mapper Patroon biedt meer flexibiliteit tijdens het ontwerpen van de database.

Zie ook deze vergelijking.

Technologie stack

Programmeertaal: TS

TS in plaats van JS

Dit project wordt geschreven in TypeScript (TS). De klant vroeg een project in JavaScript (JS) of TS. Er werden de volgende overwegingen gemaakt:

  • Statische typering laat toe om typegerelateerde fouten at compile time op te vangen ("type safety").
  • (Meer) ondersteunende tooling zorgt voor een fijnere developer-ervaring.
  • Door een future-proof programmeertaal te kiezen is het project klaar voor de toekomst.
  • Het team heeft een kleine leercurve te gaan, doordat niet iedereen evenveel ervaring heeft met TS.

Uiteindelijk wogen de voordelen zwaarder door dan de nadelen en werd er voor TS gekozen.

ECMAScript Modules (ESM) in plaats van CommonJS (CJS)

Dit project maakt gebruik van ESCMAScript Modules (ESM). Er wordt geen gebruik gemaakt van CommonJS (CJS) omdat:

  • ESM wordt als (meer) future-proof gezien dan CJS. Zo kan dit project langer ontwikkeld worden zonder ernstig refactoring.
  • ESM is deel van de ECMAScript specificatie, waardoor er tijdens de ontwikkeling teruggevallen kan worden op bestaande specificaties als dat nodig is.

Identity Provider (IDP): Keycloak

Dwengo-1 maakt gebruik van OpenID Connect om gebruikers in te loggen. Het is daarom voldoende om een compatibele provider te gebruiken.

Voorlopig werd enkel Keycloak getest, en die wordt ook gebruikt in de voorbeelden. Een overzicht van gekende OpenID Connect providers kunnen hier teruggevonden worden.

Heb je een provider getest? Laat het ons weten.

Caching: Memcached

Om herhalingen van dezelfde request naar de (langzame) dwengo.org API sneller te laten verlopen, maakt Dwengo-1 gebruik van caching. De twee meest gekende manieren om dat te doen zijn Redis en Memcached. Dit project gebruikt Memcached.

Functionaliteit Redis Memcached
Licentie Tri-license BSD 3-Clause
Persistent na herstart Ja Nee
Maximale sleutelgrootte 2G 250 bytes

De licentieveranderingen bij Redis waren uiteindelijk de dealbreaker. We besloten om met de écht open source Memcached te gaan.

Frameworks

Frontend: Vue.js

De frontend van dit project is een Vue.js frontend met Vuetify componenten.

Het Vue.js framework werd gekozen omdat het team daar simpelweg de meeste ervaring in had.

Composition API in plaats van Options API

Vue biedt ondersteuning voor twee workflows. De volgende overwegingen werden gemaakt:

  • Composition API biedt meer mogelijkheden tot herbruikbare code en is flexibeler.
  • Bij Composition API staat alle logica relevant voor één stuk bij elkaar, in tegenstelling tot bij Options API. Zie de afbeelding hieronder als voorbeeld.
  • Composition API wordt aangeraden voor grotere, complexe applicaties.
  • Composition API vergt meer inzicht dan de Options API.

Options API vs. Composition API

Uiteindelijk werd Composition API verkozen boven Options API. Er kan ook gebruik gemaakt worden van src imports voor Single-File Components indien ultieme afsplitsing van HTML, CSS en JS gewenst is.

Vuetify in plaats van Bootstrap Vue

Voor Vue bestaan er twee grote componenten-frameworks: Bootstrap Vue en Vuetify. De keuze ging naar Vuetify omdat het modern is en hoog-level componenten aanbiedt. We geloven dat het een fijne development-workflow biedt en dat er voldoende documentatie bestaat om ons vlot te helpen tijdens de ontwikkeling van het project.

Tanstack

De frontend maakt gebruik van Tanstack om frontend state bij te houden. Meer specifiek wordt er gebruik gemaakt van Tanstack's queries en stores.

Er werden voorlopig geen alternatieven in acht genomen. Heb je een suggestie? Laat het ons weten.

Backend: ExpressJS

De backend maakt gebruik van ExpressJS.

  • Het team heeft veruit de meeste ervaring met ExpressJS in vergelijking met elk ander framework.
  • De documentatie van ExpressJS is uitgebreid.
  • Ondersteuning voor eenvoudig routeren en verschillende HTTP methoden ondersteunen.
  • Ondersteuning voor middlewares (app.use(...)), bv. voor logging.
  • Aan de hand van tools kan een Express server gegenereerd worden, vertrekkende van een OpenAPI spec, of omgekeerd.

Een mogelijk alternatief zou bv. fastify zijn.

Object-Relational-Mapping (ORM): MikroORM

MikroORM in plaats van TypeORM

Na onderzoek waren de twee kandidaten voor ORM MikroORM en TypeORM. De volgende overwegingen werden gemaakt:

  • MikroORM concentreert zich op simpliciteit en developer-ervaring.
  • MikroORM heeft minder (geavanceerde) functies dan TypeORM. Dit kan als positief gezien worden als je de bijhorende leercurve in acht neemt.
  • TypeORM is meer robuust dan MikroORM, doordat het ouder is. TypeORM accepteert geen nieuwe feature requests en focust zich enkel nog op stabiliteit.

Uiteindelijk werd MikroORM boven TypeORM verkozen, omdat MikroROM als moderner aangezien werd en de documentatie uitgebreid genoeg is.

Andere alternatieven maken ofwel geen gebruik van Data Mapper Patroon, of ondersteunen bijvoorbeeld moeilijker ESM.

Testing: Vitest + Playwright

Unit testing: Vitest in plaats van Jest

Dit project maakt gebruik van Vitest voor unit testing. Vitest werd vergeleken met Jest en Mocha:

Vitest Jest Mocha
Simpel op te zetten Extra configuratie vereist Modulair, veel extra configuratie vereist
Simpel en snel Simpel Complex
Biedt integratie met frontend framework Vue.js
Ondersteunt ESM ESM ondersteuning is experimenteel
Minder documentatie Uitgebreide documentatie, wordt al gebruikt in Learning Object Repository

Hieruit werd besloten om Vitest te gebruiken om zowel de frontend als de backend te testen.

Zie ook deze vergelijking.

Integration testing: Playwright

Voor het schrijven van integratietesten maakt dit project gebruik van Playwright, om de volgende redenen:

  • Playwright ondersteunt TS natively en maakt het eenvoudig om meerdere browsers te testen.
  • Uitgebreide documentatie.
  • Zij die ervaring hebben met integratietesten in Node/JavaScript hebben de meest ervaring met Playwright.