De wereld heeft zich in de laatste tientallen jaren steeds meer verplaatst naar het internet, en webapplicaties zijn de nieuwe werkplekken en commerciële winkels geworden. Om de verscheidenheid aan doelen die moderne webapps dienen op te vangen, moet elk van hen worden ontworpen voor hoge prestaties en aanpasbaarheid.

Door een architectuur voor een webapplicatie te maken los je dit probleem op.

De architectuur van webapplicaties definieert hoe de verschillende onderdelen van een webapplicatie zijn gestructureerd. Deze architectuur is zeer specifiek voor de aard en het doel van de webapplicatie. Het kiezen van de verkeerde architectuur voor je webapp kan een ravage aanrichten in je bedrijf.

In deze handleiding zullen we het concept van de architectuur van webapplicaties uitsplitsen en begrijpen hoe die de eindgebruikerservaring van je applicatie beïnvloedt. Aan het eind bekijken we ook enkele van de best practices die je kunt toepassen om het meeste uit je webapplicatie te halen.

Wat is webapplicatie-architectuur?

Laten we, om de discussie te beginnen, beginnen met de definitie van webapplicatie-architectuur.

Eenvoudig gezegd is de architectuur van een webapplicatie een overzicht van hoe de verschillende onderdelen van je webapp op elkaar inwerken.

Dit kan zo simpel zijn als het definiëren van de relatie tussen de client en de server. Maar het kan ook zo complex zijn als het definiëren van de onderlinge relaties tussen een lading gecontaineriseerde backendservers, loadbalancers, API gateways en gebruikersgerichte single-page frontends.

Dat gezegd hebbende: het gaat echter zelden over het kiezen van de programmeertaal waarin je je code schrijft.

Hoe je je webapp ontwerpt speelt een belangrijke rol in zowel de bruikbaarheid als de kostenoptimalisatie. Hier zie je hoe een voorbeeld van een webapparchitectuur er op papier uitziet:

Componentendiagram van een aanbevelingswebapp die laat zien hoe verschillende componenten, zoals clients, database-instanties, services, enzovoort, met elkaar omgaan.
Architectuurdiagram voor een aanbevelingsapp. (Beeldbron: Wikipedia)

Waarom is webapplicatie-architectuur belangrijk?

De architectuur van webapplicaties is zonder twijfel een van de belangrijkste onderdelen van je webapplicatie. Als je ervoor kiest om je webapplicatie te ontwikkelen met een specifieke architectuur in gedachten, ben je verzekerd van veel voordelen als het gaat om het onderhoud en de groei van je applicatie.

Het kiezen van de juiste architectuur versterkt deze voordelen echter nog verder.

Hier zijn enkele van de belangrijkste redenen waarom je serieus zou moeten overwegen een architectuur voor webapplicaties te kiezen.

Gemakkelijk aanpassen aan bedrijfsbehoeften

Je app is een belangrijke toegangspoort tot je bedrijf, en de zakelijke behoeften evolueren mee met de veranderende markt. Om bij te blijven wil je dat je app flexibel genoeg is om zich aan te passen aan je veranderende bedrijfsbehoeften. En als je een app bouwt zonder rekening te houden met ingebouwde flexibiliteit, zul je steeds meer tijd en moeite kwijt zijn aan het maken van kleine aanpassingen in je app.

De juiste webapplicatie-architectuur houdt nu al rekening met sommige veranderingen die je bedrijf in de toekomst nodig zou kunnen hebben. Als je bijvoorbeeld weet dat je een e-commerce applicatie bouwt die op een dag zal worden opgeschaald en een breed scala aan diensten zal leveren aan een groot aantal klanten, dan zou het kiezen van een microservices-architectuur boven een monolithische je meer flexibiliteit bieden.

Aan de andere kant, als je een interne app voor je bedrijf bouwt met slechts één of twee vaste eisen, kun je kiezen voor een eenvoudigere monoliet om de ontwikkeling te versnellen en je codebase schoon te houden.

Georganiseerde ontwikkeling

Zoals we al eerder zeiden, biedt de juiste webapparchitectuur je een overzichtelijker stappenplan voor ontwikkeling. Architectuur zorgt voor voldoende modulariteit in je systeem om componenten te isoleren als dat nodig is, en je krijgt de vrijheid om voor elk van je modules en componenten de juiste projectstructuur te kiezen als dat nodig is.

Als je in appontwikkeling duikt zonder een architectuur in gedachten, loop je het risico tijd en geld te verspillen aan het reorganiseren van je componenten en het opstellen van nieuwe regels om de samenwerking tussen je teamleden te vergemakkelijken – tijd en geld die anders elders besteed hadden kunnen worden.

Beter beheer van de codebase

Naast het schrijven van de code van je app, besteed je ook een aanzienlijke hoeveelheid tijd aan het beheer ervan. Het organiseren van je projectbestanden, het opsplitsen van je app in modules, en het opzetten van aangepaste pijplijnen zijn slechts enkele van de taken die actief onderhoud vereisen om de ontwikkeling soepel te laten verlopen.

De juiste webapparchitectuur maakt het je gemakkelijk om wijzigingen aan te brengen. Je kunt componentspecifieke best practices toepassen, de pijnpunten van je app van elkaar scheiden, en elke feature onafhankelijk en los gekoppeld houden. Het is niet zo dat deze dingen niet zonder architectuur kunnen; het is wel zo dat de juiste architectuur het allemaal veel eenvoudiger maakt.

Het volgen van een vooraf gedefinieerde architectuur maakt het ook gemakkelijk om je applicaties sneller te ontwikkelen. De juiste architectuur in combinatie met een goede versiebeheerstrategie kan jouw developers in staat stellen om parallel met elkaar te werken en sneller features te bouwen.

Een webapparchitectuur maakt je applicatie daarnaast toekomstbestendig. Als je eenmaal een solide strategie hebt bepaald voor de organisatie van de onderdelen van je app, kun je die onderdelen gemakkelijk één voor één migreren naar nieuwere technologieën zonder je hele applicatie opnieuw te hoeven maken.

Verbeterde beveiliging

De meeste webapparchitecturen houden rekening met beveiliging bij het structureren van componenten. Ontwikkelaars kunnen van tevoren de maatregelen en praktijken plannen om de beveiliging van de app te verbeteren voordat hij wordt uitgerold naar de gebruikers.

Zo is het bouwen van een OTT video streaming app die zowel betaalde als gratis content aanbiedt met behulp van microservices zinvoller, omdat je met de microservicesarchitectuur je app kunt opsplitsen in bedrijfsvriendelijke componenten, zoals gebruikersauthenticatie en gratis of betaalde contentstreaming. Als je gebruikersauthenticatiemodule ooit uitvalt, kun je je app eenvoudig configureren om de toegang tot de betaalde contentmodule te beperken totdat de auth weer werkt, terwijl de gratis contentmodule nog steeds beschikbaar is voor je gebruikers.

In een ander geval, waarin dezelfde app is ontworpen als een strak gekoppelde monoliet, zou een uitgevallen authenticatiedienst betekenen dat ofwel de applicatie uitvalt, ofwel betaalde inhoud gratis beschikbaar wordt gesteld – resultaten die je koste wat kost wilt vermijden.

Hoe werkt de webapplicatie-architectuur?

Voordat we het hebben over de architectuur van webapplicaties, is het belangrijk te begrijpen hoe een eenvoudige website werkt:

  1. De gebruiker voert de URL van je app in de adresbalk van de browser in of klikt op een link.
  2. De browser zoekt de URL op in de DNS servers en identificeert het IP-adres van je app.
  3. De browser stuurt een HTTP verzoek naar jouw app.
  4. Je app antwoordt met de juiste content (meestal een webpagina).
  5. De browser rendert de webpagina op het scherm.

Als je er wat dieper naar zou kijken, zie je hier hoe een webapplicatie een verzoek afhandelt:

  1. De gebruiker stuurt een verzoek naar je app via je frontendgebruikersinterface.
  2. Als je een relevante cache hebt ingesteld, zou de app eerst controleren of hij een geldig record heeft dat direct naar de client kan worden teruggestuurd. Zo ja, dan wordt de gecachete content teruggestuurd, en wordt het verzoek gemarkeerd als voltooid.
  3. Als er geen cache is, wordt het verzoek doorgestuurd naar de loadbalancer.
  4. De loadbalancer identificeert een serverinstantie die beschikbaar is om het verzoek af te handelen en stuurt het door.
  5. De serverinstantie verwerkt het verzoek en roept zo nodig externe API’s aan.
  6. Zodra de resultaten op één plaats zijn verzameld, stuurt de server het antwoord terug naar de loadbalancer.
  7. De loadbalancer stuurt het antwoord terug naar de API gateway, die het op zijn beurt doorstuurt naar de gebruiker in de frontend client. Het verzoek wordt dan gemarkeerd als voltooid.

Soorten webapplicatie-architectuur

Nu je een basisidee hebt van wat webapplicatie-architectuur is, laten we eens in detail kijken naar een paar van de populaire typen webapplicatie-architectuur die overal op het web worden gebruikt.

Single-page architectuur

De architectuur van een single-page applicatie (SPA) is net zo eenvoudig als de naam: de hele applicatie is gebaseerd op een enkele pagina. Zodra de gebruiker je app ophaalt, hoeft hij niet naar andere webpagina’s te navigeren. De app is dynamisch genoeg gemaakt om schermen op te halen en te renderen die voldoen aan de eisen van de gebruikers terwijl ze door de app zelf navigeren.

SPA’s zijn geweldig als het gaat om het bieden van een snelle en naadloze ervaring aan eindgebruikers of consumenten. Ze missen echter de touch van een traditionele website, en ze kunnen moeilijk te optimaliseren zijn voor SEO.

Voordelen van SPA architectuur

Enkele voordelen van SPA architectuur zijn:

  • Je kunt zeer interactieve webapps bouwen.
  • SPA’s zijn gemakkelijk te schalen.
  • Het optimaliseren van SPA’s voor prestaties vergt niet veel inspanning.

Nadelen van SPA architectuur

Enkele nadelen van SPA architectuur zijn:

  • SPA’s beperken de flexibiliteit met hyperlinks en SEO.
  • De eerste render is meestal traag.
  • Navigatie door de app kan onintuïtief zijn.

Progressive webapplicatie architectuur

De progressive webapplicatie (PWA) architectuur bouwt voort op de single-page-architectuur door offline mogelijkheden te bieden voor je webapp. Technologieën als Capacitor en Ionic worden gebruikt om PWA’s te bouwen die gebruikers een uniforme ervaring op verschillende platforms kunnen bieden.

Net als SPA’s zijn PWA’s soepel en naadloos. Met de extra mogelijkheid van installatie op apparaten van gebruikers (via service workers) krijgen je gebruikers een meer uniforme ervaring met je applicatie.

Tegelijkertijd kan het lastig zijn om zulke apps te optimaliseren voor SEO, en updates op geïnstalleerde apps kunnen moeilijk te pushen zijn.

Voordelen van de PWA architectuur

Er zijn veel voordelen van de PWA architectuur, waaronder:

  • Apps lopen zeer soepel en bieden cross-platform compatibiliteit.
  • Schaalbaarheid is eenvoudig.
  • Offline toegang en device-native API’s zoals backgroundworkers en push-meldingen zijn mogelijk voor developers.

Nadelen van PWA architectuur

Enkele nadelen van PWA architectuur kunnen zijn:

  • Er is beperkte ondersteuning voor linkbeheer en SEO.
  • Het pushen van updates naar offline PWA’s is complexer dan bij native apps.
  • Er is beperkte ondersteuning voor PWA’s in webbrowsers en besturingssystemen.

Server-side-rendered architectuur

Bij server-side rendering (SSR) worden frontendwebpagina’s op een backendserver gerenderd nadat ze door de gebruiker zijn opgevraagd. Dit helpt de belasting van het client-apparaat te verminderen, omdat het een statische HTML, CSS en JS webpagina ontvangt.

SSR apps zijn erg populair onder blogs en e-commercewebsites. Dit komt omdat ze linkbeheer en SEO vrij eenvoudig maken. Ook is de eerste render voor SSR apps vrij snel, omdat de client geen JS code hoeft te verwerken om de schermen te renderen.

Voordelen van SSR architectuur

Enkele van de voordelen van SSR architectuur worden hieronder opgesomd:

  • Deze apps zijn geweldig voor SEO-heavy websites.
  • De first-page load is in de meeste gevallen vrijwel direct.
  • Je kunt ze koppelen aan een cachingservice om de prestaties van je app verder te verbeteren.

Nadelen van de SSR architectuur

Enkele nadelen van het gebruik van de SSR architectuur zijn:

  • Het wordt niet aanbevolen voor complexe of zware webpagina’s, omdat de server tijd nodig kan hebben om de pagina volledig te genereren, wat resulteert in een vertraagde eerste render.
  • Het wordt meestal aanbevolen voor apps die niet veel aandacht besteden aan de gebruikersinterface en alleen op zoek zijn naar verhoogde schaalbaarheid of veiligheid.

Pre-rendered applicatie architectuur

Pre-rendered applicatie-architectuur is ook bekend als static site generation architectuur. In deze architectuur worden de frontendwebpagina’s van de app vooraf gegenereerd en opgeslagen als gewone HTML, CSS en JS bestanden op de server. Zodra een gebruiker om een pagina vraagt, wordt die direct opgehaald en aan hem getoond. Dit maakt de webapp zeer snel, met minimale laadtijden van welke aard dan ook. Deze architectuur verhoogt echter de bouwtijd van de app, omdat de webpagina’s tijdens het bouwproces worden gerenderd.

Pre-rendered webapps zijn geweldig voor als je statische content wilt genereren, zoals blogs of productgegevens die niet vaak veranderen. Je kunt ook gebruik maken van templates om het ontwerp van je webpagina’s te vereenvoudigen. Het is echter vrijwel onmogelijk om met deze architectuur dynamische webapps te bouwen. Als je op zoek bent naar een zoekpagina die de zoekopdracht in zijn pad neemt (zoiets als https://myapp.com/search/foo+bar), ben je hier aan het verkeerde adres.

Omdat elke mogelijke route van de app vooraf wordt gerenderd tijdens het bouwproces, is het onmogelijk om dynamische routes te hebben zoals hierboven, omdat er oneindig veel mogelijkheden zijn die niet vooraf kunnen worden gerenderd tijdens het bouwen (en het heeft ook geen zin om dat te doen).

Voordelen van pre-rendered architectuur

Een paar van de belangrijkste voordelen van een pre-rendered applicatie architectuur zijn:

  • Webpagina’s worden gegenereerd in pure HTML, CSS en JS; daarom zijn hun prestaties vergelijkbaar met die van apps die gebouwd zijn met vanilla JS.
  • Als je alle mogelijke routes van je app kent, wordt SEO super eenvoudig.

Nadelen van pre-rendered architectuur

Zoals bij elk architectuurmodel heeft ook pre-rendered zijn nadelen:

  • Dynamische content kan met deze apps niet geleverd worden.
  • Elke wijziging aan de webapp betekent dat de app helemaal opnieuw moet worden opgebouwd en gedeployed.

Isomorphic applicatie architectuur

Isomorphic apps zijn apps die een mengeling zijn van server-side-rendered apps en SPA’s. Dit betekent dat zulke apps eerst op de server worden gerenderd als een normale server-side-rendered app. Zodra ze door de client worden ontvangen, hydrateert de app zichzelf en hecht de virtuele DOM aan voor snellere en efficiëntere clientverwerking. Hierdoor wordt de app in wezen een single-page applicatie.

Isomorphic brengt het beste van beide werelden samen. Je krijgt supersnelle verwerking en gebruikersinterface op de client, dankzij de SPA. Je krijgt ook een snelle initiële render en volwaardige SEO en linking ondersteuning, dankzij de server-side rendering.

Voordelen van isomorphic architectuur

Dit zijn slechts enkele van de voordelen van een isomorphic applicatie-architectuur:

  • Isomorphic apps hebben een supersnelle initiële render en volledige ondersteuning voor SEO.
  • Deze apps presteren ook goed op de client, omdat ze na het laden veranderen in een SPA.

Nadelen van Isomorphic architectuur

Enkele nadelen van isomorphic applicatie architectuur kunnen zijn:

  • Het opzetten van zo’n app vereist vaardig talent.
  • De opties van de techstack zijn beperkt als het gaat om het ontwerpen van een Isomorphic app. Je kunt slechts kiezen uit een handvol (meestal) JS-gebaseerde bibliotheken en frameworks.

Servicegeoriënteerde architectuur

De servicegeoriënteerde architectuur behoort tot de meest populaire alternatieven voor de traditionele monolith manier van apps bouwen. In deze architectuur worden de webapps opgedeeld in diensten die elk een functionele bedrijfseenheid vertegenwoordigen. Deze diensten zijn losjes aan elkaar gekoppeld en communiceren met elkaar via het medium message passing.

Servicegeoriënteerde architectuur voegt stabiliteit en schaalbaarheid toe aan de techstack van je applicaties. De omvang van diensten in SOA is echter niet duidelijk gedefinieerd en is gewoonlijk gebonden aan bedrijfscomponenten, niet aan technische componenten; vandaar dat onderhoud soms een probleem kan zijn.

Voordelen van servicegeoriënteerde architectuur

De belangrijkste voordelen van servicegerichte architectuur zijn:

  • Deze architectuur helpt om zeer schaalbare en betrouwbare apps te bouwen.
  • Componenten zijn herbruikbaar en worden gedeeld om ontwikkeling en onderhoud te verbeteren.

Nadelen van servicegeoriënteerde architectuur

Hier volgt een lijst van mogelijke nadelen van het gebruik van servicegeoriënteerde architectuur:

  • SOA apps zijn nog steeds niet 100% flexibel, omdat de omvang en reikwijdte van elke dienst niet vastliggen. Er kunnen diensten zijn ter grootte van bedrijfsapplicaties die moeilijk te onderhouden zijn.
  • Het delen van componenten introduceert afhankelijkheden tussen diensten.

Microservices architectuur

De microservices architectuur is ontworpen om de problemen met de servicegeoriënteerde architectuur op te lossen. Microservices zijn nog meer modulaire componenten die bij elkaar passen om een webapp te bouwen. Microservices richten zich echter op het klein houden van elke component en met een begrensde context. Gebonden context betekent in wezen dat elke microservice zijn code en gegevens aan elkaar heeft gekoppeld met minimale dependencies van andere microservices.

De microservices architectuur is waarschijnlijk de beste architectuur om apps te bouwen die tot doel hebben ooit op te schalen naar duizenden en miljoenen gebruikers. Elk onderdeel is veerkrachtig, schaalbaar en gemakkelijk te onderhouden. Het onderhouden van de DevOps levenscyclus voor een op microservices gebaseerde app vereist echter extra inspanningen; daarom is het misschien niet zo geschikt voor kleinere use-cases.

Voordelen van de microservices architectuur

Enkele voordelen van een microservices architectuur zijn:

  • App componenten zijn zeer modulair, onafhankelijk, en kunnen meer hergebruikt worden dan die van de servicegeoriënteerde architectuur.
  • Elke component kan onafhankelijk worden geschaald om aan wisselend gebruikersverkeer te voldoen.
  • Apps op basis van microservices zijn zeer fouttolerant.

Nadelen van microservices architectuur

Een nadeel van microservices architectuur kan zijn:

  • Voor kleinere projecten kan de microservices architectuur te veel inspanning vergen om te onderhouden.

Serverless architectuur

De serverless (serverloze) architectuur is een andere binnenkomer in de wereld van webapp-architecturen. Deze architectuur richt zich op het opsplitsen van je applicatie in termen van de functies die het moet uitvoeren. Vervolgens worden deze functies gehost op FaaS (Function-as-a-Service) platforms als functies die worden aangeroepen als en wanneer er verzoeken binnenkomen.

In tegenstelling tot de meeste andere architecturen op deze lijst, blijven apps die gebouwd zijn met de serverless architectuur niet de hele tijd draaien. Ze gedragen zich net als functies – wachten tot ze worden aangeroepen, en als ze worden aangeroepen, voeren ze het gedefinieerde proces uit en geven ze een resultaat terug. Door deze aard besparen ze op onderhoudskosten en zijn ze zonder veel moeite goed schaalbaar. Het is echter moeilijk om met zulke componenten langlopende taken uit te voeren.

Voordelen van serverless architectuur

Hier zijn de belangrijkste voordelen van een serverless architectuur:

  • Serverless apps zijn zeer en gemakkelijk schaalbaar. Ze kunnen zich zelfs in real-time aanpassen aan het binnenkomende verkeer om de belasting van je infrastructuur te verminderen.
  • Zulke apps kunnen gebruik maken van het pay-per-use prijsmodel van serverless platforms om de infrastructuurkosten te verlagen.
  • Serverless apps zijn vrij eenvoudig te bouwen en te deployen, omdat je alleen maar een functie hoeft te schrijven en die te hosten op een platform zoals Firebase functies, AWS Lambda, enz.

Nadelen van serverloze architectuur

Hieronder staan enkele nadelen van serverloze architectuur:

  • Langlopende taken kunnen kostbaar zijn op zo’n architectuur.
  • Als een functie na lange tijd een verzoek ontvangt, staat dat bekend als een koude start. Koude starts zijn traag en kunnen je eindgebruiker een slechte ervaring bezorgen.

Lagen van webapplicatie-architectuur

Hoewel de webapplicatie-architecturen die je hierboven zag er misschien allemaal heel verschillend uitzien, kunnen hun componenten logisch gegroepeerd worden in welomschreven lagen die helpen een bedrijfsdoel te bereiken.

Presentatielaag

De presentatielaag omvat alles in een webapplicatie dat aan de eindgebruikers wordt getoond. Hoofdzakelijk bestaat de presentatielaag uit de frontendclient. Maar het bevat ook alle logica die je op je backend hebt geschreven om je frontend dynamisch te maken. Dit geeft je de ruimte om je gebruikers te bedienen met UI op basis van hun profiel en eisen.

Drie fundamentele technologieën worden gebruikt om deze laag te bouwen: HTML, CSS en JavaScript. HTML schetst je frontend, CSS maakt hem op, en JS brengt hem tot leven (d.w.z. regelt het gedrag als gebruikers er interactie mee hebben). Bovenop deze drie technologieën kun je elk soort framework gebruiken om je ontwikkeling te vergemakkelijken. Enkele veelgebruikte frontendframeworks zijn Laravel, React, NextJS, Vue, GatsbyJS, enz.

Bedrijfslaag

De bedrijfslaag is verantwoordelijk voor het vasthouden en beheren van de werkende logica van je app. Het is meestal een backendservice die verzoeken van de client accepteert en verwerkt. Het bepaalt waartoe de gebruiker toegang heeft en bepaalt hoe de infrastructuur wordt gebruikt om gebruikersverzoeken te bedienen.

In het geval van een hotelboekingapp, dient je clientapp als een portaal voor gebruikers om hotelnamen en andere relevante gegevens in te typen. Maar zodra de gebruiker op de zoekknop klikt, ontvangt de bedrijfslaag het verzoek en start de logica voor het zoeken naar beschikbare hotelkamers die aan jouw eisen voldoen. De klant ontvangt vervolgens simpelweg een lijst met hotelkamers, zonder enige kennis van hoe deze lijst tot stand is gekomen of zelfs maar waarom de lijstitems zijn gerangschikt op de manier waarop ze zijn verzonden.

De aanwezigheid van zo’n laag zorgt ervoor dat je bedrijfslogica niet wordt blootgesteld aan je klant en, uiteindelijk, de gebruikers. Het isoleren van de bedrijfslogica helpt enorm bij gevoelige operaties zoals het afhandelen van betalingen of het beheren van gezondheidsdossiers.

Persistentielaag

De persistentielaag is verantwoordelijk voor het regelen van de toegang tot je gegevensopslag. Deze fungeert als een extra abstractielaag tussen je datastores en je bedrijfslaag. Hij ontvangt alle gegevensgerelateerde oproepen vanuit de bedrijfslagen en verwerkt ze door veilige verbindingen met de database te maken.

Deze laag bestaat meestal uit een databaseserver. Je kunt deze laag zelf instellen door een database en een databaseserver in je on-prem infrastructuur te voorzien, of kiezen voor een externe/beheerde oplossing van een van de toonaangevende aanbieders van cloud infrastructuur zoals AWS, GCP, Microsoft Azure, enz.

Componenten van webapplicaties

Nu je begrijpt wat de architectuur van een webapplicatie inhoudt, laten we eens in detail kijken naar elk van de componenten waaruit een webapp bestaat. We verdelen deze bespreking in twee grote rubrieken – servercomponenten en clientcomponenten, of backend en frontend componenten.

Serverzijdecomponenten

Serverzijdecomponenten zijn componenten die zich aan de backend van je webapplicatie bevinden. Deze zijn niet direct zichtbaar voor de gebruikers en bevatten de belangrijkste bedrijfslogica en resources voor je webapplicatie.

DNS & routing

DNS bepaalt hoe je app aan het web wordt blootgesteld. DNS records worden gebruikt door HTTP clients, wat ook een browser kan zijn, om verzoeken te vinden en te sturen naar de onderdelen van je app. DNS wordt ook intern gebruikt door je frontendclients om de locatie van je webservers en API eindpunten op te lossen om verzoeken te versturen en gebruikershandelingen te verwerken.

Loadbalancing is een ander populair onderdeel van de architectuur van webapplicaties. Een loadbalancer wordt gebruikt om HTTP verzoeken te verdelen over meerdere identieke webservers. De bedoeling van het hebben van meerdere webservers is om redundantie te behouden die de fouttolerantie verhoogt en het verkeer verdeelt om hoge prestaties te handhaven.

API endpoints worden gebruikt om backenddiensten bloot te stellen aan de frontendapplicatie. Deze helpen de communicatie tussen de client en de server te vergemakkelijken, en soms zelfs tussen meerdere servers.

Gegevensopslag

Gegevensopslag is een cruciaal onderdeel van de meeste moderne applicaties, omdat er altijd appgegevens zijn die over gebruikerssessies heen bewaard moeten worden. Er zijn twee soorten gegevensopslag:

  • Databases: Databases worden gebruikt om gegevens op te slaan voor snelle toegang. Meestal ondersteunen ze de opslag van een kleine hoeveelheid gegevens die regelmatig door je applicatie worden opgevraagd.
  • Datawarehouses: Datawarehouses zijn bedoeld voor het bewaren van historische gegevens. Deze zijn meestal niet vaak nodig in de app, maar worden regelmatig verwerkt om zakelijke inzichten te genereren.

Caching

Caching is een optionele feature die vaak in webapparchitecturen wordt toegepast om content  sneller aan de gebruikers te serveren. Een groot deel van de content van een app is vaak enige tijd repetitief, zo niet altijd. In plaats van het te benaderen vanuit een datastore en het te verwerken alvorens het terug te sturen naar de gebruiker, wordt het vaak gecached. Hier zijn de twee populairste soorten caching die in webapplicaties worden gebruikt:

  • Datacaching: Datacaching betekent een manier voor je app om gemakkelijk en snel toegang te krijgen tot regelmatig gebruikte gegevens die niet vaak veranderen. Technologieën als Redis en Memcache maken caching van data mogelijk om te besparen op dure databasequeries om steeds weer dezelfde gegevens op te halen.
  • Webpaginacaching: Een CDN (Content Delivery Network) cacht webpagina’s op dezelfde manier als Redis gegevens cacht. Vergelijkbaar met hoe alleen data die niet vaak veranderen worden gecachet, wordt meestal aangeraden alleen statische webpagina’s te cachen. Voor server-side-rendered webapps heeft caching niet veel zin, omdat hun content zeer dynamisch moet zijn.

Jobs en services

Naast het geven van een interface aan gebruikers (frontend) en het afhandelen van hun verzoeken (backend), is er nog een iets minder populaire categorie van webappcomponenten. Jobs zijn vaak achtergrondservices die bedoeld zijn om taken te voltooien die niet tijdgevoelig of synchroon zijn.

CRON jobs zijn jobs die op een vaste tijdsperiode steeds opnieuw worden uitgevoerd. Deze jobs worden gepland op de backend om op vaste tijden automatisch onderhoudsroutines uit te voeren. Enkele veel voorkomende voorbeelden hiervan zijn het verwijderen van duplicaten/oude records uit de database, het versturen van herinneringse-mails naar klanten, enz.

Clientzijdecomponenten

Clientzijdecomponenten zijn componenten die direct of indirect aan je gebruikers worden getoond.

Er zijn hoofdzakelijk twee soorten componenten in deze categorie.

Frontend gebruikersinterface

De gebruikersinterface is het visuele aspect van je applicatie. Het is wat je gebruikers zien en waarmee ze interageren om toegang te krijgen tot je diensten.

De frontendinterface is meestal gebouwd op drie populaire technologieën: HTML, CSS en JavaScript. De frontendgebruikersinterface kan een applicatie op zich zijn met een eigen software-ontwikkelingscyclus.

Deze gebruikersinterfaces bevatten niet veel van je bedrijfslogica, omdat ze direct aan je gebruikers worden blootgesteld. Als een kwaadwillende gebruiker probeert je frontendapplicatie te reverse-engineeren, kan hij informatie krijgen over hoe je bedrijf werkt en illegale activiteiten uitvoeren, zoals merkimitatie en datadiefstal.

Omdat de frontendgebruikersinterface direct aan gebruikers wordt getoond, zul je die ook willen optimaliseren voor een minimale laadtijd en responsiviteit. Soms kan dit helpen om je gebruikers een betere ervaring te bieden, waardoor je bedrijfsgroei toeneemt.

Clientzijdebedrijfslogica

Soms moet je wat bedrijfslogica op je client opslaan om eenvoudiger operaties snel uit te voeren. Clientzijdeogica die gewoonlijk in je frontendapplicatie zit, kan je helpen de reis naar de server over te slaan en je gebruikers een snellere ervaring te bieden.

Dit is een optionele feature van de clientzijdecomponenten. In sommige gevallen wordt de bedrijfslogica van de app helemaal aan de clientzijde opgeslagen (vooral als je bouwt zonder traditionele backendserver). Moderne oplossingen zoals BaaS helpen je om onderweg in je frontendapp toegang te krijgen tot veel voorkomende operaties zoals authenticatie, gegevensopslag, bestandsopslag, enz.

Er zijn manieren om deze code te verdoezelen of te verkleinen voordat je hem uitrolt naar je gebruikers om de kans op reverse-engineering te minimaliseren.

Modellen van webapplicatiecomponenten

Er zijn verschillende modellen van webapplicatie-architecturen, elk gebaseerd op de manier waarop webservers verbinding maken met hun gegevensopslag.

Eén server, één database

Het eenvoudigste model is één webserver die verbinding maakt met één database-instantie. Zo’n model is eenvoudig te implementeren en te onderhouden, en het is ook vrij eenvoudig om ermee in productie te gaan.

Door zijn eenvoud is dit model geschikt om te leren en voor kleine experimentele applicaties die niet worden blootgesteld aan veel verkeer. Beginnende developers kunnen deze apps gemakkelijk opzetten en eraan sleutelen om de grondbeginselen van webappontwikkeling te leren.

Dit model zou echter niet in productie gebruikt moeten worden, omdat het zeer onbetrouwbaar is. Een probleem in de server of de database kan leiden tot downtime en bedrijfsverlies.

Meerdere servers, één database

Dit model tilt de applicatie naar een hoger niveau door meerdere servers op te zetten voor redundantie met één gemeenschappelijke database-instantie.

Omdat meerdere webservers tegelijkertijd de database benaderen, kunnen er inconsistentieproblemen ontstaan. Om dat te voorkomen zijn de webservers stateloos ontworpen. Dit betekent dat de servers geen gegevens bewaren tijdens sessies; ze verwerken ze alleen en slaan ze op in de database.

Apps die met dit model zijn gemaakt zijn zeker betrouwbaarder dan die met het vorige model, omdat de aanwezigheid van meerdere webservers de fouttolerantie van de webapp vergroot. Maar omdat de database nog steeds één gemeenschappelijke instantie is, is het de zwakste schakel in de architectuur en kan het een bron van storingen zijn.

Meerdere servers, meerdere databases

Dit model is een van de meest voorkomende, traditionele modellen voor het ontwerpen van webapplicaties.

In dit geval zet je je applicatielogica in als meerdere identieke webserverinstanties, samengebracht achter een loadbalancer. Je gegevensopslag wordt onderhouden over meerdere database-instanties voor extra fouttolerantie.

Je kunt er ook voor kiezen je database op te splitsen over de beschikbare instanties om de prestaties te verbeteren, of duplicaten van de hele data store aan te houden voor redundantie. In beide gevallen zal een storing in één instantie van je database niet leiden tot een volledige uitval van de applicatie.

Dit model wordt zeer gewaardeerd om zijn betrouwbaarheid en schaalbaarheid. Het ontwikkelen en onderhouden van apps met dit model is echter relatief ingewikkeld en vereist kostbare, doorgewinterde developers. Daarom wordt dit model alleen aanbevolen als je op grote schaal bouwt.

Appservices

Terwijl de drie hierboven genoemde modellen goed geschikt zijn voor monolithische applicaties, is er nog een ander model voor modulaire applicaties.

Het applicatiedienstenmodel splitst een app op in kleinere modules op basis van zakelijke functionaliteit. Deze modules kunnen zo klein zijn als een functie of zo groot als een service.

Het idee hier is om elke bedrijfsfeature onafhankelijk en schaalbaar te maken. Elk van deze modules kan zelfstandig verbinding maken met de database. Je kunt zelfs speciale database-instanties hebben die passen bij de schaalbaarheidsbehoeften van je module.

Onder niet-monolithische apps is dit model vrij populair. Oude monolieten worden vaak gemigreerd naar dit model om gebruik te maken van de schaalbaarheid en modulariteit. Het beheer van apps die op zo’n model zijn gebouwd vereist echter vaak doorgewinterde ontwikkelaars, vooral ervaring met DevOps en CI/CD.

Best practices voor webapplicatie-architectuur

Hier zijn wat best practices die je in je webapplicatieproject kunt toepassen om het maximale uit de door jou gekozen webapparchitectuur te halen.

1. Maak je frontend responsief

Dit kan niet genoeg benadrukt worden: Streef altijd naar responsieve frontends. Hoe groot en complex je webapp intern ook is, het wordt allemaal blootgesteld aan je gebruikers via frontend webpagina’s, apps en schermen.

Als je gebruikers deze schermen onintuïtief of traag vinden, blijven ze niet lang genoeg hangen om het technische hoogstandje van je webapp te bekijken en te bewonderen.

Daarom is het ontwerpen van toegankelijke, gebruiksvriendelijke, lichtgewicht frontends erg belangrijk.

Er zijn voldoende UI/UX best practices beschikbaar op het web om je te helpen begrijpen wat het beste werkt voor je gebruikers. Je kunt professionals vinden die bedreven zijn in het maken van gebruiksvriendelijke ontwerpen en architecturen waarmee je gebruikers het maximale uit je apps kunnen halen.

Wij adviseren om goed na te denken over de responsiviteit van je frontend voordat je je product uitrolt naar je gebruikers.

2. Monitor de laadtijden

Je frontends moeten niet alleen gemakkelijk te begrijpen zijn, maar ook snel laden.

Volgens Portent vinden de hoogste ecommerce conversies plaats op pagina’s met laadtijden tussen 0-2 seconden, en volgens Unbounce geeft ongeveer 70% van de consumenten toe dat de laadtijd van een pagina een belangrijke factor is in hun keuze om bij een online verkoper te kopen.

Bij het ontwerpen van mobielnative applicaties kun je meestal niet zeker zijn van de apparaatspecificaties van je gebruikers. Elk apparaat dat niet voldoet aan de eisen van je app wordt doorgaans verklaard dat het de app niet ondersteunt.

Bij het web is dit echter heel anders.

Bij webapplicaties kunnen je gebruikers alles gebruiken, van de nieuwste Apple Macbook M1 Pros tot oude Blackberry en Nokia telefoons om je app te bekijken. Het optimaliseren van je frontendervaring voor zo’n breed scala aan gebruikers kan soms lastig zijn.

Diensten als LightHouse en Google PageSpeed schieten je te binnen als je het over frontendprestaties hebt. Je moet dergelijke tools gebruiken om je frontendapp te benchmarken voordat je hem in productie inzet. De meeste van dergelijke tools geven je een lijst met bruikbare tips om de prestaties van je app zoveel mogelijk te verbeteren.

De laatste 5-10% van de prestaties van de app is meestal specifiek voor je use case en kan alleen worden opgelost door iemand die je app en zijn technologieën goed kent. Het kan nooit kwaad om te investeren in webprestaties!

3. Geef waar mogelijk de voorkeur aan PWA’s

Zoals eerder besproken zijn PWA’s de ontwerpen van de toekomst. Ze passen goed bij de meeste use cases, en ze bieden de meest uniforme ervaring op de belangrijkste platforms.

Je zou moeten overwegen om zo vaak mogelijk PWA te gebruiken voor je app. De native ervaring over web en mobiel is enorm impactvol voor je gebruikers en kan ook veel van je eigen werklast verminderen.

PWA’s zijn ook snel te laden, eenvoudig te optimaliseren en snel te bouwen. Door te kiezen voor PWA’s kun je al vroeg veel van je aandacht verleggen van ontwikkeling naar business.

4. Houd je codebase schoon en beknopt

Met een schone codebase kun je de meeste problemen opsporen en oplossen voordat ze schade veroorzaken. Hier zijn enkele tips die je kunt volgen om ervoor te zorgen dat je codebase je niet meer problemen bezorgt dan nodig is.

  • Focus op hergebruik van code: Het onderhouden van kopieën van dezelfde code in je hele codebase is niet alleen overbodig, maar kan er ook voor zorgen dat er discrepanties insluipen, waardoor je codebase moeilijk te onderhouden is. Richt je altijd op hergebruik van code waar mogelijk.
  • Plan je projectstructuur: Softwareprojecten kunnen met de tijd erg groot worden. Als je niet begint met een geplande structuur van code-organisatie en resources, kun je uiteindelijk meer tijd besteden aan het vinden van bestanden dan aan het schrijven van nuttige code.
  • Schrijf unittesten: Elk stuk code heeft een kans om kapot te gaan. Alles handmatig testen is niet haalbaar, dus heb je een vaste strategie nodig voor het automatiseren van tests voor je codebase. Testrunners en code coveragetools kunnen je helpen om vast te stellen of je unittests de gewenste resultaten opleveren.
  • Hoge modulariteit: Richt je bij het schrijven van code altijd op modulariteit. Het schrijven van code die strak gekoppeld is aan andere stukken code maakt het moeilijk om te testen, te hergebruiken en te wijzigen als dat nodig is.

5. Automatiseer je CI/CD processen

CI/CD staat voor Continuous Integration/Continuous Deployment. CI/CD processen zijn cruciaal voor de ontwikkeling van je applicatie, omdat ze je helpen je project gemakkelijk te bouwen, te testen en uit te rollen.

Je wilt ze echter niet elke keer handmatig moeten uitvoeren. In plaats daarvan zou je pipelines moeten opzetten die automatisch in werking treden op basis van de activiteiten van je project. Je kunt bijvoorbeeld een pijplijn opzetten die je tests automatisch uitvoert wanneer je je code vastlegt in je versiebeheersysteem. Er zijn ook veel complexere gebruikssituaties, zoals het genereren van cross-platformartefacten uit je coderepository wanneer een release wordt gemaakt.

De mogelijkheden zijn eindeloos, dus het is aan jou om uit te zoeken hoe je het meeste uit je CI/CD pijplijnen kunt halen.

6. Beveiligingsfeatures inbouwen

De meeste moderne apps bestaan uit meerdere componenten. Neem de volgende app als voorbeeld:

Componentendiagram van een serverloze webapp die laat zien hoe verschillende componenten zoals API gateway, externe API's en services met elkaar omgaan.
Voorbeeld van een serverless webapparchitectuur.

Clientverzoeken worden via een API gateway naar de app geleid. Hoewel deze momenteel alleen directe verzoeken aan de thuismodule van de app toestaat, zou deze in de toekomst toegang kunnen geven tot meer onderdelen zonder via de thuismodule te gaan.

Vervolgens controleert de thuismodule een externe authenticatie BaaS alvorens toegang toe te staan. Eenmaal geauthenticeerd kan de cliënt toegang krijgen tot de pagina’s “Update Profile” of “View Profile”. Beide pagina’s communiceren met een gemeenschappelijke, beheerde database-oplossing die de profielgegevens afhandelt.

Zoals je kunt zien, lijkt de applicatie op een heel eenvoudige en minimale versie van een online personendirectory. Je kunt je eigen profiel toevoegen/bijwerken of andere beschikbare profielen bekijken.

Hier is een snelle legenda van de verschillende onderdelen in de architectuur:

  • Blauwe vakjes: Appmodules, die eventueel worden gehost als microservices of serverloze functies.
  • Rode vakjes: Externe BaaS-componenten die zorgen voor authenticatie en database.
  • Groene vakje: Routingcomponent die inkomende verzoeken van de client modereert.
  • Zwarte vakje: Je clientapplicatie die aan de gebruiker wordt blootgesteld.

De componenten van elk van de bovenstaande kleuren zijn kwetsbaar voor verschillende soorten beveiligingsbedreigingen. Hier zijn een paar beveiligingsconstructies die je kunt aanbrengen om je blootstelling te minimaliseren:

  • Appmodules (blauw): Omdat dit serverless functies zijn, volgen hier enkele tips om hun beveiliging te versterken:
    • Isoleer app secrets en beheer ze onafhankelijk van je broncode
    • Handhaaf toegangscontroles via IAM diensten
    • Verbeter je testinspanningen om ook te zoeken naar beveiligingsbedreigingen via technieken als SAST
  • Externe diensten (rood):
    • Stel toegangscontroles in via hun IAM-modules om de toegang te reguleren
    • Kies voor API snelheidsbeperking
    • Stel voor diensten zoals databases strikere controlepermissies in, zoals wie toegang heeft tot de gegevens van de profielen, wie de gegevens van de gebruikers kan bekijken, en meer. Veel diensten, zoals Firebase, bieden een gedetailleerde set van dergelijke regels.
  • Routingcomponent (groen):
    • Net als alle andere componenten, toegangscontroles implementeren
    • Stel autorisatie in
    • Dubbelcheck op standaard best practices zoals CORS
  • Client:
    • Zorg ervoor dat er geen app secrets beschikbaar zijn voor je client
    • Zorg door obfuscatie van je clientcode om de kans op reverse-engineering te minimaliseren

Hoewel dit slechts een handvol suggesties zijn, benadrukken ze dat appbeveiliging ingewikkeld is, en het is jouw verantwoordelijkheid om ervoor te zorgen dat je geen losse eindjes overlaat voor aanvallers om aan te trekken. Je kunt niet vertrouwen op een centrale beveiligingscomponent om je bedrijf te beschermen; appbeveiliging is verdeeld over je apparchitectuur.

7. Verzamel feedback van gebruikers

Gebruikersfeedback is een cruciale tool om te begrijpen hoe goed je app het doet in termen van zakelijke en technische prestaties. Je kunt de lichtste en soepelste app ter wereld bouwen, maar als hij je gebruikers niet laat doen wat ze verwachten, dan gaan al je inspanningen de mist in.

Er zijn meerdere manieren om gebruikersfeedback te verzamelen. Hoewel een snelle en geanonimiseerde enquête de conventionele aanpak is, kun je ook kiezen voor een meer geavanceerde oplossing, zoals een warmtekaart van de activiteit van je gebruikers.

De keuze van de methode om feedback te verzamelen is minder belangrijk dan het ondernemen van actie op de verzamelde feedback. Klanten houden van bedrijven die naar hun problemen luisteren. Giganten als McDonald’s en Tesla doen dat, en dat is een van de redenen waarom ze succesvol blijven in hun markten.

Samenvatting

Het web is een enorme speeltuin van een verscheidenheid aan applicaties, elk op zijn eigen unieke manier ontworpen. Meerdere soorten architecturen zorgen dat webapps kunnen diversifiëren, gedijen en diensten aan te bieden aan gebruikers over de hele wereld.

In deze handleiding hebben we de verschillende modellen van webapparchitectuur ontleed en je laten zien hoe cruciaal ze zijn voor de groei van een applicatie.

Is er een webapparchitectuur waar je echt mee wegloopt? Of is er een andere die je met de wereld zou willen delen? Laat het ons weten in de comments hieronder!

Kumar Harsh

Kumar is a software developer and a technical author based in India. He specializes in JavaScript and DevOps. You can learn more about his work on his website.