Jeg vil framsnakke et gammelt prinsipp og to modne verktøy som fungerer spesielt godt når alt er i bevegelse samtidig. Denne kombinasjonen var nyttig for oss da lagene våre ristet i takt og utakt med prosjekter som var utenfor vår kontroll.
¶Frontendproblemet
En kunde har en avtale om finansielle tjenester hos en bedrift. Denne avtalen kan endre tilstand som følge av et jobbskifte. Av historiske årsaker håndterer bedriften de ulike tilstandene i ulike fagsystem. Som følge av dette må brukeren forholde seg til ulike brukeropplevelser for å utføre de samme oppgavene.
Det tekniske oppsettet virket ganske standard. Arkitektene tegner det slik:
Ved nærmere ettersyn viste det seg at api-ene som ble eksponert via BFF-en i stor grad bare proxiet strukturene som fantes i fagsystemet som eide avtalen. BFF-en var proppfull av «ifs-and-buts», men det fantes ikke noe harmonisert grensesnitt som forenklet utviklingen av brukeroplevelser. På sikt førte dette til tre applikasjoner som levde sine egne liv.
Forretningen trykket hardt på for at brukerne ikke skulle påvirkes av at det var ulike fagsystem som håndterte de ulike avtaletypene. Det måtte bli en omforent brukeropplevelse for alle fasene.
¶Backend for Frontend utfordringen
Av ulike årsaker skulle BFF-en erstattes for å passe inn i et større plattformløft utenfor vår kontroll. Nytt kjøretidsmiljø, nytt programmeringsspråk, nye sikkerhetsmekanismer osv. Vi måtte etablere en helt ny BFF som betjente de eksisterende applikasjonene med nødvendige api.
¶Fagsystem i endring
Fagsystemene der bak levde også sine egne liv. Et sentralt system skulle erstattes – selvfølgelig også utenfor vår kontroll.
Hele “platformen” var i bevegelse. Tidsplanen var stram og vi måtte finne en strategi for å levere stabile grensesnitt samtidig som vi håndterer masse endringer på en trygg måte.
¶Noen faste rammer
Vår strategi var enkelt og greit å innføre ende-til-ende testing der vi simulerte alle fagsystem ved hjelp av WireMock og verifiserte alle nye api opp mot det vi fikk fra de gamle ved hjelp av ApprovalTests.
Utfordringen lå i å få kontroll på alle variasjonene innenfor hver avtaletype. Vi startet med ca 25 ulike scenarioer som måtte verifiseres. For alle disse variantene hentet vi ut responsens fra api i den gamle BFFen og tilhørende respons fra de ulike fagsytemene. Det var ca 30 ulike api involvert i henholdsvis BFF og fagssytem.
Datasettene som ble hentet ut var produksjonsnære i den forstand at de kom fra de samme systemene som ble benyttet i produksjon, men det var selvfølgelig ingen faktiske kundedata i disse. Der det var behov for å representere kundeinformasjon, ble dette hentet fra Tenor datasettet til Skatteetaten.
Med scenarioene på plass og nødvendig uttrekk av data, var det ganske raskt å sette opp simuleringen og testingen.
BFFen vi etablerte skulle i første omgang bare erstatte den gamle gjennom reetablering av de samme grensesnittene. Over tid har vi restrukturert disse grensesnittene - slik at frontend enklere kan håndtere ulike avtaletyper ved hjelp av felleskomponenter og nye api.
I alle ende-til-ende testene våre startes BFFen og WireMock opp som egne servicer. Apiene blir testet ut med de ulike scenariene.
Simuleringen av fagsystemene i WireMock konfigureres slik at den gjenspeiler de faktiske grensesnittene vi jobber mot.
Når vi kjører testene våre, verifiserer vi ende-til-ende med kall mot BFF-ens api og dens interaksjon mot fagsystemene. Hvis det er avvik mellom det den nye BFF-en produserer og fasiten fra den gamle BFF-en, vil testen feile.
Avvik vises i en egen diff mellom det som er «approved» og det som er «received».
¶Tydelig ansvarsdeling - Api, Ports and Adapters
I den nye BFF-en innførte vi et tydelig skille mellom:
- api ut mot brukergrensesnitt
- Adaptere som snakker med api-ene til de ulike fagsystemene
Prinsippene er hentet fra Hexagonal arkitektur, også kalt Ports and Adapters. Dette gir oss løse koblinger mellom datakilde og brukergrensesnitt. Løse koblinger gjør det enklere å la dem leve ulike liv – så lenge kontrakten, portene, ivaretas.
Portene definerer grensesnitt, uttrykt ved hjelp av den interne domenemodellen. api-ene har sine egne modeller som gjenspeiler kontrakten med brukergrensesnittene. På samme måte har adaptere sine modeller som gjenspeiler kontrakten med fagsystemene.
Når alle testene for nye api var feilfrie, kunne vi gradvis migrere over eksisterende applikasjoner.
Services ble etablert for å orkestrere samspill mellom ulike adaptere ut mot api-ene. Her er den originale beskrivelsen av Hexagonal arkitektur. Det er mange måter å implementere dette på. Det viktigste er at du finner din form – og er tro mot den.
|
|
|
Når et fagsystem ble byttet ut, etablerte vi en ny adapter som håndterte nye strukturer og tilkoblingspunkter. Vi samlet inn nye scenariedata fra det nye systemet og verifiserte resultatet med de samme testene.
Ved etablering av nye api ut mot det nye harmoniserte brukergrensesnittet, etablerte vi nye tester mot de samme scenariefilene. Gradvis fikk vi faset ut «bastardene» og innført en harmonisert frontend.
Vi måtte lage noen nye tester, men vi hadde kontroll på:
- hvilke scenario vi ønsket å teste
- tilhørende testdata for de ulike fagsystemene
Vi er veldig godt fornøyd med oppsettet vårt. Vi har klart å håndtere store endringer i alle lag på en trygg måte. Antall ulike testscenario har gradvis vokst til over 100 og dekker langt flere use case enn den opprinnelige avtalehåndteringen. WireMock benyttes for å simulere ca 50 bakenforliggende api.
¶Bonus 1
En fin bonus har vært rollen vår nye BFF har hatt for vår frontendutvikling. Ved å kjøre BFFen lokalt har vi hatt tilgang til alle scenariene med produksjonsnære data samtidig som vi utvikler nye brukergrensesnitt. Det har sikret godt samspill mellom BFFen som tilgjengeligjør api og de som faktisk skal benytte seg av disse.
¶Bonus 2
Kombinasjonen http4k og WireMock gjør det ganske enkelt å automatisere dokumentasjon av integrasjonene relatert til de ulike scenariene. Automatisk oppdatering av dokumentasjon er en fin bonus når mye er i endring.
