Artikel
Development
7
 min

Van lokaal tot productie: Een introductie tot de tech stack van Weave – Part 2: Protocols & Persistence

Het ontwikkelproces is meerledig. Naast tools voor samenwerking en ontwikkeling, zoals beschreven in het eerste deel van deze reeks, is het ook nodig om applicatie-data op een veilige manier op te slaan en voor protocollen te kiezen die deze data zo efficiënt en betrouwbaar mogelijk bij de gebruiker of andere systemen leveren. Door te kiezen voor technieken die lightweight en future-proof zijn, kunnen toekomstige kostbare herzieningen of herontwerpen zo veel mogelijk worden vermeden.

In het tweede deel van onze technologische introductie gaan we verder met ‘Protocols & Persistence’. In het eerste deel hebben we de ‘Tools’ beschreven en in het laatste deel zullen we ingaan op ‘Deploying & Monitoring’.

gRPC

gRPC is een open-source framework ontwikkeld door Google en biedt een efficiënt en programmeertaal-agnostisch mechanisme voor de communicatie tussen applicaties. Bij elke nieuwe versie van gRPC staat de ‘g’ voor iets anders, zie: g_stands_for - GRPC Core. In gRPC kan een client rechtstreeks een methode aanroepen op een andere machine of server. Dit maakt het eenvoudiger om gedistribueerde toepassingen en services te maken in verschillende omgevingen en programmeertalen. 

gRPC maakt gebruik van het Protocol Buffer-bestandstype voor serialisatie van gegevens, ten opzichte van een JSON-bestandstype die je vindt in REST APIs. Het Protocol Buffer-bestandstype is compact, snel en efficiënt. gRPC biedt ondersteuning voor o.a. multiplexing, versioning, server push, genereren van boilerplate code, header compression en verschillende types van data streaming: unary, server streaming, client streaming en bidirectionele streaming. Door middel van bidirectionele streaming, bijvoorbeeld, verzendt en ontvangt gRPC berichten efficiënt zonder vertragingen op te lopen. Dat is een van de manieren waarop gRPC zich van REST onderscheidt, waarin REST, in de praktijk, doorgaans synchrone request-response communicatie ondersteunt zonder ingebouwde ondersteuning voor deze features. 

In Figuur 1 is de flow afgebeeld van wanneer er een gRPC request wordt uitgevoerd. Hier kun je de kracht van gRPC zien, wat gespcialiseerd is om over verschillende soorten systemen te opereren: 

  1. De client (Ruby Client/Android-Java Client) roept een gRPC-stub aan. 
  2. De gRPC-stub serialiseert de data in een Protocol-Request en doet een verzoek aan de gRPC server (C++ Service). 
  3. Als het verzoek is goedgekeurd, stuurt de client het Proto Request naar de server.
  4. De server deserialiseert de data in het Proto Request en voert het verzoek uit, resulterend in een Proto Response.  
  5. Tenslotte volgt het Proto Response dezelfde stappen maar dan in de omgekeerde richting.

Figuur 1: Communicatie over gRPC tussen 3 verschillende applicaties (server/client). Een stub kun je uitwisselbaar gebruiken met een client in deze context.

GraphQL

GraphQL is een querytaal waarmee clients precies kunnen aangeven welke gegevens ze nodig hebben in een netwerkverzoek, in plaats van vaste endpoints te gebruiken zoals in een REST API. Dit gegeven maakt het mogelijk om enkel de relevante gegevens op te halen die nodig zijn voor de presentatie van deze data in de gebruikersinterface. Stel dat je een applicatie hebt die gebruikersinformatie en hun blogposts ophaalt. Met GraphQL kan je in één enkel verzoek zowel de gebruikersinformatie als hun posts ophalen, terwijl je bij een REST API vaak meerdere verzoeken zou moeten doen naar meerdere endpoints om de gewenste data op te halen. Dat komt doordat een GraphQL server met één grote graph werkt, waarbij je met een enkel request meerdere resources kan ophalen door middel van de gedefinieerde relaties tussen entiteiten. De onderliggende resolvers zorgen ervoor dat alle bevraagde data via één endpoint terugkomt; ‘/gql’.

Om een nieuwe GraphQL service te creëren, definieer je eerst schema’s voor de entiteiten in je backend applicatie conform het GraphQL Schema Definition Language (zie Figuur 2). Op basis van deze schema’s kunnen er functies worden gecreëerd voor elk veld van dat type, om zo queries en mutaties uit te voeren op die entiteiten. Die benodigde functies kun je met behulp van code generation tools genereren. gqlgen is, volgens hun eigen beschrijving, een Go-bibliotheek voor het bouwen van GraphQL servers zonder gedoe. Say goodbye to writing annoying boilerplate-code! Door de flexibiliteit van GraphQL aangevuld door het gemak van gqlgen gebruiken wij voor GraphQL als communicatielaag tussen front- en backend.

Figuur 2: Voorbeelden van GraphQL Schema Definition Language.

PostgresSQL

PostgreSQL, vaak afgekort als Postgres, is een krachtige open-source database. Postgres is niet alleen zeer betrouwbaar en snel, maar ook flexibel en uitbreidbaar. Dit houdt in dat de ontwikkelaars hun eigen data-types, zoekmethoden en functies kunnen toevoegen wanneer dat nodig lijkt te zijn. Postgres ondersteunt SQL-standaarden, complexe zoekopdrachten en veilige database transacties. Hierdoor is Postgres geschikt voor zowel kleine als grote projecten.

Ent & Atlas

Ent is een ORM framework dat het beheer van je entiteiten in je applicatie vergemakkelijkt door de aangeboden out-of-the-box features. Denk aan een programmatisch aanpasbaar database schema, statische types en code generatie. Daarnaast biedt Ent ondersteuning voor PostgreSQL, GraphQL en Atlas. Atlas is een tool die verantwoordelijk is voor het managen en migreren van je database. Een hele fijne feature die Atlas biedt zijn de Versioned Migrations. Die Versioned Migrations houden de veranderingen die je maakt aan je database schema bij. Als Atlas wijzigingen detecteert die je hebt gemaakt aan je database schema, zoals het toevoegen van een nieuwe kolom, wordt er een nieuw .sql bestand gecreëerd met deze wijzigingen. Zie het artikel van Emma (Entgo.io als oplossing voor onze ORM discussie, in Go) voor meer in-depth informatie over het gebruik van Ent bij Weave.

NATS

NATS is een open-source, lichtgewicht en schaalbaar berichtensysteem dat gebaseerd is op het publish-subscribe (pub/sub) patroon, zie Figuur 3. Dit wordt ook wel een message oriented middleware genoemd. Dit systeem houdt in het kort in dat er een publisher is die berichten aanmaakt, zoals informatie over de status van een transactie (betaald/gefaald) en subscribers zijn op de publisher geabonneerd om die berichten te ontvangen en kunnen de inhoud van het bericht van de publisher gebruiken om taken uit te voeren. Het is ontworpen voor hoge prestaties en eenvoud, waar gedistribueerde systemen en microservice-architecturen veel baat bij hebben. 

NATS maakt gebruik van asynchrone communicatie om data tussen verschillende (micro-)services te verdelen.  

NATS kan miljoenen berichten per seconde afhandelen zonder aanzienlijke performance issues. Dit maakt het een ideale keuze voor diensten die snelle en frequente communicatie vereisen. NATS biedt ondersteuning voor horizontale schaalbaarheid en fouttolerantie. Dit gegeven zorgt ervoor dat onze applicaties vlot uitgebreid en hersteld kunnen worden en is cruciaal voor het handhaven van een hoge beschikbaarheid en robuustheid. Bovendien zorgt NATS voor veilige communicatie met TLS/SSL en biedt essentiële autorisatie- en authenticatie mechanismen om onze applicaties te beveiligen. Zo zorgt NATS ervoor dat berichten versleuteld zijn en niet bereikbaar zijn voor niet-geauthenticeerde of -geautoriseerde gebruikers. 

Figuur 3: Voorbeeld fan-out Pub/Sub Patroon

Nats JetStream

NATS bevat een ingebouwde engine voor persistente berichtopslag, genaamd JetStream. JetStream maakt het mogelijk om berichten in het Pub/Sub berichtensysteem op te slaan en op een later moment in te zien. JetStream is ontwikkeld om multi-tenancy, horizontale schaalbaarheid en meerdere implementatiemodellen te ondersteunen. JetStream biedt onder andere functionaliteit om beveiligingscontext en volledige zichtbaarheid van de operaties (van Publisher naar Subscriber) inzichtelijk te maken (Figuur 3). In een traditioneel Pub/Sub systeem, zonder persistence, verlies je veel van deze mogelijkheden puur door de aard van hoe Pub/Sub werkt. Na een acknowledgement van een bericht over een Pub/Sub berichtensysteem, verdwijnt dit bericht over het algemeen. Door persistentie toe te voegen in deze informatiestroom, transformeer je een voorheen fragiel, complex en niet-schaalbaar systeem naar een robuuste implementatie.

Last but not least; Deploying & Monitoring

Er is tot nu toe een duidelijke trend te vinden tussen de tools die we gebruiken. Bij Weave willen we zo snel mogelijk aan de slag aan nieuwe projecten en dat willen we op een manier doen zodat de applicaties die we bouwen schaalbaar zijn en zodat er weinig overhead door de basis goed neer te zetten en te begrijpen. Dat bereiken we door voor tools te kiezen die zowel open-source zijn en goed met elkaar werken. Golang, GCP, Kubernetes en gRPC zijn allemaal ontwikkeld door Google en werken daarom ook goed met elkaar. Ent heeft ondersteuning voor Postgres en ook voor GraphQL. Zo zijn we altijd op zoek naar de tools die het beste met elkaar integreren. 

Maar een applicatie ontwikkelen is één ding, het inzichtelijk maken ervan is een ander. We nemen in het laatste deel een kijkje in onze Monitoring stack en onze Deployments naar productie. Tot dan! 

Naslagwerk en referenties

Geschreven door
Tolga
Developer
Over Weave
Wij geloven in het ontwikkelen van digitale producten en diensten die relevant zijn en zorgen voor een positieve verandering in de samenleving. Daaraan bijdragen met onze technologische expertise, is wat ons drijft.
Meer over ons

Wij zoeken talent!

Vacatures