Realtime communicatie voor digitale schermen
Hoe ik een bestaand schermplatform uitbreidde met een socketserver die wijzigingen aankondigt aan verbonden mediaplayers.
Dit artikel is geanonimiseerd. Bedrijfs-, product- en persoonsnamen en interne verwijzingen zijn weggelaten of vervangen, ook in diagrammen en voorbeelden.
Wie content publiceerde voor de digitale schermen, moest wachten tot de mediaplayers opnieuw bij het CMS (contentmanagementsysteem) controleerden. Dat deden ze ongeveer iedere vijf minuten. Een publicatie vlak na zo'n controle kon dus bijna vijf minuten blijven liggen. Mijn opdracht was een socketserver te ontwikkelen waarmee het CMS zelf een wijziging kon aankondigen aan verbonden mediaplayers. Het bestaande PHP/CakePHP-CMS en de werking van de mediaplayers moesten behouden blijven.
Deze praktijkopdracht vormde ook de basis voor mijn ontwerpgerichte afstudeeronderzoek Informatica bij Avans Hogeschool. Een socketserver was al gevraagd; ik onderzocht welke techniek paste, hoe de onderdelen moesten samenwerken en hoe ik de werking kon toetsen.
Ik leverde een werkende socketserver in TypeScript op, met tests, mijn scriptie en technische documentatie. Deze afzonderlijke backendapplicatie onderhoudt de verbindingen met mediaplayers en stuurt meldingen uit het CMS door naar de juiste ontvangers. Daarnaast paste ik de contentcontrole in het CakePHP-CMS aan. Ik werkte zelfstandig, met AI (Artificial Intelligence) als ondersteuning bij analyse, code, tests en documentatie. De keuzes en de controle van de uitkomsten bleven mijn verantwoordelijkheid. De socketserver was lokaal getoetst; beta-uitrol en acceptatie moesten bij de overdracht nog plaatsvinden.
-
Voorbereiding
- Het probleem
- De onderzoeksvraag
- Aanpak
-
Uitvoering
- Analyse
- Ontwerp
- Realisatie en toetsing
Werkende socketserver
-
Afronding
- Resultaat
- Meetgrenzen
Voorbereiding
Vaker controleren zou ook meer werk veroorzaken
In de PHP-code volgde ik hoe het CMS een aanvraag van een mediaplayer verwerkte. Bij vrijwel iedere controle bouwde het een volledige afspeellijst op, ook als de inhoud gelijk was gebleven. Die lijst gebruikte SMIL (Synchronized Multimedia Integration Language) om vast te leggen wat de mediaplayer moest afspelen. Het CMS kon de lijst pas teruggeven nadat de mediaplayer erom had gevraagd. Dit periodiek controleren heet polling.
Speelt content af op het scherm
Verwerkt polls, genereert SMIL
- CMS-beheerder → CakePHP-applicatieBeheert content · HTTPS
- Mediaplayer → CakePHP-applicatiePollt · elke circa 5 min
- CakePHP-applicatie → MediaplayerVolledige SMIL-afspeellijst terug
Een korter interval zou nieuwe publicaties eerder zichtbaar maken voor de mediaplayer, maar ook meer aanvragen aan het CMS opleveren. Bovendien moest het CMS zelf berichten kunnen sturen. De uitbreiding moest daarom naast de bestaande route werken. Polling bleef nodig voor oudere mediaplayers en om na een gemiste melding alsnog actuele content op te halen.
Van de opdracht naar toetsbare vragen
In het eerste overleg bepaalden we de opdracht. Ik werkte die uit in een voorstel voor mijn opleiding, met de aanleiding, eerste eisen en het beoogde eindproduct. Na goedkeuring organiseerde ik het onderzoek en de uitvoering zelf.
Mijn plan van aanpak verbond vijf deelvragen: hoe werkte het platform, wat moest de uitbreiding kunnen, welke techniek paste, hoe kon ik de oplossing bouwen en hoe zou ik haar toetsen? Ik onderzocht broncode, documentatie en literatuur, sprak met betrokkenen en beproefde oplossingen met een prototype en tests.
Documentatie en code kwamen niet altijd overeen. Voor de feitelijke werking ging ik uit van de actuele code. Tijdens het bouwen kwamen vervolgens nieuwe vragen naar voren, waardoor onderzoek, ontwerp en implementatie elkaar bleven beïnvloeden.
-
Deelvraag 1
Huidige werking
Code en documentatie analyseren.
De bestaande werking maakt duidelijk wat de uitbreiding moet oplossen. -
Deelvraag 2
Toetsbare eisen
Eisen bespreken en prioriteren.
De eisen geven richting aan de technologievergelijking. -
Deelvraag 3
Technologie afwegen
Kandidaten vergelijken op projectcriteria.
De gekozen techniek vormt de basis voor het ontwerp en de bouw. -
Deelvraag 4
Ontwerpen en bouwen
Ontwerp en prototype uitwerken.
De implementatie wordt met functionele scenario’s en prestatiemetingen getoetst. -
Deelvraag 5
Resultaat toetsen
Scenario’s toetsen aan de eisen.
Onderzoek en ontwikkeling samen plannen
Voor het traject had ik twintig weken met zestien uur projecttijd per week. Mijn plan van aanpak bevatte al een globale planning. Ik werkte die uit in negen sprints, met taken voor onderzoek, bouwen, tests en documentatie.
Daarbij koppelde ik een kennisbank en mijn eigen Jira-project via MCP (Model Context Protocol) aan een AI-agent. De agent hielp mijn plan te verdelen over epics en bijbehorende taken. Ik controleerde de indeling en paste die waar nodig aan. Het Gantt-overzicht liet de planning in de tijd zien; op het Jira-bord hield ik de voortgang bij.
Scroll horizontaal om de volledige planning te bekijken.
| Werk | Planning van februari tot en met juni |
|---|---|
| Sprints | 123456789 |
| Onderzoeksproject | |
| Voorbereiding | |
| Plan van aanpak | |
| Uitvoering | |
| Conceptverslag | |
| Socketserver | |
| Definitief verslag | |
| Afronding | |
| Presentatie en verdediging |
To Do
- Beoordeling van het eindverslag ontvangenAfronding
- Onderzoek en implementatie presenterenAfronding
- Herstel bij uitval van de berichtendienst onderzoeken
In Progress
- Presentatie uitwerkenAfronding
- Restart-opdracht vanuit CMS werkt niet via de mediaplayerSocketserver
- Toegang van langdurig verbonden schermen opnieuw controlerenBeveiliging
In Review
- Validatie en performancetestsSocketserver
- CMS-integratie via Strangler FigSocketserver
- Pipeline-smoketest vervangen door compose-stackSocketserver
- Prototype socketserver bouwenSocketserver
- Softwareontwerp uitwerkenSocketserver
Done
- Voortgangsupdates versturenOnderzoeksproject
Uitvoering
Snel bezorgen, bij de juiste mediaplayer
Met technische en productverantwoordelijken besprak ik snelheid, groei en uitval. Ik vertaalde hun behoeften naar eisen met een herkomst, prioriteit en voorwaarden voor goedkeuring. MoSCoW (Must, Should, Could en Won’t) hielp onderscheid te maken tussen noodzakelijk werk en aanvullingen.
Voor berichtontvangst gold bijvoorbeeld een tijdsgrens. Bij klantscheiding moest ik kunnen aantonen dat een bericht niet bij een andere klant terechtkwam. Ook de grens van de opdracht stond vast: mediaplayers bleven zelf hun mediabestanden downloaden. Deze afspraken bepaalden zowel het ontwerp als de latere tests.
De bestaande omgeving gaf de doorslag
Met een multicriteria-analyse vergeleek ik oplossingen op twaalf gewogen criteria, waaronder berichtbezorging, herstel na uitval, integratie en kennis binnen de organisatie. Ik onderscheidde de verbinding met de mediaplayer van de berichtenuitwisseling tussen systemen. Socket.IO en Centrifugo waren kandidaten voor de eerste taak; Redis Pub/Sub (publish-subscribe), Redis Streams en RabbitMQ onderzocht ik voor de tweede.
- Verkennen29
Kandidaten uit technische bronnen.
- Selecteren26
Formeel beoordeeld; drie vooraf uitgesloten wegens onderhoud of veroudering.
- Afwegen9
Kandidaten voor de gewogen vergelijking.
2 platforms gelijk op 93
De keuzeSocket.IO + Redis Pub/Sub
Frameworks en platforms · selectie uit de matrix
- Socket.IOGekozen 93 / 99
- Centrifugo 93 / 99
- deepstream.io 67 / 99
Brokers · eigen architectuurlaag
- RabbitMQ 70 / 99
- Redis Pub/SubGekozen 69 / 99
- Redis Streams 69 / 99
Socket.IO en Centrifugo eindigden gelijk. De bestaande Redis- en containerinfrastructuur en de aanwezige kennis gaven de doorslag voor een eigen service met Socket.IO en Redis Pub/Sub. Ik bouwde die in TypeScript op Node.js. Daarmee kreeg de realtime communicatie een eigen plek naast het CMS. Daar stond extra beheer tegenover: een afzonderlijke service en berichtafspraken die tussen CMS, service en mediaplayers moesten blijven aansluiten.
Een wijziging aankondigen, de contentroute behouden
Het CMS bleef bepalen welke content voor welke doelgroep beschikbaar was. Mijn socketserver kondigde een wijziging aan; de mediaplayer haalde de inhoud op en speelde die af. Zo kon ik de communicatie uitbreiden terwijl contentbeheer en afspeellogica bij de bestaande onderdelen bleven.
Het CMS publiceert daarvoor een bericht op een Redis-kanaal. De socketserver is op die kanalen geabonneerd, controleert het bericht en stuurt de melding naar de juiste verbonden mediaplayers. Dit publish-subscribe-model voorkomt dat het CMS elk draaiend exemplaar van de service afzonderlijk moet aanspreken.
Beheert en publiceert content.
Content, identiteit en SMIL-afspeellijsten.
Socket.IO-client; haalt op en speelt af.
Verspreidt publicatiesignalen.
Nieuwe communicatielaag · ontworpen doelomgeving
TLS en WebSocket-upgrade.
Controleert berichten en kiest de ontvangers; gebouwd in TypeScript.
- CMS-beheerder → CakePHP-CMSDe beheerder wijzigt en publiceert content.
- CakePHP-CMS → Pub/SubHet CMS publiceert een event op Redis.
- Pub/Sub → SocketserverDe socketserver ontvangt berichten via zijn abonnement op Redis.
- Socketserver ↔ Load balancerSocket.IO-verkeer tussen de service en de load balancer.
- Mediaplayer ↔ Load balancerDe mediaplayer verbindt en identificeert zich; de service verstuurt signalen en ontvangt bevestigingen.
- Socketserver → CakePHP-CMSDe socketserver laat de identiteit van de mediaplayer via het CMS controleren.
- Mediaplayer → CakePHP-CMSNa een signaal haalt de mediaplayer zelf de SMIL-afspeellijst op.
- Mediaplayer → CakePHP-CMSDe periodieke contentcontrole blijft naast push beschikbaar.
Voor de ontvangerselectie koppelde ik Socket.IO-rooms, groepen verbindingen, aan klanten, mediaplayers en afspeellijsten. In het voorbeeld hieronder gebruiken A, B en C dezelfde afspeellijst. D hoort bij dezelfde klant, maar gebruikt een andere lijst en ontvangt deze melding daarom niet.
Met ioredis ontvangt elk exemplaar van de service de CMS-publicatie via Redis en bezorgt die bij zijn eigen verbonden mediaplayers. De Socket.IO Redis-adapter heeft daarnaast een afzonderlijke taak: Socket.IO-berichten tussen service-exemplaren uitwisselen. Hij verspreidt deze CMS-publicatie niet nogmaals.
Socketinstantie 1
Kiest uit de eigen verbonden mediaplayers
- Mediaplayer A Afspeellijst 1 Ontvangt melding
- Mediaplayer B Afspeellijst 1 Ontvangt melding
Socketinstantie 2
Kiest uit de eigen verbonden mediaplayers
- Mediaplayer C Afspeellijst 1 Ontvangt melding
- Mediaplayer D Afspeellijst 2 Niet geselecteerd
De verbinding was de basis voor mijn eigen controles
Socket.IO bood benoemde berichten, groepen ontvangers en ontvangstbevestigingen. Engine.IO verzorgde daaronder het opzetten en bewaken van de verbinding. Het transport kan beginnen met long-polling via HTTP (Hypertext Transfer Protocol) en overgaan naar een blijvende WebSocketverbinding. Deze transportkeuze staat los van de periodieke contentcontrole bij het CMS.
Op die basis bouwde ik de regels voor identiteit, berichtinhoud en ontvangers. Een ontvangstbevestiging zegt daarbij alleen dat het bericht is aangekomen. Het downloaden en tonen van nieuwe content gebeurt daarna op de mediaplayer.
Ontwerpen terwijl de berichtafspraken veranderden
Het prototype maakte duidelijker welke gegevens de berichten moesten bevatten en hoe de service daarop moest reageren. Ik werkte de berichtafspraken en het ontwerp daarom tijdens de bouw bij.
Met UML (Unified Modeling Language) beschreef ik de gegevens en interacties. Een sessie, verbinding en bericht hebben bijvoorbeeld elk een eigen levensduur. Bij de identiteitscontrole gaf ik de CMS-koppeling, sessieopslag en telemetrie van buitenaf mee. Deze dependency injection maakte het mogelijk om in een test een CMS-antwoord of tijdelijke fout na te bootsen.
De keuzes legde ik vast in ADR’s (Architecture Decision Records), met aanleiding, alternatieven en gevolgen. Het Strangler Fig-principe diende als ontwerpkader om de communicatielaag naast het bestaande systeem te plaatsen. Polling bleef bestaan, waardoor beide routes onderhouden moesten worden.
Bij een korte onderbreking bewaarde de service sessiegegevens tijdelijk in het geheugen. Voor hervatting controleerde hij opnieuw de identiteit en klant. Een procesherstart wist die sessies, en Redis Pub/Sub bewaart geen berichten voor latere bezorging. Polling kon de actuele content alsnog ophalen; een gemiste eenmalige opdracht werd daarmee niet opnieuw uitgevoerd.
Eerst vaststellen of de afspeellijst is veranderd
Omdat polling beschikbaar bleef, keek ik ook naar de contentcontrole in CakePHP. Een mediaplayer had bij ongewijzigde inhoud geen nieuwe lijst nodig, terwijl het CMS die vrijwel iedere keer volledig opbouwde. Ik scheidde daarom het vaststellen van een wijziging van het samenstellen van de lijst.
De lichte controle berekent per mediaplayer een revisiekenmerk uit bestaande gegevens. De mediaplayer vergelijkt dat met de vorige waarde en haalt alleen bij een wijziging de volledige afspeellijst op. Voor het kenmerk hoeft het CMS de volledige lijst niet op te bouwen.
Een teller bij iedere opslaghandeling was onvoldoende. Sommige schrijfroutes in de legacycode omzeilden de gebruikelijke opslaghooks. Bovendien kan een afspeelrooster veranderen doordat een tijdvenster ingaat, zonder dat iemand gegevens opslaat. Daarom liet ik de controle aansluiten op de bestaande gegevens en de tijd- en regelselectie van de afspeellijstgenerator.
Voorheen
-
Periodieke aanvraag
De mediaplayer vraagt de afspeellijst op bij het CakePHP-CMS.
-
Volledige lijst opbouwen
Het CMS doorloopt vrijwel iedere keer de volledige generatorpijplijn.
-
Afspeellijst teruggeven
Ook wanneer de inhoud gelijk is gebleven.
Met revisiecontrole
-
Controle met mediaplayerstatus
De mediaplayer vraagt het actuele revisiekenmerk op en geeft zijn status door.
-
Berekenen en vergelijken
Het CMS berekent het kenmerk; de mediaplayer vergelijkt het met de vorige waarde.
-
Vervolg bepalen
Gelijk: huidige lijst behouden. Gewijzigd: volledige lijst ophalen. Controle mislukt: bestaande ophaalroute gebruiken.
De mediaplayer bleef bij de lichte controle zijn status doorgeven. Mislukte de controle, dan gebruikte hij de bestaande volledige ophaalroute. Ik voegde regressietests toe voor onder meer verwijderde content, gewijzigde instellingen en roostergrenzen. De database-uitvoering blokkeerde lokaal door ontbrekende configuratie. Hoeveel belasting deze aanpassing in de praktijk bespaart, is niet met een gecontroleerde meting vastgesteld.
Een geldige verbinding geeft niet overal toegang
Omdat klanten infrastructuur delen, controleert de service eerst wie een mediaplayer is en daarna welke ontvangersgroepen hij mag gebruiken. Het bestaande CMS blijft de bron voor de identiteitscontrole. Al vóór die controle begrenst de service het aantal verbindingspogingen, zodat niet iedere poging onbeperkt verdere verwerking kan veroorzaken.
Ook berichten worden gecontroleerd. Ajv toetst hun structuur, verplichte velden en gegevenstypen. Daarna vergelijkt de service de klantidentiteit in het bericht met die in het Redis-kanaal en controleert hij de bestemming. Een bericht met geldige velden maar een verkeerde klant of ontvangersgroep wordt afgewezen.
Het diagram zet deze maatregelen naast de WebSocket-richtlijn van OWASP (Open Worldwide Application Security Project). Twee grenzen blijven relevant: ingetrokken toegangsgegevens beëindigen een bestaande verbinding niet automatisch, en de omringende infrastructuur moet de verbinding versleutelen.
Bij verbindings- en bezorgproblemen legt de service logs en meetgegevens vast. Daarmee kan worden onderzocht waar het misging. De registratie van mislukte bezorging start zelf geen contentcontrole; die blijft de verantwoordelijkheid van de mediaplayer.
Foutscenario’s testen vóór het bouwen
Met Jest toetste ik onder meer verkeerde ontvangers, mislukte authenticatie en ontbrekende ontvangstbevestigingen. In unit-tests verving ik afhankelijkheden door testimplementaties om fouten gericht op te roepen. De testsuite bevat daarnaast integratietests die met Testcontainers een echte Redis-container starten en een Socket.IO-testclient verbinden.
Regeldekking hielp mij zien welke code de tests bereikten. Of de uitkomst klopte, moest blijken uit de controles op het verwachte gedrag.
Ik nam de controles op in een geautomatiseerde bouwroute: code- en opmaakcontrole, TypeScript-controle, tests en controle van afhankelijkheden. Pas daarna volgden het bouwen van een Docker-image en een kwetsbaarheidsscan met Snyk. De lockfile legde pakketversies vast voor volgende installaties.
Voor de doelomgeving was uitrol via AWS (Amazon Web Services) voorzien, met Elastic Beanstalk voor de service, ElastiCache voor Redis en een ALB (Application Load Balancer) vóór de service. Daar zou ook TLS (Transport Layer Security) worden afgehandeld. Deze uitrolroute was geconfigureerd; de volledige omgeving was bij de overdracht nog niet getoetst.
AI-uitkomsten terugleggen naast de code
Tijdens het onderzoek gebruikte ik een semantische zoekindex om relevante code op betekenis te vinden. Daarin kwamen eerst de broncode van het CMS en de mediaplayer, en later de code en documentatie van mijn socketserver. De zoekresultaten verwezen terug naar hun bronlocatie, zodat ik de omliggende code kon controleren.
De agent kreeg daarnaast context uit codedocumentatie, een kennisbank en taakspecifieke instructies. Ik toetste voorgestelde wijzigingen aan de code, eisen en tests en verantwoordde deze werkwijze in mijn scriptie. Het diagram laat zien hoe de bronnen samenkwamen; via Codeonderzoek kun je de zoekroute verder openen.
Codeonderzoek
Contentbeheer en publicaties
Content ophalen en afspelen
Mijn broncode en bijbehorende documentatie
Relevante code en uitleg op betekenis vinden
Bekijk de zoekketenGevonden code en documentatie
Verantwoordelijkheden en berichtafspraken vergelijken
Controleren aan broncode, eisen en tests
- CMS → Semantische zoekindex
- Mediaplayer → Semantische zoekindex
- Socketserver → Semantische zoekindex
- Semantische zoekindex → Codecontext
- Codecontext → AI-ondersteunde analyse
- AI-ondersteunde analyse → Mijn beoordeling
Semantische zoekindex
De geselecteerde bronbestanden
Code opdelen in samenhangende passages
Passages als getallen weergeven om op betekenis te zoeken
Vectoren, tekst en bronlocaties
Wat wil ik over de code weten?
De vraag omzetten voor de zoekindex
Passages vinden die bij de vraag passen
De gevonden passages op relevantie rangschikken
Passages met bronlocaties
Onder mijn regie
- Code en documentatie → Chunks
- Chunks → Embeddings
- Embeddings → Vectorindex
- Vectorindex → Semantisch zoeken
- Zoekvraag → Vraag-embedding
- Vraag-embedding → Semantisch zoeken
- Semantisch zoeken → Reranking
- Reranking → Broncontext
- Broncontext → AI-agent
Afronding
De berichtbezorging naast de eisen leggen
Om snelheid en herverbinden te toetsen, bouwde ik een eigen meetopstelling met gesimuleerde clients, de socketserver en een echte lokale Redis-server. Ik mat van publicatie in Redis tot ontvangst bij de testclient. Voor de herstelproef liet de testcode verbindingen verbreken en opnieuw openen.
-
Start van de meting
Testpublicatie
Tijdstip vastleggen en event publiceren.
De testpublicatie gaat via Redis naar de draaiende socketserver. -
Lokale runtime
Redis en socketserver
Event valideren en routeren.
De aankomst van het event bij de virtuele client beëindigt de tijdmeting. -
Einde van de meting
Virtuele client
Aankomsttijd vastleggen.
Bij 1.000 virtuele clients kwam 95% van de berichten binnen 79,28 ms (milliseconden) aan. Dat is de p95, het 95e percentiel. Voor herverbinden was de p95 ongeveer 1,35 seconde. Beide waarden lagen binnen de gestelde grenzen van één seconde voor berichtontvangst en vijf seconden voor herverbinden.
De proeven draaiden lokaal op Node 20, met testauthenticatie en verhoogde limieten. De tijden omvatten geen downloads of schermweergave. De beoogde Node 24-omgeving met het echte CMS, echte mediaplayers en de cloudinfrastructuur was hiermee nog niet getoetst. De scenario’s waren eenmalig gemeten.
De oplossing overdraagbaar maken
Ik leverde de socketserver op met tests, mijn scriptie en onderzoeks- en ontwerpdocumentatie. De berichtafspraken en foutafhandeling had ik tijdens het bouwen bijgehouden. Voor de overdracht bracht ik installatie-instructies, beheerhandleidingen en architectuuruitleg samen in een documentatiesite met VitePress.
Daarin bouwde ik een interactieve C4-kaart (Context, Containers, Components en Code). Een ontwikkelaar kon vanuit het systeemoverzicht naar de socketserver, de authenticatiecomponent en de bijbehorende methode navigeren. Daar stond welke gegevens de methode verwachtte en of de controle kon leiden tot accepteren, afwijzen of opnieuw proberen.
De bovenste architectuurlagen beschreef ik zelf; geselecteerde codedetails werden uit TypeScript gegenereerd. Hiervoor gebruikte ik TSDoc-commentaren en TypeDoc om API-documentatie (Application Programming Interface) uit mijn code te maken. Cytoscape.js tekende de kaart, ELK (Eclipse Layout Kernel) bepaalde de plaatsing en een uitbreiding verzorgde het in- en uitklappen.
Met de Skillit-plugin voor TypeDoc genereerde ik ook documentatie voor AI-agents, waaronder llms.txt en llms-full.txt. De kaart en deze navigatiebestanden gebruikten dezelfde gegevens over onderdelen en relaties. Daardoor waren die verbanden zowel voor ontwikkelaars als voor agents beschikbaar.
De demo hieronder toont deze manier van navigeren met twee generieke voorbeeldcomponenten. De namen en relaties zijn illustratief en geven niet de oorspronkelijke projectarchitectuur weer.
C4-demokaart
Volg een voorbeeldaanvraag van het systeemoverzicht naar de code.
Bediening
Open een laag met + en sluit die met −. Sleep de achtergrond om de kaart te verschuiven. Zoom in om de blokken groter te zien, of kies een onderdeel in het menu.
Deze API-documentatie gebruikt generieke TypeScript-voorbeelden.
Gebruiksvoorbeeld
C1 · Extern systeem
Wisselt gegevens uit met het voorbeeldsysteem.
C1 · Voorbeeldsysteem
Omvat de voorbeeldapplicatie en haar onderdelen.
C2 · Voorbeeldapplicatie
Bevat twee voorbeeldcomponenten.
C3 · Component A
Ontvangt een aanvraag in deze demo.
C4 · Voorbeeldhandler
Geeft de aanvraag door aan de voorbeeldfunctie.
Deze API-documentatie gebruikt generieke TypeScript-voorbeelden.
class ExampleHandler {
handle(request: ExampleRequest): ExampleResult;
}
- Methode · handle(request: ExampleRequest)
- Accepteert een aanvraag volgens de voorbeeldinterface.
- Retourwaarde · ExampleResult
- Geeft het resultaat van processRequest terug.
- Fout · TypeError
- Geeft bij een lege waarde de fout door aan de aanroeper.
const handler = new ExampleHandler();
const result = handler.handle({ value: 'voorbeeld' });
C4 · Voorbeeldinterface
Beschrijft de invoer en uitvoer van de demo.
Deze API-documentatie gebruikt generieke TypeScript-voorbeelden.
interface ExampleRequest {
value: string;
}
interface ExampleResult {
value: string;
}
- Eigenschap · ExampleRequest.value: string
- Een verplichte tekstwaarde; de functie controleert of die leeg is.
- Eigenschap · ExampleResult.value: string
- De verwerkte waarde die wordt teruggegeven.
const request: ExampleRequest = { value: 'voorbeeld' };
const result: ExampleResult = processRequest(request);
C3 · Component B
Verwerkt de doorgegeven aanvraag.
C4 · Voorbeeldfunctie
Verwerkt de aanvraag en geeft het resultaat terug.
Deze API-documentatie gebruikt generieke TypeScript-voorbeelden.
function processRequest(request: ExampleRequest): ExampleResult
- Parameter · request: ExampleRequest
- Een aanvraag waarvan het veld value niet leeg mag zijn.
- Retourwaarde · ExampleResult
- Een object met de verwerkte waarde in het veld value.
- Fout · TypeError
- Treedt op als request.value leeg is.
const result = processRequest({ value: 'voorbeeld' });
// result: { value: 'voorbeeld' }