Entiteit relaties tussen microservices

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Un93m59
  • Registratie: Juli 2016
  • Laatst online: 04-10 17:29
Hoi allemaal,

Disclaimer Info: Ik ben bezig met mijn eerste microservices projectje, ik ga een webshop maken door middel van de Quarkus(Java) framework.

In mijn vorige projecten (monolieten architecturen) is het heel makkelijk om een lijst van een andere domein model bij te houden, omdat het simpel gezegd in het zelfde project zit en ze elkaar dus herkennen.

Bij microservices gaat het iets anders, kortgezegd elke entity(met daarop Controller,Service en natuurlijk de ORM laag) zit in een apart project, waardoor entiteiten niet veel af weten van elkaar

Het probleem is dat mijn microservices elkaar niet kennen, maar ik moet toch gaan proberen zodat ze communiceren met elkaar bijvoorbeeld een Order microservice, zou een lijst kunnen hebben met product.

Maar hoe kent deze class: Order, deze producten? want het domeinmodel van Product/Item zit in een ander project.

Afbeeldingslocatie: https://tweakers.net/i/Jfm90-cOCw8GLxPBaBUIW7juD90=/f/image/9EzxLO2wUmGUNR10Xu8q1MAf.png

Ik wil graag aan jullie vragen of jullie weten hoe ik dit probleem kan oplossen, ik hoef geen directe antwoorden als er begrippen zijn die ik moet onderzoeken/opzoeken doe ik dit graag.

[ Voor 12% gewijzigd door Un93m59 op 24-03-2020 19:14 ]

Beste antwoord (via Un93m59 op 25-03-2020 11:18)


  • johnkeates
  • Registratie: Februari 2008
  • Laatst online: 04-07 16:30
Un93m59 schreef op woensdag 25 maart 2020 @ 10:46:
[...]


Oh ik denk dat ik mijn vraag verkeerd geformuleerd heb. Mijn excuses.
Laat me dit proberen te uitleggen.

Laten we zeggen dat er een use-case is : een user voegt een product aan zijn winkelmand om later af te rekenen.

De winkelmand microservice, moet dus toch een lijst hebben met producten?

Ik heb als oplossing een andere entiteit (domeinmodel verzonnen) voor de microservice "winkelmand" genaamd: winkelmandproduct, op basis van dit model wordt een lijst bijgehouden in de winkelmand, in plaats van de zogezegde "producten" van een andere microservice

Maar mijn vraag dan in de Winkelmandproduct domeinmodel, moet ik daar een relatie leggen met de oorspronlijke product uit het Product microservice?

Moet een winkelmandproduct model een extra Id property hebben van het oorspronkelijke Product Id? (groen gemarkeerd)
[Afbeelding]
Nee, een winkelmand moet geen 'entity' hebben van een product. Die heeft alleen een entity van een winkelmand met daarin mogelijk referenties naar producten, het aantal, en de eigenaar van de winkelmand om wat te noemen. Het is ook niet de verantwoordelijkheid van de winkelmand om productinformatie op te zoeken of via de API beschikbaar te stellen, daar is de productservice verantwoordelijk voor. Dus een ID van het product opnemen zoals in je voorbeeld is dan voldoende.

Als je die winkelmandservice can benadert vanaf een andere service of een frontend hoef je alleen te weten wat er in de winkelmand API zit en wat het schema van de data is. Met schema bedoelen we niet database-schema ofzo, maar API schema, wat iets ongedefinieerds kan zijn (zoals een blob json en zoek het maar uit) of iets compleet vastgelegd zoals een GraphQL API of een API met AVRO schema. Of iets in het midden met een Swagger API definitie.

[ Voor 13% gewijzigd door johnkeates op 25-03-2020 11:06 ]

Alle reacties


Acties:
  • 0 Henk 'm!

  • johnkeates
  • Registratie: Februari 2008
  • Laatst online: 04-07 16:30
Dat doe je door API specs te delen en service discovery toe te passen.
Zo kan je bijvoorbeeld een schema registry en een service discovery systeem combineren om met services onderling te communiceren.

Microservices hebben niet heel veel zin als je ze nog steeds met de hand aan elkaar gaat knopen.

Voor puur data schema's kan je aan Avro denken, voor API+Schema iets als gRPC, voor voornamelijk API spec misschien slechts swagger.

De meest succesvolle integraties werken dan op basis van automatisch gegenereerde interfaces (een beetje zoals dat vroeger met WSDLs ging), of met libraries. Zo kan je je API spec definieren in een library en daar gewoon een client of server mee instantieren. En om ze dan vindbaar te maken knoop je daar iets als Eureka of Consul aan. In principe zou dat ook niet echt 'in' je applicatie moeten maar eerder in de container runtime (of dat dan een 'container' of 'applicatie server' is maakt dan niet uit). Je wil namelijk niet alleen discoverability hebben maar ook healthchecks om dode services uit een pool te gooien en om circuitbreakers te maken voor overbelaste services.

[ Voor 57% gewijzigd door johnkeates op 24-03-2020 19:19 ]


Acties:
  • +1 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Un93m59 schreef op dinsdag 24 maart 2020 @ 19:12:
Bij microservices gaat het iets anders, kortgezegd elke entity(met daarop Controller,Service en natuurlijk de ORM laag) zit in een apart project, waardoor entiteiten niet veel af weten van elkaar
Sterker nog...
Un93m59 schreef op dinsdag 24 maart 2020 @ 19:12:
Het probleem is dat mijn microservices elkaar niet kennen...
O, ja dat dus. Precies wat je wil.
johnkeates schreef op dinsdag 24 maart 2020 @ 19:15:
...automatisch gegenereerde interfaces (een beetje zoals dat vroeger met WSDLs ging), of met libraries. Zo kan je je API spec definieren in een library en daar gewoon een client of server mee instantieren.
Dat nou juist liever niet. Als je (als dergelijk voorbeeld) al je DTO's verpakt in een lib die je in al je services include, dan kun je onmogelijk een update aan die lib uitvoeren zonder een update aan alle services, tenminste: om van die nieuwe feature gebruik te maken. En bovendien maken de ontwikkelaars van de verschillende services allemaal wijzigingen in die centrale lib. Je services worden zo afhankelijk van die centrale lib en het idee is juist dat er zo min mogelijk onderlinge afhankelijkheden zijn: elke service heeft zijn eigen verantwoordelijkheid, databeheer, security, etc, etc.

Het enige waar services zich aan moeten houden is het contract met de buitenwereld (de interface: de application programming interface, kortwerg API). Die moet in stand gehouden worden (of backwards compatible zijn) om de verzameling services te kunnen laten draaien. (Net als dat je een nieuwe versie van een library in je softwareproject gaat gebruiken: de interface moet hetzelfde blijven, anders doet je programma het niet meer zonder zelf aanpassingen te maken).

Volgens mij is het ook helemaal niet nodig om bijvoorbeeld een 'product' op 1 plek vast te leggen. Immers, een product heeft bij de 'orders' (productnummer, aantal) heel andere properties dan bij 'webshop' (productnummer, afbeeldingen, omschrijving in 8 talen, prijs, reviews) of 'orderpicking' (productnummer, aantal, ordernummer, gangpad, volgorder) or 'warehousing' (productnummer, verpakking, pallet#, gangpad, aantalopvoorraad) of 'inkoop' (productnummer, timetolead, leverancier).

In dit voorbeeld noem ik een paar voorbeeldservices die allemaal met producten te maken hebben, maar elk hun eigen properties eraan toekennen. Het delen ervan is niet nodig: ieder zijn eigen verantwoordelijkheid.

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • +2 Henk 'm!

  • Vloris
  • Registratie: December 2001
  • Laatst online: 03-10 17:21
Als ik het goed begrijp zoek je naar een manier om in al je microservices gebruik te kunnen maken van hetzelfde domeinmodel?

Als je in meerdere microservices hetzelfde model zou willen gebruiken moet je je afvragen waarom je het dan überhaubt opgesplitst hebt. Het hele idee van microservices is namelijk juist dat elke service zijn/haar eigen datamodel heeft, met daarin alleen de elementen die nodig zijn voor die specifieke microservice.

Niet één datamodel dat je overal gebruikt en overal heen en weer stuurt dus.

Acties:
  • 0 Henk 'm!

  • johnkeates
  • Registratie: Februari 2008
  • Laatst online: 04-07 16:30
Jurgle schreef op woensdag 25 maart 2020 @ 10:05:

[...]

Dat nou juist liever niet.

Het enige waar services zich aan moeten houden is het contract met de buitenwereld (de interface: de application programming interface, kortwerg API). Die moet in stand gehouden worden (of backwards compatible zijn) om de verzameling services te kunnen laten draaien. (Net als dat je een nieuwe versie van een library in je softwareproject gaat gebruiken: de interface moet hetzelfde blijven, anders doet je programma het niet meer zonder zelf aanpassingen te maken).

Volgens mij is het ook helemaal niet nodig om bijvoorbeeld een 'product' op 1 plek vast te leggen. Immers, een product heeft bij de 'orders' (productnummer, aantal) heel andere properties dan bij 'webshop' (productnummer, afbeeldingen, omschrijving in 8 talen, prijs, reviews) of 'orderpicking' (productnummer, aantal, ordernummer, gangpad, volgorder) or 'warehousing' (productnummer, verpakking, pallet#, gangpad, aantalopvoorraad) of 'inkoop' (productnummer, timetolead, leverancier).

In dit voorbeeld noem ik een paar voorbeeldservices die allemaal met producten te maken hebben, maar elk hun eigen properties eraan toekennen. Het delen ervan is niet nodig: ieder zijn eigen verantwoordelijkheid.
Juist wel, het gaat ook niet om een DTO, da's iets wat je vooral binnen een applicatie verwacht. Een API is ook gewoon versioned. Als je dus een modificatie doet die breaking is (bijv. toevoegen van verplichte velden) moet je je API versie ophogen. Dan draai je dus zolang het in gebruik is twee versies van de API.

Dat is hoe zo'n beetje de hele wereld productie microservices draait. Als je puur 'een kleinere service' draait dan is dat geen microservice maar een 'kleinere service'. Microservices zijn niet slechts hoe 'groot' je applicatie is of hoe veel services je per applicatie aanbiedt. Het is ook geen vertaling van een database, een DAL of DTO of iets dergelijks.

Je gaat dus niet een relationele database nabouwen maar je maakt een decompositie van herbruikbare en individueel schaalbare componenten.

Voorbeeld: je maakt een shop en je hebt orders en producten en een winkelmand en klanten (en nog veel meer maar date laten we even voor wat het is):

Je frontend staat los van je backend. Misschien heb je een site die de frontpage laat zien, een die zoekopdrachten verwerkt, een voor de winkelmand, een voor de kassa, allemaal met een eigen verantwoordelijkheid. Of misschien is het juist een SPA, who knows.
Die gaat met je backend communiceren, door met een API te praten. Die API is niet rechtstreeks de API van een instance van een service maar een gateway of ingress controller. Je praat voor je requests tegen zo'n gateway of ingress en die zoekt verder zelf uit naar welke service en welke instance van zo'n service je request gaat. Stel dat je frontend wil weten hoe veel items in je winkelmand zitten doet ie misschien een request naar winkel.com/api/v1/winkelmand en afhankelijk van hoe efficient je het bouwt een GET met een /count of een complete GET en dan in de frontend een count van de resultaten. Dan maakt het dus niet uit wat het contract of datamodel aan de binnenkant is, je werkt dan ook niet met een 'entity' maar met een API schema.

[ Voor 37% gewijzigd door johnkeates op 25-03-2020 11:02 ]


Acties:
  • 0 Henk 'm!

  • Un93m59
  • Registratie: Juli 2016
  • Laatst online: 04-10 17:29
Vloris schreef op woensdag 25 maart 2020 @ 10:29:
Als ik het goed begrijp zoek je naar een manier om in al je microservices gebruik te kunnen maken van hetzelfde domeinmodel?

Als je in meerdere microservices hetzelfde model zou willen gebruiken moet je je afvragen waarom je het dan überhaubt opgesplitst hebt. Het hele idee van microservices is namelijk juist dat elke service zijn/haar eigen datamodel heeft, met daarin alleen de elementen die nodig zijn voor die specifieke microservice.

Niet één datamodel dat je overal gebruikt en overal heen en weer stuurt dus.
Oh ik denk dat ik mijn vraag verkeerd geformuleerd heb. Mijn excuses.
Laat me dit proberen te uitleggen.

Laten we zeggen dat er een use-case is : een user voegt een product aan zijn winkelmand om later af te rekenen.

De winkelmand microservice, moet dus toch een lijst hebben met producten?

Ik heb als oplossing een andere entiteit (domeinmodel verzonnen) voor de microservice "winkelmand" genaamd: winkelmandproduct, op basis van dit model wordt een lijst bijgehouden in de winkelmand, in plaats van de zogezegde "producten" van een andere microservice

Maar mijn vraag dan in de Winkelmandproduct domeinmodel, moet ik daar een relatie leggen met de oorspronlijke product uit het Product microservice?

Moet een winkelmandproduct model een extra Id property hebben van het oorspronkelijke Product Id? (groen gemarkeerd)
Afbeeldingslocatie: https://tweakers.net/i/CLLmOMXfgbGvsS7sg_lb66OybC8=/f/image/WvCNgHEyQRpwd0wL74q9EvgO.png

[ Voor 10% gewijzigd door Un93m59 op 25-03-2020 10:54 ]


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • johnkeates
  • Registratie: Februari 2008
  • Laatst online: 04-07 16:30
Un93m59 schreef op woensdag 25 maart 2020 @ 10:46:
[...]


Oh ik denk dat ik mijn vraag verkeerd geformuleerd heb. Mijn excuses.
Laat me dit proberen te uitleggen.

Laten we zeggen dat er een use-case is : een user voegt een product aan zijn winkelmand om later af te rekenen.

De winkelmand microservice, moet dus toch een lijst hebben met producten?

Ik heb als oplossing een andere entiteit (domeinmodel verzonnen) voor de microservice "winkelmand" genaamd: winkelmandproduct, op basis van dit model wordt een lijst bijgehouden in de winkelmand, in plaats van de zogezegde "producten" van een andere microservice

Maar mijn vraag dan in de Winkelmandproduct domeinmodel, moet ik daar een relatie leggen met de oorspronlijke product uit het Product microservice?

Moet een winkelmandproduct model een extra Id property hebben van het oorspronkelijke Product Id? (groen gemarkeerd)
[Afbeelding]
Nee, een winkelmand moet geen 'entity' hebben van een product. Die heeft alleen een entity van een winkelmand met daarin mogelijk referenties naar producten, het aantal, en de eigenaar van de winkelmand om wat te noemen. Het is ook niet de verantwoordelijkheid van de winkelmand om productinformatie op te zoeken of via de API beschikbaar te stellen, daar is de productservice verantwoordelijk voor. Dus een ID van het product opnemen zoals in je voorbeeld is dan voldoende.

Als je die winkelmandservice can benadert vanaf een andere service of een frontend hoef je alleen te weten wat er in de winkelmand API zit en wat het schema van de data is. Met schema bedoelen we niet database-schema ofzo, maar API schema, wat iets ongedefinieerds kan zijn (zoals een blob json en zoek het maar uit) of iets compleet vastgelegd zoals een GraphQL API of een API met AVRO schema. Of iets in het midden met een Swagger API definitie.

[ Voor 13% gewijzigd door johnkeates op 25-03-2020 11:06 ]


Acties:
  • 0 Henk 'm!

  • Un93m59
  • Registratie: Juli 2016
  • Laatst online: 04-10 17:29
hartstikke bedankt voor de antwoorden allemaal

Ik kan verder 8) wens jullie allemaal het beste en veel programmeerplezier 8)

[ Voor 83% gewijzigd door Un93m59 op 25-03-2020 11:19 ]


Acties:
  • 0 Henk 'm!

  • johnkeates
  • Registratie: Februari 2008
  • Laatst online: 04-07 16:30
Un93m59 schreef op woensdag 25 maart 2020 @ 11:19:
hartstikke bedankt voor de antwoorden allemaal

Ik kan verder 8) wens jullie allemaal het beste en veel programmeerplezier 8)
Er is (afhankelijk van hoe je je API beschikbaar stelt) ook nog een leuke optie: lichtgewicht standaarden om referenties naar andere services in je API output mee te geven. Er zijn ook 'grotere' opties zoals GraphQL, maar als je klein/simpel wil beginnen kan je bijv. bij een antwoord van een winkelmand niet alleen de product ID's teruggeven maar ook _ref o.id. er bij meegeven met daarin de plek waar het ID opgevraagd kan worden om de rest van het product te vinden.

Er is een of andere Swagger/OpenAPI pagina die het een beetje laat zien: https://swagger.io/docs/specification/using-ref/

[ Voor 8% gewijzigd door johnkeates op 25-03-2020 11:23 ]


Acties:
  • 0 Henk 'm!

  • Un93m59
  • Registratie: Juli 2016
  • Laatst online: 04-10 17:29
johnkeates schreef op woensdag 25 maart 2020 @ 11:22:
[...]


Er is (afhankelijk van hoe je je API beschikbaar stelt) ook nog een leuke optie: lichtgewicht standaarden om referenties naar andere services in je API output mee te geven. Er zijn ook 'grotere' opties zoals GraphQL, maar als je klein/simpel wil beginnen kan je bijv. bij een antwoord van een winkelmand niet alleen de product ID's teruggeven maar ook _ref o.id. er bij meegeven met daarin de plek waar het ID opgevraagd kan worden om de rest van het product te vinden.

Er is een of andere Swagger/OpenAPI pagina die het een beetje laat zien: https://swagger.io/docs/specification/using-ref/
bedankt!

ooh echt heel cool, daar ga ik zeker naar kijken!. Het doet me een beetje denken aan het begrip HATEOAS, of heeft dat er niets mee te maken/vergelijken?

Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Ik wist voordat ik ging reageren dat me er eigenlijk gewoon buiten moest houden, maar... hier gaan we.
johnkeates schreef op woensdag 25 maart 2020 @ 10:37:
[...]
Juist wel, het gaat ook niet om een DTO, da's iets wat je vooral binnen een applicatie verwacht. Een API is ook gewoon versioned. Als je dus een modificatie doet die breaking is (bijv. toevoegen van verplichte velden) moet je je API versie ophogen. Dan draai je dus zolang het in gebruik is twee versies van de API.
Een DTO is een Data Transfer Object, een verzamelnaam voor envelopjes met data: een json representatie van data valt daar dus ook onder. Of het nu een object is tussen een library en een applicatie of een client met een service is irrelevant.
Dat een API versioned is; vanzelfsprekend. Het gaat erom dat je bij een 'centrale' definitie van je modellen niet een gedeelde verantwoordlijkheid hebt; maw: als elke afdeling binnen een bedrijf een eigen service exposed, moeten zij allemaal de centrale modellen updaten maar zijn er niet verantwoordlijk voor.
johnkeates schreef op woensdag 25 maart 2020 @ 10:37:
[...]
Dat is hoe zo'n beetje de hele wereld productie microservices draait.
...Citation needed... Lekkere uitspraak. :+
johnkeates schreef op woensdag 25 maart 2020 @ 10:37:
[...]
Als je puur 'een kleinere service' draait dan is dat geen microservice maar een 'kleinere service'. Microservices zijn niet slechts hoe 'groot' je applicatie is of hoe veel services je per applicatie aanbiedt. Het is ook geen vertaling van een database, een DAL of DTO of iets dergelijks.
Het gaat om het toepassen van principes in architectuur. Hoe een ORM zijn modellen exposed aan een consumerende applicatie verschilt niet veel van hoe een client modellen van een service consumeert. Het is enkel een ander abstractieniveau van dezelfde principes.
johnkeates schreef op woensdag 25 maart 2020 @ 10:37:
[...]
Je gaat dus niet een relationele database nabouwen maar je maakt een decompositie van herbruikbare en individueel schaalbare componenten.
Modellen die je service exposen staan los van de modellen in je (relationele) database, als je er al vanuit gaat dat elke service die modellen exposed een database heeft.
johnkeates schreef op woensdag 25 maart 2020 @ 10:37:
[...]
Voorbeeld: je maakt een shop en je hebt orders en producten en een winkelmand en klanten (en nog veel meer maar date laten we even voor wat het is):

Je frontend staat los van je backend. Misschien heb je een site die de frontpage laat zien, een die zoekopdrachten verwerkt, een voor de winkelmand, een voor de kassa, allemaal met een eigen verantwoordelijkheid. Of misschien is het juist een SPA, who knows.
Check, ik wilde eigenlijk nog niet eens een verschil maken in frontend of backend, je hebt een client en een service. Of die client nu een frontend is of een andere service of een applicatie van een derde partij is irrelevant. Maar voor dit voorbeeld: backend-frontend, ok.
johnkeates schreef op woensdag 25 maart 2020 @ 10:37:
[...]
Die gaat met je backend communiceren, door met een API te praten. Die API is niet rechtstreeks de API van een instance van een service maar een gateway of ingress controller. Je praat voor je requests tegen zo'n gateway of ingress en die zoekt verder zelf uit naar welke service en welke instance van zo'n service je request gaat.
Dat weet je niet en is irrelevant. Nogmaals: een client praat met een service. Hoeveel routers, reverse proxies, gateways, ingress controllers of andere hippe infrastructuurvoorzieningen nodig zijn is voor dit vraagstuk irrelevant.
johnkeates schreef op woensdag 25 maart 2020 @ 10:37:
[...]
Stel dat je frontend wil weten hoe veel items in je winkelmand zitten doet ie misschien een request naar winkel.com/api/v1/winkelmand en afhankelijk van hoe efficient je het bouwt een GET met een /count of een complete GET en dan in de frontend een count van de resultaten. Dan maakt het dus niet uit wat het contract of datamodel aan de binnenkant is, je werkt dan ook niet met een 'entity' maar met een API schema.
Het API schema dat, in jouw voorbeeld, via een gateway ontsloten wordt is de public facing API. Waar de TS het over heeft is een API van een service (bijvoorbeeld van TS: 'orders'). Elke service kan door een ander bedrijf(onderdeel) opgeleverd worden of in een andere taal geschreven zijn of niet eens in hetzelfde VPC staan. Ik zie nog steeds niet in waarom je gedeelde code na zou willen streven, met alle afhankelijkheidsimplicaties van dien.

Bovendien zou een model X dat service A met service B (gedeeltelijk) 'deelt' onderdeel uitmaken van die centrale code. Service C deelt model Y (gedeeltelijk) met zowel A en B, maar geeft niks om model X. Waarom zou X dan onderdeel moeten uitmaken van C?

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • +1 Henk 'm!

  • johnkeates
  • Registratie: Februari 2008
  • Laatst online: 04-07 16:30
Leuk verhaal maar hier heeft Un93m59 helemaal niks aan. Het is net alsof je zijn onderliggende vraag niet doorziet.

Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

johnkeates schreef op woensdag 25 maart 2020 @ 16:32:
[...]
Leuk verhaal maar hier heeft Un93m59 helemaal niks aan.
Dank. Dat leuke verhaal is een reactie op jouw 'verhaal', want antwoord op Un93m59 had ik al gegeven.
johnkeates schreef op woensdag 25 maart 2020 @ 16:32:
[...]
Het is net alsof je zijn onderliggende vraag niet doorziet.
Hij vraagt hoe een class een entiteit kan gebruiken die gedefinieerd is in een andere microservice in hetzelfde domein.

Mijn antwoord hierop is dat het delen ervan is niet nodig is: ieder zijn eigen verantwoordelijkheid. Wat bovendien door Vloris bevestigd wordt.
Vloris schreef op woensdag 25 maart 2020 @ 10:29:
Als ik het goed begrijp zoek je naar een manier om in al je microservices gebruik te kunnen maken van hetzelfde domeinmodel?

Als je in meerdere microservices hetzelfde model zou willen gebruiken moet je je afvragen waarom je het dan überhaubt opgesplitst hebt. Het hele idee van microservices is namelijk juist dat elke service zijn/haar eigen datamodel heeft, met daarin alleen de elementen die nodig zijn voor die specifieke microservice.

Niet één datamodel dat je overal gebruikt en overal heen en weer stuurt dus.
Daarna ga je er tegenin, wat ik in mijn 'verhaal' probeer uit te leggen. Echter de toon die je aanslaat in je laatste reactie nodigt weinig uit tot discussie dus ik laat het er maar bij.

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant

Pagina: 1