Een Mobile App zonder UI (logica) – Artikel uit SDN magazine 144
Er zijn veel keuzes die je moet maken wanneer je een mobile app gaat ontwikkelen, maar er wordt zelden gesproken of de logica voor de opbouw van de UI in de app hoort ja of nee.
Je zou kunnen denken dat dit een zeer voor de hand liggende keuze is en dit gewoon de verantwoordelijkheid is van de mobile app, maar dat is niet altijd zo.
Traditioneel
Een traditionele opzet is dat er één of meerdere (restful) API endpoints gebouwd worden die de mobile app gebruikt om data op te halen en/of acties uit te voeren. De app gebruikt deze data om de UI op te bouwen.
Wat is er mis met deze opzet die al zo vaak gebruikt is? Op zich niets per se, maar wanneer je nu een UI change wilt doorvoeren moet je wel de app bijwerken en opnieuw aanbieden in de app store. En een update betekent dan vaak ook een review. Tegenwoordig willen we zo klein mogelijk iteraties kunnen uitvoeren. We willen kunnen experimenteren met UI’s, A/B testen en snel feedback ontvangen. Het wachten op een app store approval is dan niet prettig werken.
Server Driven UI
De term “Server driven UI” betekent, zoals de naam al doet vermoeden, dat de UI zich laat bepalen door de server.
Bij server driven UI kent de mobile app een reeks aan componenten, maar bepaald de server welke componenten getoond moeten worden. Bij het opstarten begint de app te communiceren met een backend en vraagt simpelweg welke componenten getoond moeten worden. De server geeft een reeks componenten in een vooraf afgesproken format/schema terug en de app toont deze componenten. Deze componenten en opbouw zijn wel allemaal native componenten en daardoor voelt dit ook gewoon als een native ervaring.
Wil je nu de opzet van een pagina aanpassen dan is alleen een aanpassing in de backend nodig, vandaar de term Server Driven UI.
Partijen zoals Airbnb & Lyft staan er bekend om dat ze deze technieken gebruiken.
Microservices
Microservices in een artikel over hoe je UI opzet in een mobile app? Wanneer microservices, in mijn optiek, echt goed tot zijn recht komen is wanneer de microservices van frontend tot backend helemaal los van elkaar staan. In heel veel situaties wordt dit op backend niveau gedaan, maar als het bij de frontend komt dan is het vaak toch weer 1 geheel wat ze een monolitic frontend noemen. Om volledig los van elkaar staande functionele silo’s te ontwikkelen moet je dan ook micro frontends inzetten.
Maar hoe zit dat dan in een mobile app? Als het om het web gaat zijn er meerdere opties mogelijk om micro frontends te ontwikkelen, maar als het om een mobile app gaat zijn de opties wat beperkt. Er is uiteindelijk echt 1 app die in de app store terecht zal moeten komen. Je zou natuurlijk een module federation aanpak kunnen kiezen waarbij build time er 1 app build uit komt, maar dit betekent dat je voor iedere aanpassing nog steeds een app moet publiceren naar de store met bijbehorende reviews.
Bij het gebruik van Server Driven UI heb je in heel veel gevallen geen mobile app update nodig en kun je op de “backend” zoveel aanpassingen doen die nodig zijn zonder ook maar 1 app update. Pas wanneer je de mogelijke componenten wilt uitbreiden of aanpassen zul je een nieuwe app build moeten publiceren naar de store.
Betekent dit dat je per micro frontend/service volledige vrijheid hebt? Nee, je hebt nog wel de afhankelijkheid met wat de mobile app aan mogelijkheden biedt en zul je je naar 1 standaard moeten conformeren. Dit is niet anders bij micro frontends waarbij er in zekere zin gemeenschappelijke afspraken zijn. Het kan tegelijkertijd ook voordelen bieden, want als iedere micro frontend/service zijn eigen stijl hanteert ziet het er nogal snel slordig uit. Server Driven UI helpt dus ook om de huisstijl over je gehele app identiek te krijgen en houden.
Granulariteit
Er zijn verschillende opties die je kunt nemen als het gaat om Server Driven UI. De meest “pure” manier is om op een zo klein mogelijk component toe alles te laten specificeren door de backend, maar je kunt er ook voor kiezen om alleen met wat grotere componenten te werken. Hoe kleiner de componenten die gespecificeerd kunnen worden hoe meer flexibel de backend is en hoe minder vaak er een mobile app update uitgevoerd moet worden. Wel heb je dan een grotere investering nodig om deze techniek te toe te gaan passen t.o.v. wanneer je alleen de wat grotere componenten gebruikt.
In de mobile app die wij, Anycoin Direct, aan het ontwikkelen zijn gebruiken we een vorm van deze techniek ook. Bij de start van het ontwikkelen wisten we al dat wij, net zoals onze web omgeving, een zeer divers aantal scenario’s kunnen krijgen die we met enige regelmatig willen aanpassen. Er zit veel logica in onze aankoop/verkoop flow’s en om al deze logica in een mobile app te krijgen leek ons niet handig. Dat zou namelijk betekenen dat:
- We al deze processen moesten gaan uitleggen aan een nieuw mobile app development team.
- Aangezien we, na een weloverwogen besluit, voor een native app wilden gaan zou dat betekenen dat we de logica voor zowel android als iOS moesten ontwikkelen en onderhouden.
Uiteindelijk hebben we besloten dat we voor een mix gingen tussen een traditionele opzet en server driven UI. De meeste pagina’s gebruiken een traditionele opzet waar de logica volledig in de mobile app zit en er met een (restful) API endpoint de data opgehaald wordt. Maar wanneer je een aankoop wilt doen van een cryptocurrency dan is de backend in control. De app geeft aan dat er een “flow” gestart moet worden en de backend bepaald welk “scherm” getoond moet worden en welke inhoud deze moet hebben. Is er een keuze gemaakt dan gaat de keuze naar de backend en de backend bepaalt het volgende “scherm”.
Kijk in dit geval vooral wat het beste past in jouw situatie. We zijn niet allemaal de next Airbnb of Lyft
Backwards compatibility
Wat bij een web omgeving anders is, is dat de gebruiker zelf kiest wanneer hij/zij zijn mobile app update (of niet). Dit betekent dat de backend veelal backward compatible moet zijn met de mobile apps. Natuurlijk kun je hier ook een mechanisme voor introduceren waarbij je een bepaald minimumversie vereist, maar je wilt niet voor iedere app release de gebruikers forceren om eerst te updaten.
Bij een traditionele app betekent dit dat je je api endpoints moet versionen en/of backwards compatible moet houden.
Wanneer je server driven UI gebruikt is dit natuurlijk ook gewoon een aandachtspunt waar je vanaf moment 1 over na moet denken. Je kunt ervoor kiezen om componenten te gaan versioneren en oudere componenten tonen indien nodig. Ook kun je meerdere versies van pagina’s ontwikkelen en afhankelijk van de app versie een ander scherm tonen. En je kunt natuurlijk ook gewoon zeggen dat de gebruiker eerst maar eens de app moet bijwerken. It’s up to you…
Offline
Wanneer je server driven UI kiest moet je wel goed realiseren dat je app dus beperkt is op momenten dat er geen connectiviteit is. Voor sommige apps is dit helemaal geen probleem, maar voor andere weer wel. Dit is iets wat per app bepaald moet worden. Maar dit is natuurlijk ook een onderwerp waar je goed over na moet denken als je voor de meer traditionele aanpak gaat met api endpoints. In ons geval is er een hele duidelijke scheiding waar de connectiviteit vereist is en waar niet. Voor algemene content zoals welke cryptocurrencies wij aanbieden of de laatst bekende koers cachen we dit in de app. Zou er even geen connectiviteit zijn dan kunnen we de laatst bekende cache tonen. Ga je een flow in waar we Server Driven UI gebruiken dan is dit geen optie. In ons geval geen probleem, want offline een aankoop doen is nou eenmaal niet mogelijk.
Mag dit wel?
Sommige zullen denken dat dit wellicht een issue is waardoor je app wellicht afgekeurd zal worden bij het review proces van google en/of apple. Dit is gelukkig niet het geval, omdat er geen code aangepast wordt. We kunnen bijvoorbeeld geen nieuwe SDK’s of libraries gebruiken waarmee we potentieel vervelende dingen zouden kunnen doen die Google en/of Apple niet willen. Wanneer je er over nadenkt is het ook helemaal niet zoveel anders dan dat traditionele apps dit doen. Een traditionele app gebruikt ook dynamische content, waar ook plaatjes getoond zouden kunnen worden die de stores niet zouden willen. Het enige verschil is dat traditioneel de UI logica in de app zit en nu zit de logica buiten de app.
Conclusie
Server driven UI kan een techniek zijn die het mogelijk maakt om efficiënter, sneller en schaalbaar je mobile app te bouwen. Het vergt vaak wel een wat grotere investering in het begin, maar op termijn betekent dit dat je veel minder in je mobile app zelf hoeft te ontwikkelen. Het is een techniek die toegepast kan worden bij native apps in welke taal of framework dan ook.
Vincent Hendriks
Vincent Hendriks is CTO bij Anycoin Direct en een Software Engineer met meer dan 16 jaar ervaring. Vincent heeft een zeer brede ervaring in onderwerpen zoals C#, .NET/.NET Core, Software architectuur, CQRS, Event Sourcing, SQL, Azure, Docker en nog veel meer.