Projectcache
De Projectcache API beheert het laden van projecten in het geheugen voor API-operaties. Begrijpen wanneer projecten geladen moeten worden is essentieel voor efficiënt API-gebruik.
Belangrijke concepten
Geünificeerde cache-architectuur
De API en UI delen dezelfde cache in het geheugen. Wanneer je een project laadt via de API, is het dezelfde cache die de UI gebruikt. Dit betekent:
- Gedeelde status: API-operaties zien dezelfde data als UI-gebruikers
- Gedeelde resultaten: Uitvoeringsresultaten zijn zichtbaar voor zowel API als UI
- Geen divergentie: Het is onmogelijk voor API en UI om verschillende weergaven van een project te hebben
Categorieën van operaties
API-operaties vallen in drie categorieën met verschillende cachevereisten:
| Categorie | Beschrijving | Project laden vereist? | Voorbeelden |
|---|---|---|---|
| Directe DB | Alleen-lezen bewerkingen | Nee | GET endpoints, beheer van tenant/gebruiker |
| Auto-Laden | Bewerking operaties | Nee (automatisch laden) | POST/PUT/DELETE op onderzoeken, notitieboeken, blokken |
| Vereist laden | Uitvoeringsoperaties | Ja | Notitieboek uitvoeren, uitvoeringsresultaten ophalen |
Auto-Laden patroon (vereenvoudigde workflow)
Voor de meeste CRUD-operaties moet je het project niet expliciet laden. De API laadt het project automatisch wanneer nodig:
# OUDE workflow (niet meer nodig voor CRUD):
# manager.load_project(project_id) # Niet verplicht!
# NIEUWE workflow - roep de operatie direct aan:
response = requests.put(
f"{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/{notebook_id}",
json={"Name": "Updated Name"},
headers=headers
)
# Project wordt automatisch geladen indien nodig
Wanneer expliciet laden WEL vereist is
Expliciet projectladen is nog steeds vereist voor uitvoeringsoperaties:
POST /execution/notebook/{notebookId}- Voer notitieboek uitGET /execution/notebook/{notebookId}/results- Haal uitvoeringsresultaten opGET /execution/status/{notebookId}- Controleer uitvoeringsstatus
Project laden in cache
GET /api/{tenantId}/project/{projectId}/load
Laadt een project in de gedeelde cache. Gebruik dit vóór het uitvoeren van notitieboeken.
Padparameters
| Parameter | Type | Verplicht | Beschrijving |
|---|---|---|---|
tenantId |
GUID | Ja | Identificator van de tenant |
projectId |
GUID | Ja | Identificator van het project |
Respons (200 OK)
{
"projectId": "87654321-4321-4321-4321-210987654321",
"projectName": "Purchase Order Analysis",
"tenantName": "acme-corp",
"investigationCount": 5,
"notebookCount": 12,
"datasetCount": 3,
"loadedFromCache": false,
"message": "Project loaded from database"
}
Responsvelden
| Veld | Type | Beschrijving |
|---|---|---|
projectId |
GUID | Projectidentificator |
projectName |
string | Naam van het project |
tenantName |
string | Naam van de tenant |
investigationCount |
integer | Aantal onderzoeken |
notebookCount |
integer | Aantal notitieboeken |
datasetCount |
integer | Aantal datasets |
loadedFromCache |
boolean | Waar als al in cache, onwaar als geladen uit database |
message |
string | Mensvriendelijke statusmelding |
Cachegedrag
| Scenario | Respons | Prestaties |
|---|---|---|
| Eerste oproep (cache miss) | loadedFromCache: false |
~1000ms (database query) |
| Volgende oproepen (cache hit) | loadedFromCache: true |
~75ms (13x sneller) |
| Na 30 minuten inactiviteit | Cache verloopt | Volgende oproep laadt opnieuw |
Cache-eigenschappen
- Duur: 30 minuten na laatste toegang
- Automatische vernieuwing: Elke API-call naar het project reset de 30 minuten timer
- Gedeeld: Zelfde cache wordt door UI en API gebruikt
- Geheugenbeheer: Automatische schoonmaak bij 90% geheugendruk
Project uit cache verwijderen
DELETE /api/{tenantId}/project/{projectId}/unload
Verwijdert een project uit de cache, waardoor geheugen vrijkomt.
Padparameters
| Parameter | Type | Verplicht | Beschrijving |
|---|---|---|---|
tenantId |
GUID | Ja | Identificator van de tenant |
projectId |
GUID | Ja | Identificator van het project |
Respons (200 OK)
{
"projectId": "87654321-4321-4321-4321-210987654321",
"wasInCache": true,
"message": "Project unloaded from cache successfully"
}
Workflow voorbeelden
Workflow A: CRUD-operaties (Auto-Laden)
Voor het aanmaken, bijwerken of verwijderen van onderzoeken, notitieboeken of blokken:
import requests
headers = {"Authorization": f"Bearer {API_KEY}"}
# Gewoon direct de operatie aanroepen - geen laden nodig!
response = requests.post(
f"{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/investigation",
json={"name": "New Investigation", "description": "Created via API"},
headers=headers
)
# Project wordt automatisch geladen indien nodig
Workflow B: Notitieboek uitvoeren (Vereist laden)
Voor het uitvoeren van notitieboeken en ophalen van resultaten:
import requests
import time
headers = {"Authorization": f"Bearer {API_KEY}"}
# Stap 1: Project laden (VEREIST voor uitvoering)
response = requests.get(
f"{BASE_URL}/api/{TENANT_ID}/project/{PROJECT_ID}/load",
headers=headers
)
print(f"Project geladen: {response.json()['projectName']}")
# Stap 2: Notitieboek uitvoeren
response = requests.post(
f"{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/execution/notebook/{NOTEBOOK_ID}",
headers=headers
)
print(f"Uitvoering in wachtrij: {response.json()['status']}")
# Stap 3: Poll voor voltooiing
while True:
response = requests.get(
f"{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/execution/status/{NOTEBOOK_ID}",
headers=headers
)
status = response.json()
print(f"Status: {status['status']} ({status['progress']}%)")
if status['status'] == 'Completed':
break
time.sleep(2)
# Stap 4: Resultaten ophalen
response = requests.get(
f"{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/execution/notebook/{NOTEBOOK_ID}/results",
headers=headers
)
results = response.json()
# Stap 5: Project ontladen (optionele opruiming)
requests.delete(
f"{BASE_URL}/api/{TENANT_ID}/project/{PROJECT_ID}/unload",
headers=headers
)
Implementatievoorbeelden
cURL
# Project in cache laden
curl -X GET "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/project/87654321-4321-4321-4321-210987654321/load" \
-H "Authorization: Bearer YOUR_API_KEY"
# Project uit cache verwijderen
curl -X DELETE "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/project/87654321-4321-4321-4321-210987654321/unload" \
-H "Authorization: Bearer YOUR_API_KEY"
Python
import requests
TENANT_ID = '12345678-1234-1234-1234-123456789012'
BASE_URL = 'https://your-mindzie-instance.com'
class ProjectCacheManager:
def __init__(self, token):
self.headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
self.loaded_projects = set()
def load_project(self, project_id):
"""Laad project in cache (vereist voor uitvoeringsoperaties)."""
url = f'{BASE_URL}/api/{TENANT_ID}/project/{project_id}/load'
response = requests.get(url, headers=self.headers)
response.raise_for_status()
result = response.json()
self.loaded_projects.add(project_id)
status = "uit cache" if result['loadedFromCache'] else "uit database"
print(f"Project '{result['projectName']}' geladen {status}")
return result
def unload_project(self, project_id):
"""Verwijder project uit cache."""
url = f'{BASE_URL}/api/{TENANT_ID}/project/{project_id}/unload'
response = requests.delete(url, headers=self.headers)
response.raise_for_status()
self.loaded_projects.discard(project_id)
return response.json()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
for project_id in list(self.loaded_projects):
self.unload_project(project_id)
# Gebruik met contextmanager
with ProjectCacheManager('your-api-key') as cache:
result = cache.load_project('87654321-4321-4321-4321-210987654321')
# Voer notitieboeken hier uit...
# Projecten worden automatisch ontladen bij afsluiten
JavaScript/Node.js
const TENANT_ID = '12345678-1234-1234-1234-123456789012';
const BASE_URL = 'https://your-mindzie-instance.com';
class ProjectCacheManager {
constructor(token) {
this.headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
this.loadedProjects = new Set();
}
async loadProject(projectId) {
const url = `${BASE_URL}/api/${TENANT_ID}/project/${projectId}/load`;
const response = await fetch(url, { headers: this.headers });
if (!response.ok) throw new Error(`Mislukt: ${response.status}`);
const result = await response.json();
this.loadedProjects.add(projectId);
console.log(`Geladen: ${result.projectName} (uit cache: ${result.loadedFromCache})`);
return result;
}
async unloadProject(projectId) {
const url = `${BASE_URL}/api/${TENANT_ID}/project/${projectId}/unload`;
const response = await fetch(url, {
method: 'DELETE',
headers: this.headers
});
this.loadedProjects.delete(projectId);
return response.json();
}
async unloadAll() {
await Promise.all(
Array.from(this.loadedProjects).map(id => this.unloadProject(id))
);
}
}
// Gebruik
const cache = new ProjectCacheManager('your-api-key');
try {
await cache.loadProject('87654321-4321-4321-4321-210987654321');
// Voer notitieboeken hier uit...
} finally {
await cache.unloadAll();
}
Best practices
- CRUD-operaties: Laad niet expliciet - laat auto-load het regelen
- Uitvoeringsoperaties: Laad altijd eerst het project
- Langdurige clients: Verwijder projecten als ze klaar zijn om geheugen vrij te maken
- Contextmanagers: Gebruik
withstatements (Python) of try/finally voor opruiming - Geheugenbewustzijn: De cache ruimt automatisch op bij 90% geheugendruk, maar expliciet ontladen is beter
- Gedeelde cache: Bedenk dat UI-gebruikers dezelfde projectstatus zien als jouw API-operaties