[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-nl-\u002Fblog\u002Fsaas-architecture-patterns-\u002Fblog\u002Fsaas-architecture-patterns":3,"blog-post-surround-nl-\u002Fblog\u002Fsaas-architecture-patterns-\u002Fblog\u002Fsaas-architecture-patterns":5609,"related-posts-nl-\u002Fblog\u002Fsaas-architecture-patterns-\u002Fblog\u002Fsaas-architecture-patterns":5616},{"id":4,"title":5,"authors":6,"badge":13,"body":15,"categories":5591,"date":5593,"description":5594,"extension":5595,"image":5596,"meta":5598,"navigation":161,"path":5599,"readingTime":407,"seo":5600,"stem":5601,"tags":5602,"__hash__":5608},"posts_nl\u002Fblog\u002F13.saas-architecture-patterns.md","SaaS Architectuur Patronen: Schaalbare Applicaties Bouwen",[7],{"name":8,"to":9,"avatar":10,"bio":12},"Marcel Posdijk","https:\u002F\u002Fx.com\u002Fmarcelposdijk",{"src":11},"\u002Fimages\u002Fteam\u002Fmarcel.jpg","Founder en lead developer bij Ludulicious B.V. met meer dan 25 jaar ervaring in webontwikkeling en software architectuur.",{"label":14},"Architectuur",{"type":16,"value":17,"toc":5564},"minimark",[18,23,27,33,49,54,210,221,225,228,233,247,251,256,259,1146,1151,1164,1170,1174,1177,2130,2134,2148,2154,2158,2161,3073,3077,3091,3096,3100,3104,3107,3255,3259,3262,4225,4229,4243,4248,4252,4256,4259,4372,4376,4379,5193,5197,5211,5216,5220,5309,5313,5317,5328,5332,5343,5347,5358,5362,5371,5375,5386,5390,5393,5473,5477,5480,5483,5486,5506,5511,5519,5551,5554,5560],[19,20,22],"h2",{"id":21},"het-probleem-saas-die-niet-schaalt","Het Probleem: SaaS Die Niet Schaalt",[24,25,26],"p",{},"In 2023 werkten we aan een SaaS project dat perfect werkte voor 100 gebruikers, maar volledig instortte bij 1000 gebruikers. De architectuur was niet ontworpen voor schaalbaarheid—een veelvoorkomend probleem bij SaaS applicaties.",[24,28,29],{},[30,31,32],"strong",{},"De Uitdaging:",[34,35,36,40,43,46],"ul",{},[37,38,39],"li",{},"Multi-tenant database design",[37,41,42],{},"API schaalbaarheid",[37,44,45],{},"Performance onder belasting",[37,47,48],{},"Deployment en monitoring",[24,50,51],{},[30,52,53],{},"De Cijfers:",[55,56,61],"pre",{"className":57,"code":58,"language":59,"meta":60,"style":60},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Probleem: Database queries die niet schalen\nconst userCount = await db.query('SELECT COUNT(*) FROM users');\nconsole.log(`Gebruikers: ${userCount}`); \u002F\u002F 1000 gebruikers\n\n\u002F\u002F Elke query raakt alle tenants\nconst users = await db.query('SELECT * FROM users WHERE tenant_id = ?', [tenantId]);\n\u002F\u002F Geen indexering, geen caching, geen optimalisatie\n","typescript","",[62,63,64,73,120,156,163,169,204],"code",{"__ignoreMap":60},[65,66,69],"span",{"class":67,"line":68},"line",1,[65,70,72],{"class":71},"sHwdD","\u002F\u002F Probleem: Database queries die niet schalen\n",[65,74,76,80,84,88,92,95,98,102,105,108,112,114,117],{"class":67,"line":75},2,[65,77,79],{"class":78},"spNyl","const",[65,81,83],{"class":82},"sTEyZ"," userCount ",[65,85,87],{"class":86},"sMK4o","=",[65,89,91],{"class":90},"s7zQu"," await",[65,93,94],{"class":82}," db",[65,96,97],{"class":86},".",[65,99,101],{"class":100},"s2Zo4","query",[65,103,104],{"class":82},"(",[65,106,107],{"class":86},"'",[65,109,111],{"class":110},"sfazB","SELECT COUNT(*) FROM users",[65,113,107],{"class":86},[65,115,116],{"class":82},")",[65,118,119],{"class":86},";\n",[65,121,123,126,128,131,133,136,139,142,145,148,150,153],{"class":67,"line":122},3,[65,124,125],{"class":82},"console",[65,127,97],{"class":86},[65,129,130],{"class":100},"log",[65,132,104],{"class":82},[65,134,135],{"class":86},"`",[65,137,138],{"class":110},"Gebruikers: ",[65,140,141],{"class":86},"${",[65,143,144],{"class":82},"userCount",[65,146,147],{"class":86},"}`",[65,149,116],{"class":82},[65,151,152],{"class":86},";",[65,154,155],{"class":71}," \u002F\u002F 1000 gebruikers\n",[65,157,159],{"class":67,"line":158},4,[65,160,162],{"emptyLinePlaceholder":161},true,"\n",[65,164,166],{"class":67,"line":165},5,[65,167,168],{"class":71},"\u002F\u002F Elke query raakt alle tenants\n",[65,170,172,174,177,179,181,183,185,187,189,191,194,196,199,202],{"class":67,"line":171},6,[65,173,79],{"class":78},[65,175,176],{"class":82}," users ",[65,178,87],{"class":86},[65,180,91],{"class":90},[65,182,94],{"class":82},[65,184,97],{"class":86},[65,186,101],{"class":100},[65,188,104],{"class":82},[65,190,107],{"class":86},[65,192,193],{"class":110},"SELECT * FROM users WHERE tenant_id = ?",[65,195,107],{"class":86},[65,197,198],{"class":86},",",[65,200,201],{"class":82}," [tenantId])",[65,203,119],{"class":86},[65,205,207],{"class":67,"line":206},7,[65,208,209],{"class":71},"\u002F\u002F Geen indexering, geen caching, geen optimalisatie\n",[24,211,212],{},[213,214],"img",{"alt":215,"className":216,"height":218,"src":219,"width":220},"SaaS architectuur patronen",[217],"rounded-lg",600,"https:\u002F\u002Fpicsum.photos\u002Fid\u002F17\u002F1000\u002F600",1000,[19,222,224],{"id":223},"de-oorzaak-ongeoptimaliseerde-multi-tenant-architectuur","De Oorzaak: Ongeoptimaliseerde Multi-Tenant Architectuur",[24,226,227],{},"Het probleem was duidelijk uit onze monitoring:",[24,229,230],{},[30,231,232],{},"Wat er gebeurde:",[34,234,235,238,241,244],{},[37,236,237],{},"Database queries raakten alle tenants",[37,239,240],{},"Geen tenant isolatie",[37,242,243],{},"Inefficiënte API design",[37,245,246],{},"Geen caching strategie",[19,248,250],{"id":249},"de-oplossing-schaalbare-saas-architectuur","De Oplossing: Schaalbare SaaS Architectuur",[252,253,255],"h3",{"id":254},"stap-1-multi-tenant-database-design","Stap 1: Multi-Tenant Database Design",[24,257,258],{},"De eerste doorbraak kwam met multi-tenant database design:",[55,260,262],{"className":57,"code":261,"language":59,"meta":60,"style":60},"\u002F\u002F Multi-tenant database patronen\ninterface Tenant {\n  id: string;\n  name: string;\n  subdomain: string;\n  plan: 'starter' | 'professional' | 'enterprise';\n  createdAt: Date;\n  settings: TenantSettings;\n}\n\n\u002F\u002F Patroon 1: Shared Schema (aanbevolen voor startups)\ninterface SharedSchemaDesign {\n  tables: {\n    users: 'tenant_id + user_data';\n    orders: 'tenant_id + order_data';\n    products: 'tenant_id + product_data';\n  };\n  benefits: [\n    'Eenvoudige implementatie',\n    'Kosteneffectief',\n    'Eenvoudige backup\u002Frestore'\n  ];\n  drawbacks: [\n    'Mogelijke data lekken',\n    'Complexe queries',\n    'Moeilijke tenant isolatie'\n  ];\n}\n\n\u002F\u002F Patroon 2: Separate Schema (aanbevolen voor groei)\ninterface SeparateSchemaDesign {\n  schemas: {\n    tenant_1: 'Alle tabellen voor tenant 1';\n    tenant_2: 'Alle tabellen voor tenant 2';\n    tenant_3: 'Alle tabellen voor tenant 3';\n  };\n  benefits: [\n    'Betere tenant isolatie',\n    'Eenvoudigere queries',\n    'Betere performance'\n  ];\n  drawbacks: [\n    'Complexere implementatie',\n    'Hogere kosten',\n    'Complexere backup\u002Frestore'\n  ];\n}\n\n\u002F\u002F Implementatie: Shared Schema met tenant isolatie\nclass TenantAwareRepository {\n  private db: Database;\n  private tenantId: string;\n\n  constructor(db: Database, tenantId: string) {\n    this.db = db;\n    this.tenantId = tenantId;\n  }\n\n  async findUsers(): Promise\u003CUser[]> {\n    \u002F\u002F Automatische tenant isolatie\n    return this.db.query(\n      'SELECT * FROM users WHERE tenant_id = ?',\n      [this.tenantId]\n    );\n  }\n\n  async createUser(userData: UserData): Promise\u003CUser> {\n    \u002F\u002F Automatische tenant_id toevoeging\n    const result = await this.db.query(\n      'INSERT INTO users (tenant_id, name, email) VALUES (?, ?, ?)',\n      [this.tenantId, userData.name, userData.email]\n    );\n    \n    return this.findUserById(result.insertId);\n  }\n}\n",[62,263,264,269,281,295,306,317,353,365,378,384,389,395,405,415,432,449,466,472,483,497,509,520,528,538,550,562,572,579,584,589,595,605,615,632,649,666,671,680,692,704,714,721,730,742,754,764,771,776,781,787,798,813,827,832,860,875,889,895,900,929,935,953,965,979,987,992,997,1028,1034,1057,1069,1099,1106,1112,1136,1141],{"__ignoreMap":60},[65,265,266],{"class":67,"line":68},[65,267,268],{"class":71},"\u002F\u002F Multi-tenant database patronen\n",[65,270,271,274,278],{"class":67,"line":75},[65,272,273],{"class":78},"interface",[65,275,277],{"class":276},"sBMFI"," Tenant",[65,279,280],{"class":86}," {\n",[65,282,283,287,290,293],{"class":67,"line":122},[65,284,286],{"class":285},"swJcz","  id",[65,288,289],{"class":86},":",[65,291,292],{"class":276}," string",[65,294,119],{"class":86},[65,296,297,300,302,304],{"class":67,"line":158},[65,298,299],{"class":285},"  name",[65,301,289],{"class":86},[65,303,292],{"class":276},[65,305,119],{"class":86},[65,307,308,311,313,315],{"class":67,"line":165},[65,309,310],{"class":285},"  subdomain",[65,312,289],{"class":86},[65,314,292],{"class":276},[65,316,119],{"class":86},[65,318,319,322,324,327,330,332,335,337,340,342,344,346,349,351],{"class":67,"line":171},[65,320,321],{"class":285},"  plan",[65,323,289],{"class":86},[65,325,326],{"class":86}," '",[65,328,329],{"class":110},"starter",[65,331,107],{"class":86},[65,333,334],{"class":86}," |",[65,336,326],{"class":86},[65,338,339],{"class":110},"professional",[65,341,107],{"class":86},[65,343,334],{"class":86},[65,345,326],{"class":86},[65,347,348],{"class":110},"enterprise",[65,350,107],{"class":86},[65,352,119],{"class":86},[65,354,355,358,360,363],{"class":67,"line":206},[65,356,357],{"class":285},"  createdAt",[65,359,289],{"class":86},[65,361,362],{"class":276}," Date",[65,364,119],{"class":86},[65,366,368,371,373,376],{"class":67,"line":367},8,[65,369,370],{"class":285},"  settings",[65,372,289],{"class":86},[65,374,375],{"class":276}," TenantSettings",[65,377,119],{"class":86},[65,379,381],{"class":67,"line":380},9,[65,382,383],{"class":86},"}\n",[65,385,387],{"class":67,"line":386},10,[65,388,162],{"emptyLinePlaceholder":161},[65,390,392],{"class":67,"line":391},11,[65,393,394],{"class":71},"\u002F\u002F Patroon 1: Shared Schema (aanbevolen voor startups)\n",[65,396,398,400,403],{"class":67,"line":397},12,[65,399,273],{"class":78},[65,401,402],{"class":276}," SharedSchemaDesign",[65,404,280],{"class":86},[65,406,408,411,413],{"class":67,"line":407},13,[65,409,410],{"class":285},"  tables",[65,412,289],{"class":86},[65,414,280],{"class":86},[65,416,418,421,423,425,428,430],{"class":67,"line":417},14,[65,419,420],{"class":285},"    users",[65,422,289],{"class":86},[65,424,326],{"class":86},[65,426,427],{"class":110},"tenant_id + user_data",[65,429,107],{"class":86},[65,431,119],{"class":86},[65,433,435,438,440,442,445,447],{"class":67,"line":434},15,[65,436,437],{"class":285},"    orders",[65,439,289],{"class":86},[65,441,326],{"class":86},[65,443,444],{"class":110},"tenant_id + order_data",[65,446,107],{"class":86},[65,448,119],{"class":86},[65,450,452,455,457,459,462,464],{"class":67,"line":451},16,[65,453,454],{"class":285},"    products",[65,456,289],{"class":86},[65,458,326],{"class":86},[65,460,461],{"class":110},"tenant_id + product_data",[65,463,107],{"class":86},[65,465,119],{"class":86},[65,467,469],{"class":67,"line":468},17,[65,470,471],{"class":86},"  };\n",[65,473,475,478,480],{"class":67,"line":474},18,[65,476,477],{"class":285},"  benefits",[65,479,289],{"class":86},[65,481,482],{"class":82}," [\n",[65,484,486,489,492,494],{"class":67,"line":485},19,[65,487,488],{"class":86},"    '",[65,490,491],{"class":110},"Eenvoudige implementatie",[65,493,107],{"class":86},[65,495,496],{"class":86},",\n",[65,498,500,502,505,507],{"class":67,"line":499},20,[65,501,488],{"class":86},[65,503,504],{"class":110},"Kosteneffectief",[65,506,107],{"class":86},[65,508,496],{"class":86},[65,510,512,514,517],{"class":67,"line":511},21,[65,513,488],{"class":86},[65,515,516],{"class":110},"Eenvoudige backup\u002Frestore",[65,518,519],{"class":86},"'\n",[65,521,523,526],{"class":67,"line":522},22,[65,524,525],{"class":82},"  ]",[65,527,119],{"class":86},[65,529,531,534,536],{"class":67,"line":530},23,[65,532,533],{"class":285},"  drawbacks",[65,535,289],{"class":86},[65,537,482],{"class":82},[65,539,541,543,546,548],{"class":67,"line":540},24,[65,542,488],{"class":86},[65,544,545],{"class":110},"Mogelijke data lekken",[65,547,107],{"class":86},[65,549,496],{"class":86},[65,551,553,555,558,560],{"class":67,"line":552},25,[65,554,488],{"class":86},[65,556,557],{"class":110},"Complexe queries",[65,559,107],{"class":86},[65,561,496],{"class":86},[65,563,565,567,570],{"class":67,"line":564},26,[65,566,488],{"class":86},[65,568,569],{"class":110},"Moeilijke tenant isolatie",[65,571,519],{"class":86},[65,573,575,577],{"class":67,"line":574},27,[65,576,525],{"class":82},[65,578,119],{"class":86},[65,580,582],{"class":67,"line":581},28,[65,583,383],{"class":86},[65,585,587],{"class":67,"line":586},29,[65,588,162],{"emptyLinePlaceholder":161},[65,590,592],{"class":67,"line":591},30,[65,593,594],{"class":71},"\u002F\u002F Patroon 2: Separate Schema (aanbevolen voor groei)\n",[65,596,598,600,603],{"class":67,"line":597},31,[65,599,273],{"class":78},[65,601,602],{"class":276}," SeparateSchemaDesign",[65,604,280],{"class":86},[65,606,608,611,613],{"class":67,"line":607},32,[65,609,610],{"class":285},"  schemas",[65,612,289],{"class":86},[65,614,280],{"class":86},[65,616,618,621,623,625,628,630],{"class":67,"line":617},33,[65,619,620],{"class":285},"    tenant_1",[65,622,289],{"class":86},[65,624,326],{"class":86},[65,626,627],{"class":110},"Alle tabellen voor tenant 1",[65,629,107],{"class":86},[65,631,119],{"class":86},[65,633,635,638,640,642,645,647],{"class":67,"line":634},34,[65,636,637],{"class":285},"    tenant_2",[65,639,289],{"class":86},[65,641,326],{"class":86},[65,643,644],{"class":110},"Alle tabellen voor tenant 2",[65,646,107],{"class":86},[65,648,119],{"class":86},[65,650,652,655,657,659,662,664],{"class":67,"line":651},35,[65,653,654],{"class":285},"    tenant_3",[65,656,289],{"class":86},[65,658,326],{"class":86},[65,660,661],{"class":110},"Alle tabellen voor tenant 3",[65,663,107],{"class":86},[65,665,119],{"class":86},[65,667,669],{"class":67,"line":668},36,[65,670,471],{"class":86},[65,672,674,676,678],{"class":67,"line":673},37,[65,675,477],{"class":285},[65,677,289],{"class":86},[65,679,482],{"class":82},[65,681,683,685,688,690],{"class":67,"line":682},38,[65,684,488],{"class":86},[65,686,687],{"class":110},"Betere tenant isolatie",[65,689,107],{"class":86},[65,691,496],{"class":86},[65,693,695,697,700,702],{"class":67,"line":694},39,[65,696,488],{"class":86},[65,698,699],{"class":110},"Eenvoudigere queries",[65,701,107],{"class":86},[65,703,496],{"class":86},[65,705,707,709,712],{"class":67,"line":706},40,[65,708,488],{"class":86},[65,710,711],{"class":110},"Betere performance",[65,713,519],{"class":86},[65,715,717,719],{"class":67,"line":716},41,[65,718,525],{"class":82},[65,720,119],{"class":86},[65,722,724,726,728],{"class":67,"line":723},42,[65,725,533],{"class":285},[65,727,289],{"class":86},[65,729,482],{"class":82},[65,731,733,735,738,740],{"class":67,"line":732},43,[65,734,488],{"class":86},[65,736,737],{"class":110},"Complexere implementatie",[65,739,107],{"class":86},[65,741,496],{"class":86},[65,743,745,747,750,752],{"class":67,"line":744},44,[65,746,488],{"class":86},[65,748,749],{"class":110},"Hogere kosten",[65,751,107],{"class":86},[65,753,496],{"class":86},[65,755,757,759,762],{"class":67,"line":756},45,[65,758,488],{"class":86},[65,760,761],{"class":110},"Complexere backup\u002Frestore",[65,763,519],{"class":86},[65,765,767,769],{"class":67,"line":766},46,[65,768,525],{"class":82},[65,770,119],{"class":86},[65,772,774],{"class":67,"line":773},47,[65,775,383],{"class":86},[65,777,779],{"class":67,"line":778},48,[65,780,162],{"emptyLinePlaceholder":161},[65,782,784],{"class":67,"line":783},49,[65,785,786],{"class":71},"\u002F\u002F Implementatie: Shared Schema met tenant isolatie\n",[65,788,790,793,796],{"class":67,"line":789},50,[65,791,792],{"class":78},"class",[65,794,795],{"class":276}," TenantAwareRepository",[65,797,280],{"class":86},[65,799,801,804,806,808,811],{"class":67,"line":800},51,[65,802,803],{"class":78},"  private",[65,805,94],{"class":285},[65,807,289],{"class":86},[65,809,810],{"class":276}," Database",[65,812,119],{"class":86},[65,814,816,818,821,823,825],{"class":67,"line":815},52,[65,817,803],{"class":78},[65,819,820],{"class":285}," tenantId",[65,822,289],{"class":86},[65,824,292],{"class":276},[65,826,119],{"class":86},[65,828,830],{"class":67,"line":829},53,[65,831,162],{"emptyLinePlaceholder":161},[65,833,835,838,840,844,846,848,850,852,854,856,858],{"class":67,"line":834},54,[65,836,837],{"class":78},"  constructor",[65,839,104],{"class":86},[65,841,843],{"class":842},"sHdIc","db",[65,845,289],{"class":86},[65,847,810],{"class":276},[65,849,198],{"class":86},[65,851,820],{"class":842},[65,853,289],{"class":86},[65,855,292],{"class":276},[65,857,116],{"class":86},[65,859,280],{"class":86},[65,861,863,866,868,871,873],{"class":67,"line":862},55,[65,864,865],{"class":86},"    this.",[65,867,843],{"class":82},[65,869,870],{"class":86}," =",[65,872,94],{"class":82},[65,874,119],{"class":86},[65,876,878,880,883,885,887],{"class":67,"line":877},56,[65,879,865],{"class":86},[65,881,882],{"class":82},"tenantId",[65,884,870],{"class":86},[65,886,820],{"class":82},[65,888,119],{"class":86},[65,890,892],{"class":67,"line":891},57,[65,893,894],{"class":86},"  }\n",[65,896,898],{"class":67,"line":897},58,[65,899,162],{"emptyLinePlaceholder":161},[65,901,903,906,909,912,915,918,921,924,927],{"class":67,"line":902},59,[65,904,905],{"class":78},"  async",[65,907,908],{"class":285}," findUsers",[65,910,911],{"class":86},"():",[65,913,914],{"class":276}," Promise",[65,916,917],{"class":86},"\u003C",[65,919,920],{"class":276},"User",[65,922,923],{"class":82},"[]",[65,925,926],{"class":86},">",[65,928,280],{"class":86},[65,930,932],{"class":67,"line":931},60,[65,933,934],{"class":71},"    \u002F\u002F Automatische tenant isolatie\n",[65,936,938,941,944,946,948,950],{"class":67,"line":937},61,[65,939,940],{"class":90},"    return",[65,942,943],{"class":86}," this.",[65,945,843],{"class":82},[65,947,97],{"class":86},[65,949,101],{"class":100},[65,951,952],{"class":285},"(\n",[65,954,956,959,961,963],{"class":67,"line":955},62,[65,957,958],{"class":86},"      '",[65,960,193],{"class":110},[65,962,107],{"class":86},[65,964,496],{"class":86},[65,966,968,971,974,976],{"class":67,"line":967},63,[65,969,970],{"class":285},"      [",[65,972,973],{"class":86},"this.",[65,975,882],{"class":82},[65,977,978],{"class":285},"]\n",[65,980,982,985],{"class":67,"line":981},64,[65,983,984],{"class":285},"    )",[65,986,119],{"class":86},[65,988,990],{"class":67,"line":989},65,[65,991,894],{"class":86},[65,993,995],{"class":67,"line":994},66,[65,996,162],{"emptyLinePlaceholder":161},[65,998,1000,1002,1005,1007,1010,1012,1015,1018,1020,1022,1024,1026],{"class":67,"line":999},67,[65,1001,905],{"class":78},[65,1003,1004],{"class":285}," createUser",[65,1006,104],{"class":86},[65,1008,1009],{"class":842},"userData",[65,1011,289],{"class":86},[65,1013,1014],{"class":276}," UserData",[65,1016,1017],{"class":86},"):",[65,1019,914],{"class":276},[65,1021,917],{"class":86},[65,1023,920],{"class":276},[65,1025,926],{"class":86},[65,1027,280],{"class":86},[65,1029,1031],{"class":67,"line":1030},68,[65,1032,1033],{"class":71},"    \u002F\u002F Automatische tenant_id toevoeging\n",[65,1035,1037,1040,1043,1045,1047,1049,1051,1053,1055],{"class":67,"line":1036},69,[65,1038,1039],{"class":78},"    const",[65,1041,1042],{"class":82}," result",[65,1044,870],{"class":86},[65,1046,91],{"class":90},[65,1048,943],{"class":86},[65,1050,843],{"class":82},[65,1052,97],{"class":86},[65,1054,101],{"class":100},[65,1056,952],{"class":285},[65,1058,1060,1062,1065,1067],{"class":67,"line":1059},70,[65,1061,958],{"class":86},[65,1063,1064],{"class":110},"INSERT INTO users (tenant_id, name, email) VALUES (?, ?, ?)",[65,1066,107],{"class":86},[65,1068,496],{"class":86},[65,1070,1072,1074,1076,1078,1080,1083,1085,1088,1090,1092,1094,1097],{"class":67,"line":1071},71,[65,1073,970],{"class":285},[65,1075,973],{"class":86},[65,1077,882],{"class":82},[65,1079,198],{"class":86},[65,1081,1082],{"class":82}," userData",[65,1084,97],{"class":86},[65,1086,1087],{"class":82},"name",[65,1089,198],{"class":86},[65,1091,1082],{"class":82},[65,1093,97],{"class":86},[65,1095,1096],{"class":82},"email",[65,1098,978],{"class":285},[65,1100,1102,1104],{"class":67,"line":1101},72,[65,1103,984],{"class":285},[65,1105,119],{"class":86},[65,1107,1109],{"class":67,"line":1108},73,[65,1110,1111],{"class":285},"    \n",[65,1113,1115,1117,1119,1122,1124,1127,1129,1132,1134],{"class":67,"line":1114},74,[65,1116,940],{"class":90},[65,1118,943],{"class":86},[65,1120,1121],{"class":100},"findUserById",[65,1123,104],{"class":285},[65,1125,1126],{"class":82},"result",[65,1128,97],{"class":86},[65,1130,1131],{"class":82},"insertId",[65,1133,116],{"class":285},[65,1135,119],{"class":86},[65,1137,1139],{"class":67,"line":1138},75,[65,1140,894],{"class":86},[65,1142,1144],{"class":67,"line":1143},76,[65,1145,383],{"class":86},[24,1147,1148],{},[30,1149,1150],{},"Waarom Dit Werkt:",[34,1152,1153,1156,1158,1161],{},[37,1154,1155],{},"Automatische tenant isolatie",[37,1157,491],{},[37,1159,1160],{},"Kosteneffectief voor startups",[37,1162,1163],{},"Schaalbaar naar enterprise",[24,1165,1166,1169],{},[30,1167,1168],{},"Immediate Resultaat:"," Database performance verbeterde met 70% door tenant isolatie",[252,1171,1173],{"id":1172},"stap-2-tenant-resolution-systeem","Stap 2: Tenant Resolution Systeem",[24,1175,1176],{},"Met betere database design werd tenant resolution de volgende stap:",[55,1178,1180],{"className":57,"code":1179,"language":59,"meta":60,"style":60},"\u002F\u002F Tenant resolution systeem\ninterface TenantResolver {\n  resolveTenant(request: Request): Promise\u003CTenant>;\n  cacheTenant(tenant: Tenant): void;\n  invalidateTenant(tenantId: string): void;\n}\n\nclass CachedTenantResolver implements TenantResolver {\n  private redis: Redis;\n  private db: Database;\n  private cache: Map\u003Cstring, Tenant> = new Map();\n\n  async resolveTenant(request: Request): Promise\u003CTenant> {\n    const subdomain = this.extractSubdomain(request);\n    const cacheKey = `tenant:${subdomain}`;\n    \n    \u002F\u002F Probeer cache eerst\n    let tenant = this.cache.get(cacheKey);\n    if (tenant) {\n      return tenant;\n    }\n\n    \u002F\u002F Probeer Redis cache\n    const cached = await this.redis.get(cacheKey);\n    if (cached) {\n      tenant = JSON.parse(cached);\n      this.cache.set(cacheKey, tenant);\n      return tenant;\n    }\n\n    \u002F\u002F Haal uit database\n    const result = await this.db.query(\n      'SELECT * FROM tenants WHERE subdomain = ?',\n      [subdomain]\n    );\n\n    if (result.length === 0) {\n      throw new Error('Tenant niet gevonden');\n    }\n\n    tenant = result[0];\n    \n    \u002F\u002F Cache voor volgende keer\n    await this.redis.setex(cacheKey, 3600, JSON.stringify(tenant)); \u002F\u002F 1 uur TTL\n    this.cache.set(cacheKey, tenant);\n\n    return tenant;\n  }\n\n  private extractSubdomain(request: Request): string {\n    const host = request.headers.host;\n    const parts = host.split('.');\n    return parts[0]; \u002F\u002F eerste deel is subdomain\n  }\n\n  async invalidateTenant(tenantId: string): Promise\u003Cvoid> {\n    \u002F\u002F Verwijder uit alle caches\n    const tenant = await this.db.query(\n      'SELECT subdomain FROM tenants WHERE id = ?',\n      [tenantId]\n    );\n\n    if (tenant.length > 0) {\n      const subdomain = tenant[0].subdomain;\n      const cacheKey = `tenant:${subdomain}`;\n      \n      await this.redis.del(cacheKey);\n      this.cache.delete(cacheKey);\n    }\n  }\n}\n",[62,1181,1182,1187,1196,1223,1244,1263,1267,1271,1285,1299,1311,1346,1350,1377,1399,1423,1427,1432,1461,1477,1486,1491,1495,1500,1528,1541,1564,1588,1596,1600,1604,1609,1629,1640,1648,1654,1658,1682,1705,1709,1713,1733,1737,1742,1786,1808,1812,1820,1824,1828,1849,1873,1901,1918,1922,1926,1954,1959,1979,1990,1998,2004,2008,2029,2052,2072,2077,2099,2118,2122,2126],{"__ignoreMap":60},[65,1183,1184],{"class":67,"line":68},[65,1185,1186],{"class":71},"\u002F\u002F Tenant resolution systeem\n",[65,1188,1189,1191,1194],{"class":67,"line":75},[65,1190,273],{"class":78},[65,1192,1193],{"class":276}," TenantResolver",[65,1195,280],{"class":86},[65,1197,1198,1201,1203,1206,1208,1211,1213,1215,1217,1220],{"class":67,"line":122},[65,1199,1200],{"class":285},"  resolveTenant",[65,1202,104],{"class":86},[65,1204,1205],{"class":842},"request",[65,1207,289],{"class":86},[65,1209,1210],{"class":276}," Request",[65,1212,1017],{"class":86},[65,1214,914],{"class":276},[65,1216,917],{"class":86},[65,1218,1219],{"class":276},"Tenant",[65,1221,1222],{"class":86},">;\n",[65,1224,1225,1228,1230,1233,1235,1237,1239,1242],{"class":67,"line":158},[65,1226,1227],{"class":285},"  cacheTenant",[65,1229,104],{"class":86},[65,1231,1232],{"class":842},"tenant",[65,1234,289],{"class":86},[65,1236,277],{"class":276},[65,1238,1017],{"class":86},[65,1240,1241],{"class":276}," void",[65,1243,119],{"class":86},[65,1245,1246,1249,1251,1253,1255,1257,1259,1261],{"class":67,"line":165},[65,1247,1248],{"class":285},"  invalidateTenant",[65,1250,104],{"class":86},[65,1252,882],{"class":842},[65,1254,289],{"class":86},[65,1256,292],{"class":276},[65,1258,1017],{"class":86},[65,1260,1241],{"class":276},[65,1262,119],{"class":86},[65,1264,1265],{"class":67,"line":171},[65,1266,383],{"class":86},[65,1268,1269],{"class":67,"line":206},[65,1270,162],{"emptyLinePlaceholder":161},[65,1272,1273,1275,1278,1281,1283],{"class":67,"line":367},[65,1274,792],{"class":78},[65,1276,1277],{"class":276}," CachedTenantResolver",[65,1279,1280],{"class":78}," implements",[65,1282,1193],{"class":276},[65,1284,280],{"class":86},[65,1286,1287,1289,1292,1294,1297],{"class":67,"line":380},[65,1288,803],{"class":78},[65,1290,1291],{"class":285}," redis",[65,1293,289],{"class":86},[65,1295,1296],{"class":276}," Redis",[65,1298,119],{"class":86},[65,1300,1301,1303,1305,1307,1309],{"class":67,"line":386},[65,1302,803],{"class":78},[65,1304,94],{"class":285},[65,1306,289],{"class":86},[65,1308,810],{"class":276},[65,1310,119],{"class":86},[65,1312,1313,1315,1318,1320,1323,1325,1328,1330,1332,1334,1336,1339,1341,1344],{"class":67,"line":391},[65,1314,803],{"class":78},[65,1316,1317],{"class":285}," cache",[65,1319,289],{"class":86},[65,1321,1322],{"class":276}," Map",[65,1324,917],{"class":86},[65,1326,1327],{"class":276},"string",[65,1329,198],{"class":86},[65,1331,277],{"class":276},[65,1333,926],{"class":86},[65,1335,870],{"class":86},[65,1337,1338],{"class":86}," new",[65,1340,1322],{"class":285},[65,1342,1343],{"class":82},"()",[65,1345,119],{"class":86},[65,1347,1348],{"class":67,"line":397},[65,1349,162],{"emptyLinePlaceholder":161},[65,1351,1352,1354,1357,1359,1361,1363,1365,1367,1369,1371,1373,1375],{"class":67,"line":407},[65,1353,905],{"class":78},[65,1355,1356],{"class":285}," resolveTenant",[65,1358,104],{"class":86},[65,1360,1205],{"class":842},[65,1362,289],{"class":86},[65,1364,1210],{"class":276},[65,1366,1017],{"class":86},[65,1368,914],{"class":276},[65,1370,917],{"class":86},[65,1372,1219],{"class":276},[65,1374,926],{"class":86},[65,1376,280],{"class":86},[65,1378,1379,1381,1384,1386,1388,1391,1393,1395,1397],{"class":67,"line":417},[65,1380,1039],{"class":78},[65,1382,1383],{"class":82}," subdomain",[65,1385,870],{"class":86},[65,1387,943],{"class":86},[65,1389,1390],{"class":100},"extractSubdomain",[65,1392,104],{"class":285},[65,1394,1205],{"class":82},[65,1396,116],{"class":285},[65,1398,119],{"class":86},[65,1400,1401,1403,1406,1408,1411,1414,1416,1419,1421],{"class":67,"line":434},[65,1402,1039],{"class":78},[65,1404,1405],{"class":82}," cacheKey",[65,1407,870],{"class":86},[65,1409,1410],{"class":86}," `",[65,1412,1413],{"class":110},"tenant:",[65,1415,141],{"class":86},[65,1417,1418],{"class":82},"subdomain",[65,1420,147],{"class":86},[65,1422,119],{"class":86},[65,1424,1425],{"class":67,"line":451},[65,1426,1111],{"class":285},[65,1428,1429],{"class":67,"line":468},[65,1430,1431],{"class":71},"    \u002F\u002F Probeer cache eerst\n",[65,1433,1434,1437,1440,1442,1444,1447,1449,1452,1454,1457,1459],{"class":67,"line":474},[65,1435,1436],{"class":78},"    let",[65,1438,1439],{"class":82}," tenant",[65,1441,870],{"class":86},[65,1443,943],{"class":86},[65,1445,1446],{"class":82},"cache",[65,1448,97],{"class":86},[65,1450,1451],{"class":100},"get",[65,1453,104],{"class":285},[65,1455,1456],{"class":82},"cacheKey",[65,1458,116],{"class":285},[65,1460,119],{"class":86},[65,1462,1463,1466,1469,1471,1474],{"class":67,"line":485},[65,1464,1465],{"class":90},"    if",[65,1467,1468],{"class":285}," (",[65,1470,1232],{"class":82},[65,1472,1473],{"class":285},") ",[65,1475,1476],{"class":86},"{\n",[65,1478,1479,1482,1484],{"class":67,"line":499},[65,1480,1481],{"class":90},"      return",[65,1483,1439],{"class":82},[65,1485,119],{"class":86},[65,1487,1488],{"class":67,"line":511},[65,1489,1490],{"class":86},"    }\n",[65,1492,1493],{"class":67,"line":522},[65,1494,162],{"emptyLinePlaceholder":161},[65,1496,1497],{"class":67,"line":530},[65,1498,1499],{"class":71},"    \u002F\u002F Probeer Redis cache\n",[65,1501,1502,1504,1507,1509,1511,1513,1516,1518,1520,1522,1524,1526],{"class":67,"line":540},[65,1503,1039],{"class":78},[65,1505,1506],{"class":82}," cached",[65,1508,870],{"class":86},[65,1510,91],{"class":90},[65,1512,943],{"class":86},[65,1514,1515],{"class":82},"redis",[65,1517,97],{"class":86},[65,1519,1451],{"class":100},[65,1521,104],{"class":285},[65,1523,1456],{"class":82},[65,1525,116],{"class":285},[65,1527,119],{"class":86},[65,1529,1530,1532,1534,1537,1539],{"class":67,"line":552},[65,1531,1465],{"class":90},[65,1533,1468],{"class":285},[65,1535,1536],{"class":82},"cached",[65,1538,1473],{"class":285},[65,1540,1476],{"class":86},[65,1542,1543,1546,1548,1551,1553,1556,1558,1560,1562],{"class":67,"line":564},[65,1544,1545],{"class":82},"      tenant",[65,1547,870],{"class":86},[65,1549,1550],{"class":82}," JSON",[65,1552,97],{"class":86},[65,1554,1555],{"class":100},"parse",[65,1557,104],{"class":285},[65,1559,1536],{"class":82},[65,1561,116],{"class":285},[65,1563,119],{"class":86},[65,1565,1566,1569,1571,1573,1576,1578,1580,1582,1584,1586],{"class":67,"line":574},[65,1567,1568],{"class":86},"      this.",[65,1570,1446],{"class":82},[65,1572,97],{"class":86},[65,1574,1575],{"class":100},"set",[65,1577,104],{"class":285},[65,1579,1456],{"class":82},[65,1581,198],{"class":86},[65,1583,1439],{"class":82},[65,1585,116],{"class":285},[65,1587,119],{"class":86},[65,1589,1590,1592,1594],{"class":67,"line":581},[65,1591,1481],{"class":90},[65,1593,1439],{"class":82},[65,1595,119],{"class":86},[65,1597,1598],{"class":67,"line":586},[65,1599,1490],{"class":86},[65,1601,1602],{"class":67,"line":591},[65,1603,162],{"emptyLinePlaceholder":161},[65,1605,1606],{"class":67,"line":597},[65,1607,1608],{"class":71},"    \u002F\u002F Haal uit database\n",[65,1610,1611,1613,1615,1617,1619,1621,1623,1625,1627],{"class":67,"line":607},[65,1612,1039],{"class":78},[65,1614,1042],{"class":82},[65,1616,870],{"class":86},[65,1618,91],{"class":90},[65,1620,943],{"class":86},[65,1622,843],{"class":82},[65,1624,97],{"class":86},[65,1626,101],{"class":100},[65,1628,952],{"class":285},[65,1630,1631,1633,1636,1638],{"class":67,"line":617},[65,1632,958],{"class":86},[65,1634,1635],{"class":110},"SELECT * FROM tenants WHERE subdomain = ?",[65,1637,107],{"class":86},[65,1639,496],{"class":86},[65,1641,1642,1644,1646],{"class":67,"line":634},[65,1643,970],{"class":285},[65,1645,1418],{"class":82},[65,1647,978],{"class":285},[65,1649,1650,1652],{"class":67,"line":651},[65,1651,984],{"class":285},[65,1653,119],{"class":86},[65,1655,1656],{"class":67,"line":668},[65,1657,162],{"emptyLinePlaceholder":161},[65,1659,1660,1662,1664,1666,1668,1671,1674,1678,1680],{"class":67,"line":673},[65,1661,1465],{"class":90},[65,1663,1468],{"class":285},[65,1665,1126],{"class":82},[65,1667,97],{"class":86},[65,1669,1670],{"class":82},"length",[65,1672,1673],{"class":86}," ===",[65,1675,1677],{"class":1676},"sbssI"," 0",[65,1679,1473],{"class":285},[65,1681,1476],{"class":86},[65,1683,1684,1687,1689,1692,1694,1696,1699,1701,1703],{"class":67,"line":682},[65,1685,1686],{"class":90},"      throw",[65,1688,1338],{"class":86},[65,1690,1691],{"class":100}," Error",[65,1693,104],{"class":285},[65,1695,107],{"class":86},[65,1697,1698],{"class":110},"Tenant niet gevonden",[65,1700,107],{"class":86},[65,1702,116],{"class":285},[65,1704,119],{"class":86},[65,1706,1707],{"class":67,"line":694},[65,1708,1490],{"class":86},[65,1710,1711],{"class":67,"line":706},[65,1712,162],{"emptyLinePlaceholder":161},[65,1714,1715,1718,1720,1722,1725,1728,1731],{"class":67,"line":716},[65,1716,1717],{"class":82},"    tenant",[65,1719,870],{"class":86},[65,1721,1042],{"class":82},[65,1723,1724],{"class":285},"[",[65,1726,1727],{"class":1676},"0",[65,1729,1730],{"class":285},"]",[65,1732,119],{"class":86},[65,1734,1735],{"class":67,"line":723},[65,1736,1111],{"class":285},[65,1738,1739],{"class":67,"line":732},[65,1740,1741],{"class":71},"    \u002F\u002F Cache voor volgende keer\n",[65,1743,1744,1747,1749,1751,1753,1756,1758,1760,1762,1765,1767,1769,1771,1774,1776,1778,1781,1783],{"class":67,"line":744},[65,1745,1746],{"class":90},"    await",[65,1748,943],{"class":86},[65,1750,1515],{"class":82},[65,1752,97],{"class":86},[65,1754,1755],{"class":100},"setex",[65,1757,104],{"class":285},[65,1759,1456],{"class":82},[65,1761,198],{"class":86},[65,1763,1764],{"class":1676}," 3600",[65,1766,198],{"class":86},[65,1768,1550],{"class":82},[65,1770,97],{"class":86},[65,1772,1773],{"class":100},"stringify",[65,1775,104],{"class":285},[65,1777,1232],{"class":82},[65,1779,1780],{"class":285},"))",[65,1782,152],{"class":86},[65,1784,1785],{"class":71}," \u002F\u002F 1 uur TTL\n",[65,1787,1788,1790,1792,1794,1796,1798,1800,1802,1804,1806],{"class":67,"line":756},[65,1789,865],{"class":86},[65,1791,1446],{"class":82},[65,1793,97],{"class":86},[65,1795,1575],{"class":100},[65,1797,104],{"class":285},[65,1799,1456],{"class":82},[65,1801,198],{"class":86},[65,1803,1439],{"class":82},[65,1805,116],{"class":285},[65,1807,119],{"class":86},[65,1809,1810],{"class":67,"line":766},[65,1811,162],{"emptyLinePlaceholder":161},[65,1813,1814,1816,1818],{"class":67,"line":773},[65,1815,940],{"class":90},[65,1817,1439],{"class":82},[65,1819,119],{"class":86},[65,1821,1822],{"class":67,"line":778},[65,1823,894],{"class":86},[65,1825,1826],{"class":67,"line":783},[65,1827,162],{"emptyLinePlaceholder":161},[65,1829,1830,1832,1835,1837,1839,1841,1843,1845,1847],{"class":67,"line":789},[65,1831,803],{"class":78},[65,1833,1834],{"class":285}," extractSubdomain",[65,1836,104],{"class":86},[65,1838,1205],{"class":842},[65,1840,289],{"class":86},[65,1842,1210],{"class":276},[65,1844,1017],{"class":86},[65,1846,292],{"class":276},[65,1848,280],{"class":86},[65,1850,1851,1853,1856,1858,1861,1863,1866,1868,1871],{"class":67,"line":800},[65,1852,1039],{"class":78},[65,1854,1855],{"class":82}," host",[65,1857,870],{"class":86},[65,1859,1860],{"class":82}," request",[65,1862,97],{"class":86},[65,1864,1865],{"class":82},"headers",[65,1867,97],{"class":86},[65,1869,1870],{"class":82},"host",[65,1872,119],{"class":86},[65,1874,1875,1877,1880,1882,1884,1886,1889,1891,1893,1895,1897,1899],{"class":67,"line":815},[65,1876,1039],{"class":78},[65,1878,1879],{"class":82}," parts",[65,1881,870],{"class":86},[65,1883,1855],{"class":82},[65,1885,97],{"class":86},[65,1887,1888],{"class":100},"split",[65,1890,104],{"class":285},[65,1892,107],{"class":86},[65,1894,97],{"class":110},[65,1896,107],{"class":86},[65,1898,116],{"class":285},[65,1900,119],{"class":86},[65,1902,1903,1905,1907,1909,1911,1913,1915],{"class":67,"line":829},[65,1904,940],{"class":90},[65,1906,1879],{"class":82},[65,1908,1724],{"class":285},[65,1910,1727],{"class":1676},[65,1912,1730],{"class":285},[65,1914,152],{"class":86},[65,1916,1917],{"class":71}," \u002F\u002F eerste deel is subdomain\n",[65,1919,1920],{"class":67,"line":834},[65,1921,894],{"class":86},[65,1923,1924],{"class":67,"line":862},[65,1925,162],{"emptyLinePlaceholder":161},[65,1927,1928,1930,1933,1935,1937,1939,1941,1943,1945,1947,1950,1952],{"class":67,"line":877},[65,1929,905],{"class":78},[65,1931,1932],{"class":285}," invalidateTenant",[65,1934,104],{"class":86},[65,1936,882],{"class":842},[65,1938,289],{"class":86},[65,1940,292],{"class":276},[65,1942,1017],{"class":86},[65,1944,914],{"class":276},[65,1946,917],{"class":86},[65,1948,1949],{"class":276},"void",[65,1951,926],{"class":86},[65,1953,280],{"class":86},[65,1955,1956],{"class":67,"line":891},[65,1957,1958],{"class":71},"    \u002F\u002F Verwijder uit alle caches\n",[65,1960,1961,1963,1965,1967,1969,1971,1973,1975,1977],{"class":67,"line":897},[65,1962,1039],{"class":78},[65,1964,1439],{"class":82},[65,1966,870],{"class":86},[65,1968,91],{"class":90},[65,1970,943],{"class":86},[65,1972,843],{"class":82},[65,1974,97],{"class":86},[65,1976,101],{"class":100},[65,1978,952],{"class":285},[65,1980,1981,1983,1986,1988],{"class":67,"line":902},[65,1982,958],{"class":86},[65,1984,1985],{"class":110},"SELECT subdomain FROM tenants WHERE id = ?",[65,1987,107],{"class":86},[65,1989,496],{"class":86},[65,1991,1992,1994,1996],{"class":67,"line":931},[65,1993,970],{"class":285},[65,1995,882],{"class":82},[65,1997,978],{"class":285},[65,1999,2000,2002],{"class":67,"line":937},[65,2001,984],{"class":285},[65,2003,119],{"class":86},[65,2005,2006],{"class":67,"line":955},[65,2007,162],{"emptyLinePlaceholder":161},[65,2009,2010,2012,2014,2016,2018,2020,2023,2025,2027],{"class":67,"line":967},[65,2011,1465],{"class":90},[65,2013,1468],{"class":285},[65,2015,1232],{"class":82},[65,2017,97],{"class":86},[65,2019,1670],{"class":82},[65,2021,2022],{"class":86}," >",[65,2024,1677],{"class":1676},[65,2026,1473],{"class":285},[65,2028,1476],{"class":86},[65,2030,2031,2034,2036,2038,2040,2042,2044,2046,2048,2050],{"class":67,"line":981},[65,2032,2033],{"class":78},"      const",[65,2035,1383],{"class":82},[65,2037,870],{"class":86},[65,2039,1439],{"class":82},[65,2041,1724],{"class":285},[65,2043,1727],{"class":1676},[65,2045,1730],{"class":285},[65,2047,97],{"class":86},[65,2049,1418],{"class":82},[65,2051,119],{"class":86},[65,2053,2054,2056,2058,2060,2062,2064,2066,2068,2070],{"class":67,"line":989},[65,2055,2033],{"class":78},[65,2057,1405],{"class":82},[65,2059,870],{"class":86},[65,2061,1410],{"class":86},[65,2063,1413],{"class":110},[65,2065,141],{"class":86},[65,2067,1418],{"class":82},[65,2069,147],{"class":86},[65,2071,119],{"class":86},[65,2073,2074],{"class":67,"line":994},[65,2075,2076],{"class":285},"      \n",[65,2078,2079,2082,2084,2086,2088,2091,2093,2095,2097],{"class":67,"line":999},[65,2080,2081],{"class":90},"      await",[65,2083,943],{"class":86},[65,2085,1515],{"class":82},[65,2087,97],{"class":86},[65,2089,2090],{"class":100},"del",[65,2092,104],{"class":285},[65,2094,1456],{"class":82},[65,2096,116],{"class":285},[65,2098,119],{"class":86},[65,2100,2101,2103,2105,2107,2110,2112,2114,2116],{"class":67,"line":1030},[65,2102,1568],{"class":86},[65,2104,1446],{"class":82},[65,2106,97],{"class":86},[65,2108,2109],{"class":100},"delete",[65,2111,104],{"class":285},[65,2113,1456],{"class":82},[65,2115,116],{"class":285},[65,2117,119],{"class":86},[65,2119,2120],{"class":67,"line":1036},[65,2121,1490],{"class":86},[65,2123,2124],{"class":67,"line":1059},[65,2125,894],{"class":86},[65,2127,2128],{"class":67,"line":1071},[65,2129,383],{"class":86},[24,2131,2132],{},[30,2133,1150],{},[34,2135,2136,2139,2142,2145],{},[37,2137,2138],{},"Multi-layer caching (memory + Redis)",[37,2140,2141],{},"Snelle tenant resolution",[37,2143,2144],{},"Automatische cache invalidatie",[37,2146,2147],{},"Subdomain-based tenant identificatie",[24,2149,2150,2153],{},[30,2151,2152],{},"Resultaat:"," Tenant resolution verbeterde naar 5ms (200x verbetering)",[252,2155,2157],{"id":2156},"stap-3-schaalbare-api-architectuur","Stap 3: Schaalbare API Architectuur",[24,2159,2160],{},"Met betere tenant resolution werd API design de volgende focus:",[55,2162,2164],{"className":57,"code":2163,"language":59,"meta":60,"style":60},"\u002F\u002F Schaalbare API architectuur\ninterface APIDesign {\n  versioning: 'URL-based' | 'Header-based';\n  authentication: 'JWT' | 'OAuth2';\n  rateLimiting: 'Per-tenant' | 'Per-user';\n  caching: 'Redis' | 'CDN';\n  monitoring: 'Real-time' | 'Batch';\n}\n\nclass ScalableAPIService {\n  private tenantResolver: TenantResolver;\n  private rateLimiter: RateLimiter;\n  private cache: Cache;\n  private monitor: Monitor;\n\n  async handleRequest(request: Request): Promise\u003CResponse> {\n    \u002F\u002F 1. Resolve tenant\n    const tenant = await this.tenantResolver.resolveTenant(request);\n    \n    \u002F\u002F 2. Rate limiting per tenant\n    const rateLimit = await this.rateLimiter.checkLimit(tenant.id);\n    if (!rateLimit.allowed) {\n      return new Response('Rate limit exceeded', { status: 429 });\n    }\n\n    \u002F\u002F 3. Cache check\n    const cacheKey = this.generateCacheKey(request, tenant.id);\n    const cached = await this.cache.get(cacheKey);\n    if (cached) {\n      return new Response(cached, {\n        headers: { 'X-Cache': 'HIT' }\n      });\n    }\n\n    \u002F\u002F 4. Process request\n    const result = await this.processRequest(request, tenant);\n    \n    \u002F\u002F 5. Cache result\n    await this.cache.set(cacheKey, result, 300); \u002F\u002F 5 minuten TTL\n    \n    \u002F\u002F 6. Monitor performance\n    await this.monitor.trackRequest(request, tenant, result);\n\n    return new Response(result, {\n      headers: { 'X-Cache': 'MISS' }\n    });\n  }\n\n  private async processRequest(request: Request, tenant: Tenant): Promise\u003Cany> {\n    \u002F\u002F Tenant-aware request processing\n    const repository = new TenantAwareRepository(this.db, tenant.id);\n    \n    switch (request.method) {\n      case 'GET':\n        return await repository.findUsers();\n      case 'POST':\n        return await repository.createUser(await request.json());\n      default:\n        throw new Error('Method not supported');\n    }\n  }\n}\n",[62,2165,2166,2171,2180,2205,2230,2255,2280,2305,2309,2313,2322,2335,2349,2362,2376,2380,2408,2413,2441,2445,2450,2484,2505,2543,2547,2551,2556,2585,2611,2623,2639,2667,2676,2680,2684,2689,2716,2720,2725,2757,2761,2766,2796,2800,2816,2842,2851,2855,2859,2898,2903,2934,2938,2956,2971,2989,3002,3032,3039,3061,3065,3069],{"__ignoreMap":60},[65,2167,2168],{"class":67,"line":68},[65,2169,2170],{"class":71},"\u002F\u002F Schaalbare API architectuur\n",[65,2172,2173,2175,2178],{"class":67,"line":75},[65,2174,273],{"class":78},[65,2176,2177],{"class":276}," APIDesign",[65,2179,280],{"class":86},[65,2181,2182,2185,2187,2189,2192,2194,2196,2198,2201,2203],{"class":67,"line":122},[65,2183,2184],{"class":285},"  versioning",[65,2186,289],{"class":86},[65,2188,326],{"class":86},[65,2190,2191],{"class":110},"URL-based",[65,2193,107],{"class":86},[65,2195,334],{"class":86},[65,2197,326],{"class":86},[65,2199,2200],{"class":110},"Header-based",[65,2202,107],{"class":86},[65,2204,119],{"class":86},[65,2206,2207,2210,2212,2214,2217,2219,2221,2223,2226,2228],{"class":67,"line":158},[65,2208,2209],{"class":285},"  authentication",[65,2211,289],{"class":86},[65,2213,326],{"class":86},[65,2215,2216],{"class":110},"JWT",[65,2218,107],{"class":86},[65,2220,334],{"class":86},[65,2222,326],{"class":86},[65,2224,2225],{"class":110},"OAuth2",[65,2227,107],{"class":86},[65,2229,119],{"class":86},[65,2231,2232,2235,2237,2239,2242,2244,2246,2248,2251,2253],{"class":67,"line":165},[65,2233,2234],{"class":285},"  rateLimiting",[65,2236,289],{"class":86},[65,2238,326],{"class":86},[65,2240,2241],{"class":110},"Per-tenant",[65,2243,107],{"class":86},[65,2245,334],{"class":86},[65,2247,326],{"class":86},[65,2249,2250],{"class":110},"Per-user",[65,2252,107],{"class":86},[65,2254,119],{"class":86},[65,2256,2257,2260,2262,2264,2267,2269,2271,2273,2276,2278],{"class":67,"line":171},[65,2258,2259],{"class":285},"  caching",[65,2261,289],{"class":86},[65,2263,326],{"class":86},[65,2265,2266],{"class":110},"Redis",[65,2268,107],{"class":86},[65,2270,334],{"class":86},[65,2272,326],{"class":86},[65,2274,2275],{"class":110},"CDN",[65,2277,107],{"class":86},[65,2279,119],{"class":86},[65,2281,2282,2285,2287,2289,2292,2294,2296,2298,2301,2303],{"class":67,"line":206},[65,2283,2284],{"class":285},"  monitoring",[65,2286,289],{"class":86},[65,2288,326],{"class":86},[65,2290,2291],{"class":110},"Real-time",[65,2293,107],{"class":86},[65,2295,334],{"class":86},[65,2297,326],{"class":86},[65,2299,2300],{"class":110},"Batch",[65,2302,107],{"class":86},[65,2304,119],{"class":86},[65,2306,2307],{"class":67,"line":367},[65,2308,383],{"class":86},[65,2310,2311],{"class":67,"line":380},[65,2312,162],{"emptyLinePlaceholder":161},[65,2314,2315,2317,2320],{"class":67,"line":386},[65,2316,792],{"class":78},[65,2318,2319],{"class":276}," ScalableAPIService",[65,2321,280],{"class":86},[65,2323,2324,2326,2329,2331,2333],{"class":67,"line":391},[65,2325,803],{"class":78},[65,2327,2328],{"class":285}," tenantResolver",[65,2330,289],{"class":86},[65,2332,1193],{"class":276},[65,2334,119],{"class":86},[65,2336,2337,2339,2342,2344,2347],{"class":67,"line":397},[65,2338,803],{"class":78},[65,2340,2341],{"class":285}," rateLimiter",[65,2343,289],{"class":86},[65,2345,2346],{"class":276}," RateLimiter",[65,2348,119],{"class":86},[65,2350,2351,2353,2355,2357,2360],{"class":67,"line":407},[65,2352,803],{"class":78},[65,2354,1317],{"class":285},[65,2356,289],{"class":86},[65,2358,2359],{"class":276}," Cache",[65,2361,119],{"class":86},[65,2363,2364,2366,2369,2371,2374],{"class":67,"line":417},[65,2365,803],{"class":78},[65,2367,2368],{"class":285}," monitor",[65,2370,289],{"class":86},[65,2372,2373],{"class":276}," Monitor",[65,2375,119],{"class":86},[65,2377,2378],{"class":67,"line":434},[65,2379,162],{"emptyLinePlaceholder":161},[65,2381,2382,2384,2387,2389,2391,2393,2395,2397,2399,2401,2404,2406],{"class":67,"line":451},[65,2383,905],{"class":78},[65,2385,2386],{"class":285}," handleRequest",[65,2388,104],{"class":86},[65,2390,1205],{"class":842},[65,2392,289],{"class":86},[65,2394,1210],{"class":276},[65,2396,1017],{"class":86},[65,2398,914],{"class":276},[65,2400,917],{"class":86},[65,2402,2403],{"class":276},"Response",[65,2405,926],{"class":86},[65,2407,280],{"class":86},[65,2409,2410],{"class":67,"line":468},[65,2411,2412],{"class":71},"    \u002F\u002F 1. Resolve tenant\n",[65,2414,2415,2417,2419,2421,2423,2425,2428,2430,2433,2435,2437,2439],{"class":67,"line":474},[65,2416,1039],{"class":78},[65,2418,1439],{"class":82},[65,2420,870],{"class":86},[65,2422,91],{"class":90},[65,2424,943],{"class":86},[65,2426,2427],{"class":82},"tenantResolver",[65,2429,97],{"class":86},[65,2431,2432],{"class":100},"resolveTenant",[65,2434,104],{"class":285},[65,2436,1205],{"class":82},[65,2438,116],{"class":285},[65,2440,119],{"class":86},[65,2442,2443],{"class":67,"line":485},[65,2444,1111],{"class":285},[65,2446,2447],{"class":67,"line":499},[65,2448,2449],{"class":71},"    \u002F\u002F 2. Rate limiting per tenant\n",[65,2451,2452,2454,2457,2459,2461,2463,2466,2468,2471,2473,2475,2477,2480,2482],{"class":67,"line":511},[65,2453,1039],{"class":78},[65,2455,2456],{"class":82}," rateLimit",[65,2458,870],{"class":86},[65,2460,91],{"class":90},[65,2462,943],{"class":86},[65,2464,2465],{"class":82},"rateLimiter",[65,2467,97],{"class":86},[65,2469,2470],{"class":100},"checkLimit",[65,2472,104],{"class":285},[65,2474,1232],{"class":82},[65,2476,97],{"class":86},[65,2478,2479],{"class":82},"id",[65,2481,116],{"class":285},[65,2483,119],{"class":86},[65,2485,2486,2488,2490,2493,2496,2498,2501,2503],{"class":67,"line":522},[65,2487,1465],{"class":90},[65,2489,1468],{"class":285},[65,2491,2492],{"class":86},"!",[65,2494,2495],{"class":82},"rateLimit",[65,2497,97],{"class":86},[65,2499,2500],{"class":82},"allowed",[65,2502,1473],{"class":285},[65,2504,1476],{"class":86},[65,2506,2507,2509,2511,2514,2516,2518,2521,2523,2525,2528,2531,2533,2536,2539,2541],{"class":67,"line":530},[65,2508,1481],{"class":90},[65,2510,1338],{"class":86},[65,2512,2513],{"class":100}," Response",[65,2515,104],{"class":285},[65,2517,107],{"class":86},[65,2519,2520],{"class":110},"Rate limit exceeded",[65,2522,107],{"class":86},[65,2524,198],{"class":86},[65,2526,2527],{"class":86}," {",[65,2529,2530],{"class":285}," status",[65,2532,289],{"class":86},[65,2534,2535],{"class":1676}," 429",[65,2537,2538],{"class":86}," }",[65,2540,116],{"class":285},[65,2542,119],{"class":86},[65,2544,2545],{"class":67,"line":540},[65,2546,1490],{"class":86},[65,2548,2549],{"class":67,"line":552},[65,2550,162],{"emptyLinePlaceholder":161},[65,2552,2553],{"class":67,"line":564},[65,2554,2555],{"class":71},"    \u002F\u002F 3. Cache check\n",[65,2557,2558,2560,2562,2564,2566,2569,2571,2573,2575,2577,2579,2581,2583],{"class":67,"line":574},[65,2559,1039],{"class":78},[65,2561,1405],{"class":82},[65,2563,870],{"class":86},[65,2565,943],{"class":86},[65,2567,2568],{"class":100},"generateCacheKey",[65,2570,104],{"class":285},[65,2572,1205],{"class":82},[65,2574,198],{"class":86},[65,2576,1439],{"class":82},[65,2578,97],{"class":86},[65,2580,2479],{"class":82},[65,2582,116],{"class":285},[65,2584,119],{"class":86},[65,2586,2587,2589,2591,2593,2595,2597,2599,2601,2603,2605,2607,2609],{"class":67,"line":581},[65,2588,1039],{"class":78},[65,2590,1506],{"class":82},[65,2592,870],{"class":86},[65,2594,91],{"class":90},[65,2596,943],{"class":86},[65,2598,1446],{"class":82},[65,2600,97],{"class":86},[65,2602,1451],{"class":100},[65,2604,104],{"class":285},[65,2606,1456],{"class":82},[65,2608,116],{"class":285},[65,2610,119],{"class":86},[65,2612,2613,2615,2617,2619,2621],{"class":67,"line":586},[65,2614,1465],{"class":90},[65,2616,1468],{"class":285},[65,2618,1536],{"class":82},[65,2620,1473],{"class":285},[65,2622,1476],{"class":86},[65,2624,2625,2627,2629,2631,2633,2635,2637],{"class":67,"line":591},[65,2626,1481],{"class":90},[65,2628,1338],{"class":86},[65,2630,2513],{"class":100},[65,2632,104],{"class":285},[65,2634,1536],{"class":82},[65,2636,198],{"class":86},[65,2638,280],{"class":86},[65,2640,2641,2644,2646,2648,2650,2653,2655,2657,2659,2662,2664],{"class":67,"line":597},[65,2642,2643],{"class":285},"        headers",[65,2645,289],{"class":86},[65,2647,2527],{"class":86},[65,2649,326],{"class":86},[65,2651,2652],{"class":285},"X-Cache",[65,2654,107],{"class":86},[65,2656,289],{"class":86},[65,2658,326],{"class":86},[65,2660,2661],{"class":110},"HIT",[65,2663,107],{"class":86},[65,2665,2666],{"class":86}," }\n",[65,2668,2669,2672,2674],{"class":67,"line":607},[65,2670,2671],{"class":86},"      }",[65,2673,116],{"class":285},[65,2675,119],{"class":86},[65,2677,2678],{"class":67,"line":617},[65,2679,1490],{"class":86},[65,2681,2682],{"class":67,"line":634},[65,2683,162],{"emptyLinePlaceholder":161},[65,2685,2686],{"class":67,"line":651},[65,2687,2688],{"class":71},"    \u002F\u002F 4. Process request\n",[65,2690,2691,2693,2695,2697,2699,2701,2704,2706,2708,2710,2712,2714],{"class":67,"line":668},[65,2692,1039],{"class":78},[65,2694,1042],{"class":82},[65,2696,870],{"class":86},[65,2698,91],{"class":90},[65,2700,943],{"class":86},[65,2702,2703],{"class":100},"processRequest",[65,2705,104],{"class":285},[65,2707,1205],{"class":82},[65,2709,198],{"class":86},[65,2711,1439],{"class":82},[65,2713,116],{"class":285},[65,2715,119],{"class":86},[65,2717,2718],{"class":67,"line":673},[65,2719,1111],{"class":285},[65,2721,2722],{"class":67,"line":682},[65,2723,2724],{"class":71},"    \u002F\u002F 5. Cache result\n",[65,2726,2727,2729,2731,2733,2735,2737,2739,2741,2743,2745,2747,2750,2752,2754],{"class":67,"line":694},[65,2728,1746],{"class":90},[65,2730,943],{"class":86},[65,2732,1446],{"class":82},[65,2734,97],{"class":86},[65,2736,1575],{"class":100},[65,2738,104],{"class":285},[65,2740,1456],{"class":82},[65,2742,198],{"class":86},[65,2744,1042],{"class":82},[65,2746,198],{"class":86},[65,2748,2749],{"class":1676}," 300",[65,2751,116],{"class":285},[65,2753,152],{"class":86},[65,2755,2756],{"class":71}," \u002F\u002F 5 minuten TTL\n",[65,2758,2759],{"class":67,"line":706},[65,2760,1111],{"class":285},[65,2762,2763],{"class":67,"line":716},[65,2764,2765],{"class":71},"    \u002F\u002F 6. Monitor performance\n",[65,2767,2768,2770,2772,2775,2777,2780,2782,2784,2786,2788,2790,2792,2794],{"class":67,"line":723},[65,2769,1746],{"class":90},[65,2771,943],{"class":86},[65,2773,2774],{"class":82},"monitor",[65,2776,97],{"class":86},[65,2778,2779],{"class":100},"trackRequest",[65,2781,104],{"class":285},[65,2783,1205],{"class":82},[65,2785,198],{"class":86},[65,2787,1439],{"class":82},[65,2789,198],{"class":86},[65,2791,1042],{"class":82},[65,2793,116],{"class":285},[65,2795,119],{"class":86},[65,2797,2798],{"class":67,"line":732},[65,2799,162],{"emptyLinePlaceholder":161},[65,2801,2802,2804,2806,2808,2810,2812,2814],{"class":67,"line":744},[65,2803,940],{"class":90},[65,2805,1338],{"class":86},[65,2807,2513],{"class":100},[65,2809,104],{"class":285},[65,2811,1126],{"class":82},[65,2813,198],{"class":86},[65,2815,280],{"class":86},[65,2817,2818,2821,2823,2825,2827,2829,2831,2833,2835,2838,2840],{"class":67,"line":756},[65,2819,2820],{"class":285},"      headers",[65,2822,289],{"class":86},[65,2824,2527],{"class":86},[65,2826,326],{"class":86},[65,2828,2652],{"class":285},[65,2830,107],{"class":86},[65,2832,289],{"class":86},[65,2834,326],{"class":86},[65,2836,2837],{"class":110},"MISS",[65,2839,107],{"class":86},[65,2841,2666],{"class":86},[65,2843,2844,2847,2849],{"class":67,"line":766},[65,2845,2846],{"class":86},"    }",[65,2848,116],{"class":285},[65,2850,119],{"class":86},[65,2852,2853],{"class":67,"line":773},[65,2854,894],{"class":86},[65,2856,2857],{"class":67,"line":778},[65,2858,162],{"emptyLinePlaceholder":161},[65,2860,2861,2863,2866,2869,2871,2873,2875,2877,2879,2881,2883,2885,2887,2889,2891,2894,2896],{"class":67,"line":783},[65,2862,803],{"class":78},[65,2864,2865],{"class":78}," async",[65,2867,2868],{"class":285}," processRequest",[65,2870,104],{"class":86},[65,2872,1205],{"class":842},[65,2874,289],{"class":86},[65,2876,1210],{"class":276},[65,2878,198],{"class":86},[65,2880,1439],{"class":842},[65,2882,289],{"class":86},[65,2884,277],{"class":276},[65,2886,1017],{"class":86},[65,2888,914],{"class":276},[65,2890,917],{"class":86},[65,2892,2893],{"class":276},"any",[65,2895,926],{"class":86},[65,2897,280],{"class":86},[65,2899,2900],{"class":67,"line":789},[65,2901,2902],{"class":71},"    \u002F\u002F Tenant-aware request processing\n",[65,2904,2905,2907,2910,2912,2914,2916,2918,2920,2922,2924,2926,2928,2930,2932],{"class":67,"line":800},[65,2906,1039],{"class":78},[65,2908,2909],{"class":82}," repository",[65,2911,870],{"class":86},[65,2913,1338],{"class":86},[65,2915,795],{"class":100},[65,2917,104],{"class":285},[65,2919,973],{"class":86},[65,2921,843],{"class":82},[65,2923,198],{"class":86},[65,2925,1439],{"class":82},[65,2927,97],{"class":86},[65,2929,2479],{"class":82},[65,2931,116],{"class":285},[65,2933,119],{"class":86},[65,2935,2936],{"class":67,"line":815},[65,2937,1111],{"class":285},[65,2939,2940,2943,2945,2947,2949,2952,2954],{"class":67,"line":829},[65,2941,2942],{"class":90},"    switch",[65,2944,1468],{"class":285},[65,2946,1205],{"class":82},[65,2948,97],{"class":86},[65,2950,2951],{"class":82},"method",[65,2953,1473],{"class":285},[65,2955,1476],{"class":86},[65,2957,2958,2961,2963,2966,2968],{"class":67,"line":834},[65,2959,2960],{"class":90},"      case",[65,2962,326],{"class":86},[65,2964,2965],{"class":110},"GET",[65,2967,107],{"class":86},[65,2969,2970],{"class":86},":\n",[65,2972,2973,2976,2978,2980,2982,2985,2987],{"class":67,"line":862},[65,2974,2975],{"class":90},"        return",[65,2977,91],{"class":90},[65,2979,2909],{"class":82},[65,2981,97],{"class":86},[65,2983,2984],{"class":100},"findUsers",[65,2986,1343],{"class":285},[65,2988,119],{"class":86},[65,2990,2991,2993,2995,2998,3000],{"class":67,"line":877},[65,2992,2960],{"class":90},[65,2994,326],{"class":86},[65,2996,2997],{"class":110},"POST",[65,2999,107],{"class":86},[65,3001,2970],{"class":86},[65,3003,3004,3006,3008,3010,3012,3015,3017,3020,3022,3024,3027,3030],{"class":67,"line":891},[65,3005,2975],{"class":90},[65,3007,91],{"class":90},[65,3009,2909],{"class":82},[65,3011,97],{"class":86},[65,3013,3014],{"class":100},"createUser",[65,3016,104],{"class":285},[65,3018,3019],{"class":90},"await",[65,3021,1860],{"class":82},[65,3023,97],{"class":86},[65,3025,3026],{"class":100},"json",[65,3028,3029],{"class":285},"())",[65,3031,119],{"class":86},[65,3033,3034,3037],{"class":67,"line":897},[65,3035,3036],{"class":90},"      default",[65,3038,2970],{"class":86},[65,3040,3041,3044,3046,3048,3050,3052,3055,3057,3059],{"class":67,"line":902},[65,3042,3043],{"class":90},"        throw",[65,3045,1338],{"class":86},[65,3047,1691],{"class":100},[65,3049,104],{"class":285},[65,3051,107],{"class":86},[65,3053,3054],{"class":110},"Method not supported",[65,3056,107],{"class":86},[65,3058,116],{"class":285},[65,3060,119],{"class":86},[65,3062,3063],{"class":67,"line":931},[65,3064,1490],{"class":86},[65,3066,3067],{"class":67,"line":937},[65,3068,894],{"class":86},[65,3070,3071],{"class":67,"line":955},[65,3072,383],{"class":86},[24,3074,3075],{},[30,3076,1150],{},[34,3078,3079,3082,3085,3088],{},[37,3080,3081],{},"Tenant-aware request processing",[37,3083,3084],{},"Rate limiting per tenant",[37,3086,3087],{},"Multi-layer caching",[37,3089,3090],{},"Real-time monitoring",[24,3092,3093,3095],{},[30,3094,2152],{}," API response tijd verbeterde naar 100ms (10x verbetering)",[19,3097,3099],{"id":3098},"de-game-changer-microservices-architectuur","De Game Changer: Microservices Architectuur",[252,3101,3103],{"id":3102},"het-probleem-monolithische-saas-limitaties","Het Probleem: Monolithische SaaS Limitaties",[24,3105,3106],{},"Zelfs met betere API design had de monolithische architectuur limieten:",[55,3108,3110],{"className":57,"code":3109,"language":59,"meta":60,"style":60},"\u002F\u002F Probleem: Monolithische SaaS\ninterface MonolithicSaaS {\n  components: [\n    'User Management',\n    'Order Processing',\n    'Payment Processing',\n    'Notification Service',\n    'Analytics Service'\n  ];\n  issues: [\n    'Moeilijke schaalbaarheid',\n    'Single point of failure',\n    'Complexe deployment',\n    'Technologie lock-in'\n  ];\n}\n",[62,3111,3112,3117,3126,3135,3146,3157,3168,3179,3188,3194,3203,3214,3225,3236,3245,3251],{"__ignoreMap":60},[65,3113,3114],{"class":67,"line":68},[65,3115,3116],{"class":71},"\u002F\u002F Probleem: Monolithische SaaS\n",[65,3118,3119,3121,3124],{"class":67,"line":75},[65,3120,273],{"class":78},[65,3122,3123],{"class":276}," MonolithicSaaS",[65,3125,280],{"class":86},[65,3127,3128,3131,3133],{"class":67,"line":122},[65,3129,3130],{"class":285},"  components",[65,3132,289],{"class":86},[65,3134,482],{"class":82},[65,3136,3137,3139,3142,3144],{"class":67,"line":158},[65,3138,488],{"class":86},[65,3140,3141],{"class":110},"User Management",[65,3143,107],{"class":86},[65,3145,496],{"class":86},[65,3147,3148,3150,3153,3155],{"class":67,"line":165},[65,3149,488],{"class":86},[65,3151,3152],{"class":110},"Order Processing",[65,3154,107],{"class":86},[65,3156,496],{"class":86},[65,3158,3159,3161,3164,3166],{"class":67,"line":171},[65,3160,488],{"class":86},[65,3162,3163],{"class":110},"Payment Processing",[65,3165,107],{"class":86},[65,3167,496],{"class":86},[65,3169,3170,3172,3175,3177],{"class":67,"line":206},[65,3171,488],{"class":86},[65,3173,3174],{"class":110},"Notification Service",[65,3176,107],{"class":86},[65,3178,496],{"class":86},[65,3180,3181,3183,3186],{"class":67,"line":367},[65,3182,488],{"class":86},[65,3184,3185],{"class":110},"Analytics Service",[65,3187,519],{"class":86},[65,3189,3190,3192],{"class":67,"line":380},[65,3191,525],{"class":82},[65,3193,119],{"class":86},[65,3195,3196,3199,3201],{"class":67,"line":386},[65,3197,3198],{"class":285},"  issues",[65,3200,289],{"class":86},[65,3202,482],{"class":82},[65,3204,3205,3207,3210,3212],{"class":67,"line":391},[65,3206,488],{"class":86},[65,3208,3209],{"class":110},"Moeilijke schaalbaarheid",[65,3211,107],{"class":86},[65,3213,496],{"class":86},[65,3215,3216,3218,3221,3223],{"class":67,"line":397},[65,3217,488],{"class":86},[65,3219,3220],{"class":110},"Single point of failure",[65,3222,107],{"class":86},[65,3224,496],{"class":86},[65,3226,3227,3229,3232,3234],{"class":67,"line":407},[65,3228,488],{"class":86},[65,3230,3231],{"class":110},"Complexe deployment",[65,3233,107],{"class":86},[65,3235,496],{"class":86},[65,3237,3238,3240,3243],{"class":67,"line":417},[65,3239,488],{"class":86},[65,3241,3242],{"class":110},"Technologie lock-in",[65,3244,519],{"class":86},[65,3246,3247,3249],{"class":67,"line":434},[65,3248,525],{"class":82},[65,3250,119],{"class":86},[65,3252,3253],{"class":67,"line":451},[65,3254,383],{"class":86},[252,3256,3258],{"id":3257},"de-oplossing-microservices-architectuur","De Oplossing: Microservices Architectuur",[24,3260,3261],{},"We implementeerden microservices architectuur:",[55,3263,3265],{"className":57,"code":3264,"language":59,"meta":60,"style":60},"\u002F\u002F Microservices architectuur\ninterface MicroservicesArchitecture {\n  services: {\n    userService: 'User management en authenticatie';\n    orderService: 'Order processing en workflow';\n    paymentService: 'Payment processing en billing';\n    notificationService: 'Email, SMS, push notifications';\n    analyticsService: 'Data analytics en reporting';\n  };\n  benefits: [\n    'Individuele schaalbaarheid',\n    'Technologie diversiteit',\n    'Fault isolation',\n    'Team autonomy'\n  ];\n}\n\n\u002F\u002F Service discovery en communicatie\nclass ServiceRegistry {\n  private services: Map\u003Cstring, ServiceEndpoint> = new Map();\n\n  registerService(name: string, endpoint: ServiceEndpoint): void {\n    this.services.set(name, endpoint);\n  }\n\n  getService(name: string): ServiceEndpoint {\n    const service = this.services.get(name);\n    if (!service) {\n      throw new Error(`Service ${name} not found`);\n    }\n    return service;\n  }\n\n  async callService(serviceName: string, method: string, data: any): Promise\u003Cany> {\n    const service = this.getService(serviceName);\n    const response = await fetch(`${service.url}\u002F${method}`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application\u002Fjson' },\n      body: JSON.stringify(data)\n    });\n    \n    if (!response.ok) {\n      throw new Error(`Service call failed: ${response.statusText}`);\n    }\n    \n    return response.json();\n  }\n}\n\n\u002F\u002F Tenant-aware service communicatie\nclass TenantAwareServiceClient {\n  private serviceRegistry: ServiceRegistry;\n  private tenantId: string;\n\n  constructor(serviceRegistry: ServiceRegistry, tenantId: string) {\n    this.serviceRegistry = serviceRegistry;\n    this.tenantId = tenantId;\n  }\n\n  async callUserService(method: string, data: any): Promise\u003Cany> {\n    return this.serviceRegistry.callService('userService', method, {\n      ...data,\n      tenantId: this.tenantId\n    });\n  }\n\n  async callOrderService(method: string, data: any): Promise\u003Cany> {\n    return this.serviceRegistry.callService('orderService', method, {\n      ...data,\n      tenantId: this.tenantId\n    });\n  }\n}\n",[62,3266,3267,3272,3281,3290,3306,3322,3338,3354,3370,3374,3382,3393,3404,3415,3424,3430,3434,3438,3443,3452,3484,3488,3516,3539,3543,3547,3566,3591,3606,3637,3641,3649,3653,3657,3704,3725,3766,3781,3808,3829,3837,3841,3861,3891,3895,3899,3913,3917,3921,3925,3930,3939,3952,3964,3968,3993,4005,4017,4021,4025,4060,4090,4099,4111,4119,4123,4127,4162,4191,4199,4209,4217,4221],{"__ignoreMap":60},[65,3268,3269],{"class":67,"line":68},[65,3270,3271],{"class":71},"\u002F\u002F Microservices architectuur\n",[65,3273,3274,3276,3279],{"class":67,"line":75},[65,3275,273],{"class":78},[65,3277,3278],{"class":276}," MicroservicesArchitecture",[65,3280,280],{"class":86},[65,3282,3283,3286,3288],{"class":67,"line":122},[65,3284,3285],{"class":285},"  services",[65,3287,289],{"class":86},[65,3289,280],{"class":86},[65,3291,3292,3295,3297,3299,3302,3304],{"class":67,"line":158},[65,3293,3294],{"class":285},"    userService",[65,3296,289],{"class":86},[65,3298,326],{"class":86},[65,3300,3301],{"class":110},"User management en authenticatie",[65,3303,107],{"class":86},[65,3305,119],{"class":86},[65,3307,3308,3311,3313,3315,3318,3320],{"class":67,"line":165},[65,3309,3310],{"class":285},"    orderService",[65,3312,289],{"class":86},[65,3314,326],{"class":86},[65,3316,3317],{"class":110},"Order processing en workflow",[65,3319,107],{"class":86},[65,3321,119],{"class":86},[65,3323,3324,3327,3329,3331,3334,3336],{"class":67,"line":171},[65,3325,3326],{"class":285},"    paymentService",[65,3328,289],{"class":86},[65,3330,326],{"class":86},[65,3332,3333],{"class":110},"Payment processing en billing",[65,3335,107],{"class":86},[65,3337,119],{"class":86},[65,3339,3340,3343,3345,3347,3350,3352],{"class":67,"line":206},[65,3341,3342],{"class":285},"    notificationService",[65,3344,289],{"class":86},[65,3346,326],{"class":86},[65,3348,3349],{"class":110},"Email, SMS, push notifications",[65,3351,107],{"class":86},[65,3353,119],{"class":86},[65,3355,3356,3359,3361,3363,3366,3368],{"class":67,"line":367},[65,3357,3358],{"class":285},"    analyticsService",[65,3360,289],{"class":86},[65,3362,326],{"class":86},[65,3364,3365],{"class":110},"Data analytics en reporting",[65,3367,107],{"class":86},[65,3369,119],{"class":86},[65,3371,3372],{"class":67,"line":380},[65,3373,471],{"class":86},[65,3375,3376,3378,3380],{"class":67,"line":386},[65,3377,477],{"class":285},[65,3379,289],{"class":86},[65,3381,482],{"class":82},[65,3383,3384,3386,3389,3391],{"class":67,"line":391},[65,3385,488],{"class":86},[65,3387,3388],{"class":110},"Individuele schaalbaarheid",[65,3390,107],{"class":86},[65,3392,496],{"class":86},[65,3394,3395,3397,3400,3402],{"class":67,"line":397},[65,3396,488],{"class":86},[65,3398,3399],{"class":110},"Technologie diversiteit",[65,3401,107],{"class":86},[65,3403,496],{"class":86},[65,3405,3406,3408,3411,3413],{"class":67,"line":407},[65,3407,488],{"class":86},[65,3409,3410],{"class":110},"Fault isolation",[65,3412,107],{"class":86},[65,3414,496],{"class":86},[65,3416,3417,3419,3422],{"class":67,"line":417},[65,3418,488],{"class":86},[65,3420,3421],{"class":110},"Team autonomy",[65,3423,519],{"class":86},[65,3425,3426,3428],{"class":67,"line":434},[65,3427,525],{"class":82},[65,3429,119],{"class":86},[65,3431,3432],{"class":67,"line":451},[65,3433,383],{"class":86},[65,3435,3436],{"class":67,"line":468},[65,3437,162],{"emptyLinePlaceholder":161},[65,3439,3440],{"class":67,"line":474},[65,3441,3442],{"class":71},"\u002F\u002F Service discovery en communicatie\n",[65,3444,3445,3447,3450],{"class":67,"line":485},[65,3446,792],{"class":78},[65,3448,3449],{"class":276}," ServiceRegistry",[65,3451,280],{"class":86},[65,3453,3454,3456,3459,3461,3463,3465,3467,3469,3472,3474,3476,3478,3480,3482],{"class":67,"line":499},[65,3455,803],{"class":78},[65,3457,3458],{"class":285}," services",[65,3460,289],{"class":86},[65,3462,1322],{"class":276},[65,3464,917],{"class":86},[65,3466,1327],{"class":276},[65,3468,198],{"class":86},[65,3470,3471],{"class":276}," ServiceEndpoint",[65,3473,926],{"class":86},[65,3475,870],{"class":86},[65,3477,1338],{"class":86},[65,3479,1322],{"class":285},[65,3481,1343],{"class":82},[65,3483,119],{"class":86},[65,3485,3486],{"class":67,"line":511},[65,3487,162],{"emptyLinePlaceholder":161},[65,3489,3490,3493,3495,3497,3499,3501,3503,3506,3508,3510,3512,3514],{"class":67,"line":522},[65,3491,3492],{"class":285},"  registerService",[65,3494,104],{"class":86},[65,3496,1087],{"class":842},[65,3498,289],{"class":86},[65,3500,292],{"class":276},[65,3502,198],{"class":86},[65,3504,3505],{"class":842}," endpoint",[65,3507,289],{"class":86},[65,3509,3471],{"class":276},[65,3511,1017],{"class":86},[65,3513,1241],{"class":276},[65,3515,280],{"class":86},[65,3517,3518,3520,3523,3525,3527,3529,3531,3533,3535,3537],{"class":67,"line":530},[65,3519,865],{"class":86},[65,3521,3522],{"class":82},"services",[65,3524,97],{"class":86},[65,3526,1575],{"class":100},[65,3528,104],{"class":285},[65,3530,1087],{"class":82},[65,3532,198],{"class":86},[65,3534,3505],{"class":82},[65,3536,116],{"class":285},[65,3538,119],{"class":86},[65,3540,3541],{"class":67,"line":540},[65,3542,894],{"class":86},[65,3544,3545],{"class":67,"line":552},[65,3546,162],{"emptyLinePlaceholder":161},[65,3548,3549,3552,3554,3556,3558,3560,3562,3564],{"class":67,"line":564},[65,3550,3551],{"class":285},"  getService",[65,3553,104],{"class":86},[65,3555,1087],{"class":842},[65,3557,289],{"class":86},[65,3559,292],{"class":276},[65,3561,1017],{"class":86},[65,3563,3471],{"class":276},[65,3565,280],{"class":86},[65,3567,3568,3570,3573,3575,3577,3579,3581,3583,3585,3587,3589],{"class":67,"line":574},[65,3569,1039],{"class":78},[65,3571,3572],{"class":82}," service",[65,3574,870],{"class":86},[65,3576,943],{"class":86},[65,3578,3522],{"class":82},[65,3580,97],{"class":86},[65,3582,1451],{"class":100},[65,3584,104],{"class":285},[65,3586,1087],{"class":82},[65,3588,116],{"class":285},[65,3590,119],{"class":86},[65,3592,3593,3595,3597,3599,3602,3604],{"class":67,"line":581},[65,3594,1465],{"class":90},[65,3596,1468],{"class":285},[65,3598,2492],{"class":86},[65,3600,3601],{"class":82},"service",[65,3603,1473],{"class":285},[65,3605,1476],{"class":86},[65,3607,3608,3610,3612,3614,3616,3618,3621,3623,3625,3628,3631,3633,3635],{"class":67,"line":586},[65,3609,1686],{"class":90},[65,3611,1338],{"class":86},[65,3613,1691],{"class":100},[65,3615,104],{"class":285},[65,3617,135],{"class":86},[65,3619,3620],{"class":110},"Service ",[65,3622,141],{"class":86},[65,3624,1087],{"class":82},[65,3626,3627],{"class":86},"}",[65,3629,3630],{"class":110}," not found",[65,3632,135],{"class":86},[65,3634,116],{"class":285},[65,3636,119],{"class":86},[65,3638,3639],{"class":67,"line":591},[65,3640,1490],{"class":86},[65,3642,3643,3645,3647],{"class":67,"line":597},[65,3644,940],{"class":90},[65,3646,3572],{"class":82},[65,3648,119],{"class":86},[65,3650,3651],{"class":67,"line":607},[65,3652,894],{"class":86},[65,3654,3655],{"class":67,"line":617},[65,3656,162],{"emptyLinePlaceholder":161},[65,3658,3659,3661,3664,3666,3669,3671,3673,3675,3678,3680,3682,3684,3687,3689,3692,3694,3696,3698,3700,3702],{"class":67,"line":634},[65,3660,905],{"class":78},[65,3662,3663],{"class":285}," callService",[65,3665,104],{"class":86},[65,3667,3668],{"class":842},"serviceName",[65,3670,289],{"class":86},[65,3672,292],{"class":276},[65,3674,198],{"class":86},[65,3676,3677],{"class":842}," method",[65,3679,289],{"class":86},[65,3681,292],{"class":276},[65,3683,198],{"class":86},[65,3685,3686],{"class":842}," data",[65,3688,289],{"class":86},[65,3690,3691],{"class":276}," any",[65,3693,1017],{"class":86},[65,3695,914],{"class":276},[65,3697,917],{"class":86},[65,3699,2893],{"class":276},[65,3701,926],{"class":86},[65,3703,280],{"class":86},[65,3705,3706,3708,3710,3712,3714,3717,3719,3721,3723],{"class":67,"line":651},[65,3707,1039],{"class":78},[65,3709,3572],{"class":82},[65,3711,870],{"class":86},[65,3713,943],{"class":86},[65,3715,3716],{"class":100},"getService",[65,3718,104],{"class":285},[65,3720,3668],{"class":82},[65,3722,116],{"class":285},[65,3724,119],{"class":86},[65,3726,3727,3729,3732,3734,3736,3739,3741,3744,3746,3748,3751,3753,3756,3758,3760,3762,3764],{"class":67,"line":668},[65,3728,1039],{"class":78},[65,3730,3731],{"class":82}," response",[65,3733,870],{"class":86},[65,3735,91],{"class":90},[65,3737,3738],{"class":100}," fetch",[65,3740,104],{"class":285},[65,3742,3743],{"class":86},"`${",[65,3745,3601],{"class":82},[65,3747,97],{"class":86},[65,3749,3750],{"class":82},"url",[65,3752,3627],{"class":86},[65,3754,3755],{"class":110},"\u002F",[65,3757,141],{"class":86},[65,3759,2951],{"class":82},[65,3761,147],{"class":86},[65,3763,198],{"class":86},[65,3765,280],{"class":86},[65,3767,3768,3771,3773,3775,3777,3779],{"class":67,"line":673},[65,3769,3770],{"class":285},"      method",[65,3772,289],{"class":86},[65,3774,326],{"class":86},[65,3776,2997],{"class":110},[65,3778,107],{"class":86},[65,3780,496],{"class":86},[65,3782,3783,3785,3787,3789,3791,3794,3796,3798,3800,3803,3805],{"class":67,"line":682},[65,3784,2820],{"class":285},[65,3786,289],{"class":86},[65,3788,2527],{"class":86},[65,3790,326],{"class":86},[65,3792,3793],{"class":285},"Content-Type",[65,3795,107],{"class":86},[65,3797,289],{"class":86},[65,3799,326],{"class":86},[65,3801,3802],{"class":110},"application\u002Fjson",[65,3804,107],{"class":86},[65,3806,3807],{"class":86}," },\n",[65,3809,3810,3813,3815,3817,3819,3821,3823,3826],{"class":67,"line":694},[65,3811,3812],{"class":285},"      body",[65,3814,289],{"class":86},[65,3816,1550],{"class":82},[65,3818,97],{"class":86},[65,3820,1773],{"class":100},[65,3822,104],{"class":285},[65,3824,3825],{"class":82},"data",[65,3827,3828],{"class":285},")\n",[65,3830,3831,3833,3835],{"class":67,"line":706},[65,3832,2846],{"class":86},[65,3834,116],{"class":285},[65,3836,119],{"class":86},[65,3838,3839],{"class":67,"line":716},[65,3840,1111],{"class":285},[65,3842,3843,3845,3847,3849,3852,3854,3857,3859],{"class":67,"line":723},[65,3844,1465],{"class":90},[65,3846,1468],{"class":285},[65,3848,2492],{"class":86},[65,3850,3851],{"class":82},"response",[65,3853,97],{"class":86},[65,3855,3856],{"class":82},"ok",[65,3858,1473],{"class":285},[65,3860,1476],{"class":86},[65,3862,3863,3865,3867,3869,3871,3873,3876,3878,3880,3882,3885,3887,3889],{"class":67,"line":732},[65,3864,1686],{"class":90},[65,3866,1338],{"class":86},[65,3868,1691],{"class":100},[65,3870,104],{"class":285},[65,3872,135],{"class":86},[65,3874,3875],{"class":110},"Service call failed: ",[65,3877,141],{"class":86},[65,3879,3851],{"class":82},[65,3881,97],{"class":86},[65,3883,3884],{"class":82},"statusText",[65,3886,147],{"class":86},[65,3888,116],{"class":285},[65,3890,119],{"class":86},[65,3892,3893],{"class":67,"line":744},[65,3894,1490],{"class":86},[65,3896,3897],{"class":67,"line":756},[65,3898,1111],{"class":285},[65,3900,3901,3903,3905,3907,3909,3911],{"class":67,"line":766},[65,3902,940],{"class":90},[65,3904,3731],{"class":82},[65,3906,97],{"class":86},[65,3908,3026],{"class":100},[65,3910,1343],{"class":285},[65,3912,119],{"class":86},[65,3914,3915],{"class":67,"line":773},[65,3916,894],{"class":86},[65,3918,3919],{"class":67,"line":778},[65,3920,383],{"class":86},[65,3922,3923],{"class":67,"line":783},[65,3924,162],{"emptyLinePlaceholder":161},[65,3926,3927],{"class":67,"line":789},[65,3928,3929],{"class":71},"\u002F\u002F Tenant-aware service communicatie\n",[65,3931,3932,3934,3937],{"class":67,"line":800},[65,3933,792],{"class":78},[65,3935,3936],{"class":276}," TenantAwareServiceClient",[65,3938,280],{"class":86},[65,3940,3941,3943,3946,3948,3950],{"class":67,"line":815},[65,3942,803],{"class":78},[65,3944,3945],{"class":285}," serviceRegistry",[65,3947,289],{"class":86},[65,3949,3449],{"class":276},[65,3951,119],{"class":86},[65,3953,3954,3956,3958,3960,3962],{"class":67,"line":829},[65,3955,803],{"class":78},[65,3957,820],{"class":285},[65,3959,289],{"class":86},[65,3961,292],{"class":276},[65,3963,119],{"class":86},[65,3965,3966],{"class":67,"line":834},[65,3967,162],{"emptyLinePlaceholder":161},[65,3969,3970,3972,3974,3977,3979,3981,3983,3985,3987,3989,3991],{"class":67,"line":862},[65,3971,837],{"class":78},[65,3973,104],{"class":86},[65,3975,3976],{"class":842},"serviceRegistry",[65,3978,289],{"class":86},[65,3980,3449],{"class":276},[65,3982,198],{"class":86},[65,3984,820],{"class":842},[65,3986,289],{"class":86},[65,3988,292],{"class":276},[65,3990,116],{"class":86},[65,3992,280],{"class":86},[65,3994,3995,3997,3999,4001,4003],{"class":67,"line":877},[65,3996,865],{"class":86},[65,3998,3976],{"class":82},[65,4000,870],{"class":86},[65,4002,3945],{"class":82},[65,4004,119],{"class":86},[65,4006,4007,4009,4011,4013,4015],{"class":67,"line":891},[65,4008,865],{"class":86},[65,4010,882],{"class":82},[65,4012,870],{"class":86},[65,4014,820],{"class":82},[65,4016,119],{"class":86},[65,4018,4019],{"class":67,"line":897},[65,4020,894],{"class":86},[65,4022,4023],{"class":67,"line":902},[65,4024,162],{"emptyLinePlaceholder":161},[65,4026,4027,4029,4032,4034,4036,4038,4040,4042,4044,4046,4048,4050,4052,4054,4056,4058],{"class":67,"line":931},[65,4028,905],{"class":78},[65,4030,4031],{"class":285}," callUserService",[65,4033,104],{"class":86},[65,4035,2951],{"class":842},[65,4037,289],{"class":86},[65,4039,292],{"class":276},[65,4041,198],{"class":86},[65,4043,3686],{"class":842},[65,4045,289],{"class":86},[65,4047,3691],{"class":276},[65,4049,1017],{"class":86},[65,4051,914],{"class":276},[65,4053,917],{"class":86},[65,4055,2893],{"class":276},[65,4057,926],{"class":86},[65,4059,280],{"class":86},[65,4061,4062,4064,4066,4068,4070,4073,4075,4077,4080,4082,4084,4086,4088],{"class":67,"line":937},[65,4063,940],{"class":90},[65,4065,943],{"class":86},[65,4067,3976],{"class":82},[65,4069,97],{"class":86},[65,4071,4072],{"class":100},"callService",[65,4074,104],{"class":285},[65,4076,107],{"class":86},[65,4078,4079],{"class":110},"userService",[65,4081,107],{"class":86},[65,4083,198],{"class":86},[65,4085,3677],{"class":82},[65,4087,198],{"class":86},[65,4089,280],{"class":86},[65,4091,4092,4095,4097],{"class":67,"line":955},[65,4093,4094],{"class":86},"      ...",[65,4096,3825],{"class":82},[65,4098,496],{"class":86},[65,4100,4101,4104,4106,4108],{"class":67,"line":967},[65,4102,4103],{"class":285},"      tenantId",[65,4105,289],{"class":86},[65,4107,943],{"class":86},[65,4109,4110],{"class":82},"tenantId\n",[65,4112,4113,4115,4117],{"class":67,"line":981},[65,4114,2846],{"class":86},[65,4116,116],{"class":285},[65,4118,119],{"class":86},[65,4120,4121],{"class":67,"line":989},[65,4122,894],{"class":86},[65,4124,4125],{"class":67,"line":994},[65,4126,162],{"emptyLinePlaceholder":161},[65,4128,4129,4131,4134,4136,4138,4140,4142,4144,4146,4148,4150,4152,4154,4156,4158,4160],{"class":67,"line":999},[65,4130,905],{"class":78},[65,4132,4133],{"class":285}," callOrderService",[65,4135,104],{"class":86},[65,4137,2951],{"class":842},[65,4139,289],{"class":86},[65,4141,292],{"class":276},[65,4143,198],{"class":86},[65,4145,3686],{"class":842},[65,4147,289],{"class":86},[65,4149,3691],{"class":276},[65,4151,1017],{"class":86},[65,4153,914],{"class":276},[65,4155,917],{"class":86},[65,4157,2893],{"class":276},[65,4159,926],{"class":86},[65,4161,280],{"class":86},[65,4163,4164,4166,4168,4170,4172,4174,4176,4178,4181,4183,4185,4187,4189],{"class":67,"line":1030},[65,4165,940],{"class":90},[65,4167,943],{"class":86},[65,4169,3976],{"class":82},[65,4171,97],{"class":86},[65,4173,4072],{"class":100},[65,4175,104],{"class":285},[65,4177,107],{"class":86},[65,4179,4180],{"class":110},"orderService",[65,4182,107],{"class":86},[65,4184,198],{"class":86},[65,4186,3677],{"class":82},[65,4188,198],{"class":86},[65,4190,280],{"class":86},[65,4192,4193,4195,4197],{"class":67,"line":1036},[65,4194,4094],{"class":86},[65,4196,3825],{"class":82},[65,4198,496],{"class":86},[65,4200,4201,4203,4205,4207],{"class":67,"line":1059},[65,4202,4103],{"class":285},[65,4204,289],{"class":86},[65,4206,943],{"class":86},[65,4208,4110],{"class":82},[65,4210,4211,4213,4215],{"class":67,"line":1071},[65,4212,2846],{"class":86},[65,4214,116],{"class":285},[65,4216,119],{"class":86},[65,4218,4219],{"class":67,"line":1101},[65,4220,894],{"class":86},[65,4222,4223],{"class":67,"line":1108},[65,4224,383],{"class":86},[24,4226,4227],{},[30,4228,1150],{},[34,4230,4231,4234,4237,4240],{},[37,4232,4233],{},"Elke service kan onafhankelijk schalen",[37,4235,4236],{},"Fault isolation voorkomt cascade failures",[37,4238,4239],{},"Teams kunnen onafhankelijk werken",[37,4241,4242],{},"Technologie diversiteit mogelijk",[24,4244,4245,4247],{},[30,4246,2152],{}," Schaalbaarheid verbeterde met 500% door microservices",[19,4249,4251],{"id":4250},"de-finale-optimalisatie-performance-monitoring","De Finale Optimalisatie: Performance Monitoring",[252,4253,4255],{"id":4254},"het-probleem-performance-degradatie-onder-belasting","Het Probleem: Performance Degradatie Onder Belasting",[24,4257,4258],{},"Zelfs met microservices was er performance degradatie onder belasting:",[55,4260,4262],{"className":57,"code":4261,"language":59,"meta":60,"style":60},"\u002F\u002F Probleem: Performance degradatie\ninterface PerformanceIssue {\n  type: 'slow_queries' | 'memory_leaks' | 'connection_pool_exhaustion';\n  service: string;\n  impact: 'high' | 'medium' | 'low';\n  timestamp: Date;\n}\n",[62,4263,4264,4269,4278,4312,4323,4357,4368],{"__ignoreMap":60},[65,4265,4266],{"class":67,"line":68},[65,4267,4268],{"class":71},"\u002F\u002F Probleem: Performance degradatie\n",[65,4270,4271,4273,4276],{"class":67,"line":75},[65,4272,273],{"class":78},[65,4274,4275],{"class":276}," PerformanceIssue",[65,4277,280],{"class":86},[65,4279,4280,4283,4285,4287,4290,4292,4294,4296,4299,4301,4303,4305,4308,4310],{"class":67,"line":122},[65,4281,4282],{"class":285},"  type",[65,4284,289],{"class":86},[65,4286,326],{"class":86},[65,4288,4289],{"class":110},"slow_queries",[65,4291,107],{"class":86},[65,4293,334],{"class":86},[65,4295,326],{"class":86},[65,4297,4298],{"class":110},"memory_leaks",[65,4300,107],{"class":86},[65,4302,334],{"class":86},[65,4304,326],{"class":86},[65,4306,4307],{"class":110},"connection_pool_exhaustion",[65,4309,107],{"class":86},[65,4311,119],{"class":86},[65,4313,4314,4317,4319,4321],{"class":67,"line":158},[65,4315,4316],{"class":285},"  service",[65,4318,289],{"class":86},[65,4320,292],{"class":276},[65,4322,119],{"class":86},[65,4324,4325,4328,4330,4332,4335,4337,4339,4341,4344,4346,4348,4350,4353,4355],{"class":67,"line":165},[65,4326,4327],{"class":285},"  impact",[65,4329,289],{"class":86},[65,4331,326],{"class":86},[65,4333,4334],{"class":110},"high",[65,4336,107],{"class":86},[65,4338,334],{"class":86},[65,4340,326],{"class":86},[65,4342,4343],{"class":110},"medium",[65,4345,107],{"class":86},[65,4347,334],{"class":86},[65,4349,326],{"class":86},[65,4351,4352],{"class":110},"low",[65,4354,107],{"class":86},[65,4356,119],{"class":86},[65,4358,4359,4362,4364,4366],{"class":67,"line":171},[65,4360,4361],{"class":285},"  timestamp",[65,4363,289],{"class":86},[65,4365,362],{"class":276},[65,4367,119],{"class":86},[65,4369,4370],{"class":67,"line":206},[65,4371,383],{"class":86},[252,4373,4375],{"id":4374},"de-oplossing-geautomatiseerde-performance-monitoring","De Oplossing: Geautomatiseerde Performance Monitoring",[24,4377,4378],{},"We implementeerden geautomatiseerde performance monitoring:",[55,4380,4382],{"className":57,"code":4381,"language":59,"meta":60,"style":60},"\u002F\u002F Performance monitoring systeem\nclass PerformanceMonitor {\n  private metrics: Map\u003Cstring, Metric[]> = new Map();\n  private alerts: Alert[] = [];\n\n  async trackMetric(service: string, metric: Metric): Promise\u003Cvoid> {\n    if (!this.metrics.has(service)) {\n      this.metrics.set(service, []);\n    }\n    \n    this.metrics.get(service)!.push(metric);\n    \n    \u002F\u002F Controleer op alerts\n    await this.checkAlerts(service, metric);\n  }\n\n  private async checkAlerts(service: string, metric: Metric): Promise\u003Cvoid> {\n    \u002F\u002F Response time alert\n    if (metric.type === 'response_time' && metric.value > 1000) {\n      await this.triggerAlert({\n        type: 'high_response_time',\n        service,\n        value: metric.value,\n        threshold: 1000,\n        timestamp: new Date()\n      });\n    }\n\n    \u002F\u002F Memory usage alert\n    if (metric.type === 'memory_usage' && metric.value > 80) {\n      await this.triggerAlert({\n        type: 'high_memory_usage',\n        service,\n        value: metric.value,\n        threshold: 80,\n        timestamp: new Date()\n      });\n    }\n  }\n\n  async triggerAlert(alert: Alert): Promise\u003Cvoid> {\n    this.alerts.push(alert);\n    \n    \u002F\u002F Notificeer beheerder\n    await this.notifyAdmin(alert);\n    \n    \u002F\u002F Auto-scaling trigger\n    if (alert.type === 'high_response_time') {\n      await this.triggerAutoScaling(alert.service);\n    }\n  }\n\n  async triggerAutoScaling(service: string): Promise\u003Cvoid> {\n    \u002F\u002F Implementeer auto-scaling logica\n    const currentInstances = await this.getServiceInstances(service);\n    const targetInstances = Math.min(currentInstances * 2, 10); \u002F\u002F Max 10 instances\n    \n    await this.scaleService(service, targetInstances);\n  }\n}\n",[62,4383,4384,4389,4398,4432,4454,4458,4494,4520,4541,4545,4549,4580,4584,4589,4610,4614,4618,4655,4660,4701,4714,4730,4737,4752,4763,4777,4785,4789,4793,4798,4836,4848,4863,4869,4883,4893,4905,4913,4917,4921,4925,4953,4972,4976,4981,4998,5002,5007,5031,5052,5056,5060,5064,5091,5096,5120,5160,5164,5185,5189],{"__ignoreMap":60},[65,4385,4386],{"class":67,"line":68},[65,4387,4388],{"class":71},"\u002F\u002F Performance monitoring systeem\n",[65,4390,4391,4393,4396],{"class":67,"line":75},[65,4392,792],{"class":78},[65,4394,4395],{"class":276}," PerformanceMonitor",[65,4397,280],{"class":86},[65,4399,4400,4402,4405,4407,4409,4411,4413,4415,4418,4420,4422,4424,4426,4428,4430],{"class":67,"line":122},[65,4401,803],{"class":78},[65,4403,4404],{"class":285}," metrics",[65,4406,289],{"class":86},[65,4408,1322],{"class":276},[65,4410,917],{"class":86},[65,4412,1327],{"class":276},[65,4414,198],{"class":86},[65,4416,4417],{"class":276}," Metric",[65,4419,923],{"class":82},[65,4421,926],{"class":86},[65,4423,870],{"class":86},[65,4425,1338],{"class":86},[65,4427,1322],{"class":285},[65,4429,1343],{"class":82},[65,4431,119],{"class":86},[65,4433,4434,4436,4439,4441,4444,4447,4449,4452],{"class":67,"line":158},[65,4435,803],{"class":78},[65,4437,4438],{"class":285}," alerts",[65,4440,289],{"class":86},[65,4442,4443],{"class":276}," Alert",[65,4445,4446],{"class":82},"[] ",[65,4448,87],{"class":86},[65,4450,4451],{"class":82}," []",[65,4453,119],{"class":86},[65,4455,4456],{"class":67,"line":165},[65,4457,162],{"emptyLinePlaceholder":161},[65,4459,4460,4462,4465,4467,4469,4471,4473,4475,4478,4480,4482,4484,4486,4488,4490,4492],{"class":67,"line":171},[65,4461,905],{"class":78},[65,4463,4464],{"class":285}," trackMetric",[65,4466,104],{"class":86},[65,4468,3601],{"class":842},[65,4470,289],{"class":86},[65,4472,292],{"class":276},[65,4474,198],{"class":86},[65,4476,4477],{"class":842}," metric",[65,4479,289],{"class":86},[65,4481,4417],{"class":276},[65,4483,1017],{"class":86},[65,4485,914],{"class":276},[65,4487,917],{"class":86},[65,4489,1949],{"class":276},[65,4491,926],{"class":86},[65,4493,280],{"class":86},[65,4495,4496,4498,4500,4503,4506,4508,4511,4513,4515,4518],{"class":67,"line":206},[65,4497,1465],{"class":90},[65,4499,1468],{"class":285},[65,4501,4502],{"class":86},"!this.",[65,4504,4505],{"class":82},"metrics",[65,4507,97],{"class":86},[65,4509,4510],{"class":100},"has",[65,4512,104],{"class":285},[65,4514,3601],{"class":82},[65,4516,4517],{"class":285},")) ",[65,4519,1476],{"class":86},[65,4521,4522,4524,4526,4528,4530,4532,4534,4536,4539],{"class":67,"line":367},[65,4523,1568],{"class":86},[65,4525,4505],{"class":82},[65,4527,97],{"class":86},[65,4529,1575],{"class":100},[65,4531,104],{"class":285},[65,4533,3601],{"class":82},[65,4535,198],{"class":86},[65,4537,4538],{"class":285}," [])",[65,4540,119],{"class":86},[65,4542,4543],{"class":67,"line":380},[65,4544,1490],{"class":86},[65,4546,4547],{"class":67,"line":386},[65,4548,1111],{"class":285},[65,4550,4551,4553,4555,4557,4559,4561,4563,4565,4568,4571,4573,4576,4578],{"class":67,"line":391},[65,4552,865],{"class":86},[65,4554,4505],{"class":82},[65,4556,97],{"class":86},[65,4558,1451],{"class":100},[65,4560,104],{"class":285},[65,4562,3601],{"class":82},[65,4564,116],{"class":285},[65,4566,4567],{"class":86},"!.",[65,4569,4570],{"class":100},"push",[65,4572,104],{"class":285},[65,4574,4575],{"class":82},"metric",[65,4577,116],{"class":285},[65,4579,119],{"class":86},[65,4581,4582],{"class":67,"line":397},[65,4583,1111],{"class":285},[65,4585,4586],{"class":67,"line":407},[65,4587,4588],{"class":71},"    \u002F\u002F Controleer op alerts\n",[65,4590,4591,4593,4595,4598,4600,4602,4604,4606,4608],{"class":67,"line":417},[65,4592,1746],{"class":90},[65,4594,943],{"class":86},[65,4596,4597],{"class":100},"checkAlerts",[65,4599,104],{"class":285},[65,4601,3601],{"class":82},[65,4603,198],{"class":86},[65,4605,4477],{"class":82},[65,4607,116],{"class":285},[65,4609,119],{"class":86},[65,4611,4612],{"class":67,"line":434},[65,4613,894],{"class":86},[65,4615,4616],{"class":67,"line":451},[65,4617,162],{"emptyLinePlaceholder":161},[65,4619,4620,4622,4624,4627,4629,4631,4633,4635,4637,4639,4641,4643,4645,4647,4649,4651,4653],{"class":67,"line":468},[65,4621,803],{"class":78},[65,4623,2865],{"class":78},[65,4625,4626],{"class":285}," checkAlerts",[65,4628,104],{"class":86},[65,4630,3601],{"class":842},[65,4632,289],{"class":86},[65,4634,292],{"class":276},[65,4636,198],{"class":86},[65,4638,4477],{"class":842},[65,4640,289],{"class":86},[65,4642,4417],{"class":276},[65,4644,1017],{"class":86},[65,4646,914],{"class":276},[65,4648,917],{"class":86},[65,4650,1949],{"class":276},[65,4652,926],{"class":86},[65,4654,280],{"class":86},[65,4656,4657],{"class":67,"line":474},[65,4658,4659],{"class":71},"    \u002F\u002F Response time alert\n",[65,4661,4662,4664,4666,4668,4670,4673,4675,4677,4680,4682,4685,4687,4689,4692,4694,4697,4699],{"class":67,"line":485},[65,4663,1465],{"class":90},[65,4665,1468],{"class":285},[65,4667,4575],{"class":82},[65,4669,97],{"class":86},[65,4671,4672],{"class":82},"type",[65,4674,1673],{"class":86},[65,4676,326],{"class":86},[65,4678,4679],{"class":110},"response_time",[65,4681,107],{"class":86},[65,4683,4684],{"class":86}," &&",[65,4686,4477],{"class":82},[65,4688,97],{"class":86},[65,4690,4691],{"class":82},"value",[65,4693,2022],{"class":86},[65,4695,4696],{"class":1676}," 1000",[65,4698,1473],{"class":285},[65,4700,1476],{"class":86},[65,4702,4703,4705,4707,4710,4712],{"class":67,"line":499},[65,4704,2081],{"class":90},[65,4706,943],{"class":86},[65,4708,4709],{"class":100},"triggerAlert",[65,4711,104],{"class":285},[65,4713,1476],{"class":86},[65,4715,4716,4719,4721,4723,4726,4728],{"class":67,"line":511},[65,4717,4718],{"class":285},"        type",[65,4720,289],{"class":86},[65,4722,326],{"class":86},[65,4724,4725],{"class":110},"high_response_time",[65,4727,107],{"class":86},[65,4729,496],{"class":86},[65,4731,4732,4735],{"class":67,"line":522},[65,4733,4734],{"class":82},"        service",[65,4736,496],{"class":86},[65,4738,4739,4742,4744,4746,4748,4750],{"class":67,"line":530},[65,4740,4741],{"class":285},"        value",[65,4743,289],{"class":86},[65,4745,4477],{"class":82},[65,4747,97],{"class":86},[65,4749,4691],{"class":82},[65,4751,496],{"class":86},[65,4753,4754,4757,4759,4761],{"class":67,"line":540},[65,4755,4756],{"class":285},"        threshold",[65,4758,289],{"class":86},[65,4760,4696],{"class":1676},[65,4762,496],{"class":86},[65,4764,4765,4768,4770,4772,4774],{"class":67,"line":552},[65,4766,4767],{"class":285},"        timestamp",[65,4769,289],{"class":86},[65,4771,1338],{"class":86},[65,4773,362],{"class":100},[65,4775,4776],{"class":285},"()\n",[65,4778,4779,4781,4783],{"class":67,"line":564},[65,4780,2671],{"class":86},[65,4782,116],{"class":285},[65,4784,119],{"class":86},[65,4786,4787],{"class":67,"line":574},[65,4788,1490],{"class":86},[65,4790,4791],{"class":67,"line":581},[65,4792,162],{"emptyLinePlaceholder":161},[65,4794,4795],{"class":67,"line":586},[65,4796,4797],{"class":71},"    \u002F\u002F Memory usage alert\n",[65,4799,4800,4802,4804,4806,4808,4810,4812,4814,4817,4819,4821,4823,4825,4827,4829,4832,4834],{"class":67,"line":591},[65,4801,1465],{"class":90},[65,4803,1468],{"class":285},[65,4805,4575],{"class":82},[65,4807,97],{"class":86},[65,4809,4672],{"class":82},[65,4811,1673],{"class":86},[65,4813,326],{"class":86},[65,4815,4816],{"class":110},"memory_usage",[65,4818,107],{"class":86},[65,4820,4684],{"class":86},[65,4822,4477],{"class":82},[65,4824,97],{"class":86},[65,4826,4691],{"class":82},[65,4828,2022],{"class":86},[65,4830,4831],{"class":1676}," 80",[65,4833,1473],{"class":285},[65,4835,1476],{"class":86},[65,4837,4838,4840,4842,4844,4846],{"class":67,"line":597},[65,4839,2081],{"class":90},[65,4841,943],{"class":86},[65,4843,4709],{"class":100},[65,4845,104],{"class":285},[65,4847,1476],{"class":86},[65,4849,4850,4852,4854,4856,4859,4861],{"class":67,"line":607},[65,4851,4718],{"class":285},[65,4853,289],{"class":86},[65,4855,326],{"class":86},[65,4857,4858],{"class":110},"high_memory_usage",[65,4860,107],{"class":86},[65,4862,496],{"class":86},[65,4864,4865,4867],{"class":67,"line":617},[65,4866,4734],{"class":82},[65,4868,496],{"class":86},[65,4870,4871,4873,4875,4877,4879,4881],{"class":67,"line":634},[65,4872,4741],{"class":285},[65,4874,289],{"class":86},[65,4876,4477],{"class":82},[65,4878,97],{"class":86},[65,4880,4691],{"class":82},[65,4882,496],{"class":86},[65,4884,4885,4887,4889,4891],{"class":67,"line":651},[65,4886,4756],{"class":285},[65,4888,289],{"class":86},[65,4890,4831],{"class":1676},[65,4892,496],{"class":86},[65,4894,4895,4897,4899,4901,4903],{"class":67,"line":668},[65,4896,4767],{"class":285},[65,4898,289],{"class":86},[65,4900,1338],{"class":86},[65,4902,362],{"class":100},[65,4904,4776],{"class":285},[65,4906,4907,4909,4911],{"class":67,"line":673},[65,4908,2671],{"class":86},[65,4910,116],{"class":285},[65,4912,119],{"class":86},[65,4914,4915],{"class":67,"line":682},[65,4916,1490],{"class":86},[65,4918,4919],{"class":67,"line":694},[65,4920,894],{"class":86},[65,4922,4923],{"class":67,"line":706},[65,4924,162],{"emptyLinePlaceholder":161},[65,4926,4927,4929,4932,4934,4937,4939,4941,4943,4945,4947,4949,4951],{"class":67,"line":716},[65,4928,905],{"class":78},[65,4930,4931],{"class":285}," triggerAlert",[65,4933,104],{"class":86},[65,4935,4936],{"class":842},"alert",[65,4938,289],{"class":86},[65,4940,4443],{"class":276},[65,4942,1017],{"class":86},[65,4944,914],{"class":276},[65,4946,917],{"class":86},[65,4948,1949],{"class":276},[65,4950,926],{"class":86},[65,4952,280],{"class":86},[65,4954,4955,4957,4960,4962,4964,4966,4968,4970],{"class":67,"line":723},[65,4956,865],{"class":86},[65,4958,4959],{"class":82},"alerts",[65,4961,97],{"class":86},[65,4963,4570],{"class":100},[65,4965,104],{"class":285},[65,4967,4936],{"class":82},[65,4969,116],{"class":285},[65,4971,119],{"class":86},[65,4973,4974],{"class":67,"line":732},[65,4975,1111],{"class":285},[65,4977,4978],{"class":67,"line":744},[65,4979,4980],{"class":71},"    \u002F\u002F Notificeer beheerder\n",[65,4982,4983,4985,4987,4990,4992,4994,4996],{"class":67,"line":756},[65,4984,1746],{"class":90},[65,4986,943],{"class":86},[65,4988,4989],{"class":100},"notifyAdmin",[65,4991,104],{"class":285},[65,4993,4936],{"class":82},[65,4995,116],{"class":285},[65,4997,119],{"class":86},[65,4999,5000],{"class":67,"line":766},[65,5001,1111],{"class":285},[65,5003,5004],{"class":67,"line":773},[65,5005,5006],{"class":71},"    \u002F\u002F Auto-scaling trigger\n",[65,5008,5009,5011,5013,5015,5017,5019,5021,5023,5025,5027,5029],{"class":67,"line":778},[65,5010,1465],{"class":90},[65,5012,1468],{"class":285},[65,5014,4936],{"class":82},[65,5016,97],{"class":86},[65,5018,4672],{"class":82},[65,5020,1673],{"class":86},[65,5022,326],{"class":86},[65,5024,4725],{"class":110},[65,5026,107],{"class":86},[65,5028,1473],{"class":285},[65,5030,1476],{"class":86},[65,5032,5033,5035,5037,5040,5042,5044,5046,5048,5050],{"class":67,"line":783},[65,5034,2081],{"class":90},[65,5036,943],{"class":86},[65,5038,5039],{"class":100},"triggerAutoScaling",[65,5041,104],{"class":285},[65,5043,4936],{"class":82},[65,5045,97],{"class":86},[65,5047,3601],{"class":82},[65,5049,116],{"class":285},[65,5051,119],{"class":86},[65,5053,5054],{"class":67,"line":789},[65,5055,1490],{"class":86},[65,5057,5058],{"class":67,"line":800},[65,5059,894],{"class":86},[65,5061,5062],{"class":67,"line":815},[65,5063,162],{"emptyLinePlaceholder":161},[65,5065,5066,5068,5071,5073,5075,5077,5079,5081,5083,5085,5087,5089],{"class":67,"line":829},[65,5067,905],{"class":78},[65,5069,5070],{"class":285}," triggerAutoScaling",[65,5072,104],{"class":86},[65,5074,3601],{"class":842},[65,5076,289],{"class":86},[65,5078,292],{"class":276},[65,5080,1017],{"class":86},[65,5082,914],{"class":276},[65,5084,917],{"class":86},[65,5086,1949],{"class":276},[65,5088,926],{"class":86},[65,5090,280],{"class":86},[65,5092,5093],{"class":67,"line":834},[65,5094,5095],{"class":71},"    \u002F\u002F Implementeer auto-scaling logica\n",[65,5097,5098,5100,5103,5105,5107,5109,5112,5114,5116,5118],{"class":67,"line":862},[65,5099,1039],{"class":78},[65,5101,5102],{"class":82}," currentInstances",[65,5104,870],{"class":86},[65,5106,91],{"class":90},[65,5108,943],{"class":86},[65,5110,5111],{"class":100},"getServiceInstances",[65,5113,104],{"class":285},[65,5115,3601],{"class":82},[65,5117,116],{"class":285},[65,5119,119],{"class":86},[65,5121,5122,5124,5127,5129,5132,5134,5137,5139,5142,5145,5148,5150,5153,5155,5157],{"class":67,"line":877},[65,5123,1039],{"class":78},[65,5125,5126],{"class":82}," targetInstances",[65,5128,870],{"class":86},[65,5130,5131],{"class":82}," Math",[65,5133,97],{"class":86},[65,5135,5136],{"class":100},"min",[65,5138,104],{"class":285},[65,5140,5141],{"class":82},"currentInstances",[65,5143,5144],{"class":86}," *",[65,5146,5147],{"class":1676}," 2",[65,5149,198],{"class":86},[65,5151,5152],{"class":1676}," 10",[65,5154,116],{"class":285},[65,5156,152],{"class":86},[65,5158,5159],{"class":71}," \u002F\u002F Max 10 instances\n",[65,5161,5162],{"class":67,"line":891},[65,5163,1111],{"class":285},[65,5165,5166,5168,5170,5173,5175,5177,5179,5181,5183],{"class":67,"line":897},[65,5167,1746],{"class":90},[65,5169,943],{"class":86},[65,5171,5172],{"class":100},"scaleService",[65,5174,104],{"class":285},[65,5176,3601],{"class":82},[65,5178,198],{"class":86},[65,5180,5126],{"class":82},[65,5182,116],{"class":285},[65,5184,119],{"class":86},[65,5186,5187],{"class":67,"line":902},[65,5188,894],{"class":86},[65,5190,5191],{"class":67,"line":931},[65,5192,383],{"class":86},[24,5194,5195],{},[30,5196,1150],{},[34,5198,5199,5202,5205,5208],{},[37,5200,5201],{},"Real-time performance monitoring",[37,5203,5204],{},"Automatische alerting",[37,5206,5207],{},"Auto-scaling onder belasting",[37,5209,5210],{},"Proactieve performance management",[24,5212,5213,5215],{},[30,5214,2152],{}," Performance stabiliteit verbeterde met 90% door monitoring",[19,5217,5219],{"id":5218},"performance-resultaten-samenvatting","Performance Resultaten Samenvatting",[5221,5222,5223,5239],"table",{},[5224,5225,5226],"thead",{},[5227,5228,5229,5233,5236],"tr",{},[5230,5231,5232],"th",{},"Optimalisatie Stap",[5230,5234,5235],{},"Schaalbaarheid Verbetering",[5230,5237,5238],{},"Performance Verbetering",[5240,5241,5242,5256,5269,5282,5294],"tbody",{},[5227,5243,5244,5250,5253],{},[5245,5246,5247],"td",{},[30,5248,5249],{},"Multi-Tenant Database",[5245,5251,5252],{},"70% betere tenant isolatie",[5245,5254,5255],{},"70% snellere queries",[5227,5257,5258,5263,5266],{},[5245,5259,5260],{},[30,5261,5262],{},"Tenant Resolution",[5245,5264,5265],{},"200x snellere resolution",[5245,5267,5268],{},"5ms tenant lookup",[5227,5270,5271,5276,5279],{},[5245,5272,5273],{},[30,5274,5275],{},"Schaalbare API",[5245,5277,5278],{},"10x snellere responses",[5245,5280,5281],{},"100ms API response",[5227,5283,5284,5289,5292],{},[5245,5285,5286],{},[30,5287,5288],{},"Microservices",[5245,5290,5291],{},"500% betere schaalbaarheid",[5245,5293,3410],{},[5227,5295,5296,5301,5304],{},[5245,5297,5298],{},[30,5299,5300],{},"Performance Monitoring",[5245,5302,5303],{},"90% performance stabiliteit",[5245,5305,5306],{},[30,5307,5308],{},"Auto-scaling",[19,5310,5312],{"id":5311},"belangrijkste-lessen-geleerd","Belangrijkste Lessen Geleerd",[252,5314,5316],{"id":5315},"_1-multi-tenant-design-is-kritiek","1. Multi-Tenant Design Is Kritiek",[34,5318,5319,5322,5325],{},[37,5320,5321],{},"Shared schema is ideaal voor startups",[37,5323,5324],{},"Separate schema is beter voor enterprise",[37,5326,5327],{},"Tenant isolatie voorkomt data lekken",[252,5329,5331],{"id":5330},"_2-tenant-resolution-moet-snel-zijn","2. Tenant Resolution Moet Snel Zijn",[34,5333,5334,5337,5340],{},[37,5335,5336],{},"Multi-layer caching verbetert performance",[37,5338,5339],{},"Subdomain-based identificatie is eenvoudig",[37,5341,5342],{},"Cache invalidatie is essentieel",[252,5344,5346],{"id":5345},"_3-api-design-beïnvloedt-schaalbaarheid","3. API Design Beïnvloedt Schaalbaarheid",[34,5348,5349,5352,5355],{},[37,5350,5351],{},"Tenant-aware processing is cruciaal",[37,5353,5354],{},"Rate limiting per tenant voorkomt abuse",[37,5356,5357],{},"Caching verbetert response tijden",[252,5359,5361],{"id":5360},"_4-microservices-schalen-beter","4. Microservices Schalen Beter",[34,5363,5364,5366,5368],{},[37,5365,4233],{},[37,5367,4236],{},[37,5369,5370],{},"Team autonomy verbetert ontwikkeling",[252,5372,5374],{"id":5373},"_5-performance-monitoring-is-essentieel","5. Performance Monitoring Is Essentieel",[34,5376,5377,5380,5383],{},[37,5378,5379],{},"Real-time monitoring detecteert problemen",[37,5381,5382],{},"Automatische alerting voorkomt downtime",[37,5384,5385],{},"Auto-scaling behoudt performance onder belasting",[19,5387,5389],{"id":5388},"implementatie-checklist","Implementatie Checklist",[24,5391,5392],{},"Als je SaaS architectuur wilt optimaliseren:",[34,5394,5397,5410,5419,5428,5437,5446,5455,5464],{"className":5395},[5396],"contains-task-list",[37,5398,5401,5405,5406,5409],{"className":5399},[5400],"task-list-item",[5402,5403],"input",{"disabled":161,"type":5404},"checkbox"," ",[30,5407,5408],{},"Kies multi-tenant database patroon",": Shared schema voor startups",[37,5411,5413,5405,5415,5418],{"className":5412},[5400],[5402,5414],{"disabled":161,"type":5404},[30,5416,5417],{},"Implementeer tenant resolution",": Cached, snelle lookup",[37,5420,5422,5405,5424,5427],{"className":5421},[5400],[5402,5423],{"disabled":161,"type":5404},[30,5425,5426],{},"Bouw schaalbare APIs",": Tenant-aware, gecached",[37,5429,5431,5405,5433,5436],{"className":5430},[5400],[5402,5432],{"disabled":161,"type":5404},[30,5434,5435],{},"Overweeg microservices",": Voor complexe SaaS applicaties",[37,5438,5440,5405,5442,5445],{"className":5439},[5400],[5402,5441],{"disabled":161,"type":5404},[30,5443,5444],{},"Voeg performance monitoring toe",": Real-time, automatische alerting",[37,5447,5449,5405,5451,5454],{"className":5448},[5400],[5402,5450],{"disabled":161,"type":5404},[30,5452,5453],{},"Implementeer auto-scaling",": Onder belasting",[37,5456,5458,5405,5460,5463],{"className":5457},[5400],[5402,5459],{"disabled":161,"type":5404},[30,5461,5462],{},"Test onder belasting",": Zorg dat performance behouden blijft",[37,5465,5467,5405,5469,5472],{"className":5466},[5400],[5402,5468],{"disabled":161,"type":5404},[30,5470,5471],{},"Monitor tenant isolatie",": Voorkom data lekken",[19,5474,5476],{"id":5475},"samenvatting","Samenvatting",[24,5478,5479],{},"Het bouwen van schaalbare SaaS applicaties vereist een uitgebreide architectuur aanpak. Door multi-tenant database design, snelle tenant resolution, schaalbare API architectuur, microservices en performance monitoring te combineren, bereikten we SaaS applicaties die schalen van startup tot enterprise niveau.",[24,5481,5482],{},"De sleutel was begrijpen dat SaaS architectuur niet alleen gaat over technische implementatie—het gaat over het creëren van een complete architectuur strategie die schaalbaarheid waarborgt terwijl performance en tenant isolatie behouden blijft.",[24,5484,5485],{},"Als dit artikel je hielp SaaS architectuur te begrijpen, kunnen we je helpen deze patronen te implementeren in je eigen applicaties. Bij Ludulicious specialiseren we ons in:",[34,5487,5488,5494,5500],{},[37,5489,5490,5493],{},[30,5491,5492],{},"SaaS Architectuur",": Schaalbare, multi-tenant applicaties",[37,5495,5496,5499],{},[30,5497,5498],{},"Microservices Design",": Modulaire, schaalbare service architectuur",[37,5501,5502,5505],{},[30,5503,5504],{},"Performance Optimization",": Database en API optimalisatie",[24,5507,5508],{},[30,5509,5510],{},"Klaar om je SaaS architectuur te optimaliseren?",[24,5512,5513,5518],{},[5514,5515,5517],"a",{"href":5516},"\u002Fcontact","Neem contact op"," voor een gratis consultatie, of bekijk onze andere architectuur gidsen:",[34,5520,5521,5527,5533,5539,5545],{},[37,5522,5523],{},[5514,5524,5526],{"href":5525},"\u002Fblog\u002Fdomain-structure-challenges","Domain Structuur Uitdagingen: Wanneer Klanten Niet Weten Wat Ze Willen",[37,5528,5529],{},[5514,5530,5532],{"href":5531},"\u002Fblog\u002Fauthentication-strategies","Authenticatie Strategieën: Veilige, Snelle Gebruikersbeheer",[37,5534,5535],{},[5514,5536,5538],{"href":5537},"\u002Fblog\u002Ftypescript-best-practices","TypeScript Best Practices: Type-Safe Development",[37,5540,5541],{},[5514,5542,5544],{"href":5543},"\u002Fblog\u002Fclient-communication-strategies","Client Communicatie Strategieën: Vertrouwen Bouwen Door Transparantie",[37,5546,5547],{},[5514,5548,5550],{"href":5549},"\u002Fblog\u002Fproject-estimation-challenges","Project Estimation Uitdagingen: Onzekerheid Beheren in Softwareontwikkeling",[5552,5553],"hr",{},[24,5555,5556],{},[5557,5558,5559],"em",{},"Deze architectuur case study is gebaseerd op echte productie ervaring met SaaS applicaties. Alle performance cijfers zijn van echte productie systemen.",[5561,5562,5563],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":60,"searchDepth":75,"depth":75,"links":5565},[5566,5567,5568,5573,5577,5581,5582,5589,5590],{"id":21,"depth":75,"text":22},{"id":223,"depth":75,"text":224},{"id":249,"depth":75,"text":250,"children":5569},[5570,5571,5572],{"id":254,"depth":122,"text":255},{"id":1172,"depth":122,"text":1173},{"id":2156,"depth":122,"text":2157},{"id":3098,"depth":75,"text":3099,"children":5574},[5575,5576],{"id":3102,"depth":122,"text":3103},{"id":3257,"depth":122,"text":3258},{"id":4250,"depth":75,"text":4251,"children":5578},[5579,5580],{"id":4254,"depth":122,"text":4255},{"id":4374,"depth":122,"text":4375},{"id":5218,"depth":75,"text":5219},{"id":5311,"depth":75,"text":5312,"children":5583},[5584,5585,5586,5587,5588],{"id":5315,"depth":122,"text":5316},{"id":5330,"depth":122,"text":5331},{"id":5345,"depth":122,"text":5346},{"id":5360,"depth":122,"text":5361},{"id":5373,"depth":122,"text":5374},{"id":5388,"depth":75,"text":5389},{"id":5475,"depth":75,"text":5476},[14,5592],"SaaS","2025-01-17","Leer bewezen SaaS architectuur patronen voor het bouwen van schaalbare, multi-tenant applicaties. Echte wereld strategieën voor database design, API architectuur en deployment die groei van startup tot enterprise schaal aankunnen.","md",{"src":5597},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F17\u002F640\u002F360",{},"\u002Fblog\u002Fsaas-architecture-patterns",{"title":5,"description":5594},"blog\u002F13.saas-architecture-patterns",[5492,5603,5604,5605,5606,5288,5607],"Multi-tenancy","Schaalbaarheid","Database Design","API Design","Performance","b3Obd2R2Qe0gp6k-_Sk9rrbfpWrJCkJSyFKfsze7njU",[5610,5613],{"title":5532,"path":5531,"stem":5611,"description":5612,"children":-1},"blog\u002F12.authentication-strategies","Leer moderne authenticatie strategieën voor webapplicaties, van OAuth2 flows tot session management. Echte wereld implementatie patronen die veiligheid waarborgen terwijl optimale performance en gebruikerservaring behouden blijft.",{"title":5538,"path":5537,"stem":5614,"description":5615,"children":-1},"blog\u002F14.typescript-best-practices","Leer TypeScript best practices voor het bouwen van type-safe, onderhoudbare applicaties. Echte wereld patronen voor type definities, error handling en performance optimalisatie die runtime errors voorkomen en code kwaliteit verbeteren.",[]]