Tidigare märkte jag ofta ett vanligt tillvägagångssätt där utvecklare (inklusive mig själv förstås) använde samma API för både läsning och skrivning på varje fall. Ännu mer så förlitade vi oss ofta på samma datakälla, såsom MySQL/PostgreSQL, för att hantera båda operationerna.
Detta innebär att man skriver till samma kolumner och läser från dem, vilket ofta leder till problem med att optimera index på fält som var mycket efterfrågade.
Så till exempel skulle vi finna att vi ofta justerar index för att passa nya filter eller förbättra frågeprestanda, och fält som används med operatörer som LIKE utgjorde särskilda utmaningar på grund av deras inverkan på prestanda.
Dessa ändringar leder ofta till ytterligare justeringar av backend, inklusive modifiering av API:er för att exponera den uppdaterade funktionen, uppmätta tider på grund av ytterligare JOINs och så vidare...
För att möta utmaningen med att lägga till nya filter och sånt i API:t gjordes försök att optimera processen med hjälp av verktyg och standarder som Apicalypse och, naturligtvis, GraphQL .
Dessa lösningar syftade till att effektivisera generering av API-frågor och minska den manuella ansträngning som krävs för att implementera nya filter och funktioner, och erbjöd ett mer dynamiskt tillvägagångssätt för att hantera dataåtkomst, men de hade en hög inlärningskurva.
Med framväxten av CQRS (Command Query Responsibility Segregation) började ett nytt tillvägagångssätt dyka upp. Detta tankesätt uppmuntrade användningen av separata källor för att skriva och läsa. Skriver kan avge händelser, och läsningar kan bygga vyer från dessa händelser på särskilda platser. Även om läsningar och skrivningar hanterades inom samma databas (men olika tabeller), gav denna separation betydande fördelar, och kunde naturligtvis bli av med den andra utmaningen - JOINs och sökfrågor på domänmodeller, som läsmodeller är vanligtvis i en form av denormaliserade JSONs.
Detta väckte dock ett annat problem. Med läsningar var vi tvungna att skala skrivningar, vilket betyder att den enda anledningen till att vi var tvungna att skala instanser av vår applikation från X till Y var på grund av läsningar. Det här problemet kan delvis mildras med cachning, och i en värld av mikrotjänster kan vi ha dedikerade mikrotjänster för läsningar.
Men...
Ändå var detta inte en idealisk lösning för andra arkitektoniska stilar som modulära monoliter, där sådan separation kanske inte passade väl med systemets designfilosofi. En annan sak var, när API låg nere var hela produkten nere, och med tanke på att de flesta produkterna är beroende av fler läsningar än skrivningar, kan det påverka verksamheten i onödan (bortsett från down API förstås ;) )
Så, tänk om vi kunde fråga dessa "vyer", även kända som läsmodeller, direkt utan att involvera API:et och hantera belastningar? Det är här lösningar som Meilisearch , AppSearch och andra kommer in i bilden och utnyttjar ett mönster som kallas "Valet Key". Genom att använda det här mönstret kan frontends komma åt läsoptimerade modeller direkt, vilket minskar beroendet av backend-API:er. Naturligtvis måste frontend fortfarande "be" API efter "Valet key", men frontend kan cache-nycklar, så även när API är nere kan frontend fortfarande kommunicera och visa innehåll.
Med detta tillvägagångssätt kan vi fokusera på läsdatabasen och inte oroa oss för att hantera trafiken för läsningar i vårt API. "Valet Key" som tillhandahålls till frontend via vårt API är säkrad på ett sätt som frontend inte kan ändra den. Den innehåller fördefinierade filter och index.
Om gränssnittet kräver ytterligare funktioner kan det begära dem via API:t, där API:et kan validera om de ska tillåtas. Det är fortfarande färre samtal.
Några fördelar jag kan se är:
Men det finns alltid nackdelar:
Så, det här tillvägagångssättet är inte en silverkula och introducerar sin egen uppsättning utmaningar, men om du är okej med en nackdel, kommer en liten förändring på frontend troligen inte att kräva att backend-teamet involveras, effektivisera utvecklingsprocessen och förbättra övergripande smidighet och självklart skalbarhet bör vara lättare.