7.5 KiB
7.5 KiB
type, category, name, version, status, tags, dependencies, emits, subscribes
| type | category | name | version | status | tags | dependencies | emits | subscribes | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| step | api | Advoware Proxy GET | 1.0.0 | active |
|
|
Advoware Proxy GET Step
Zweck
Universeller REST-API-Proxy für GET-Requests an die Advoware API mit automatischer Authentifizierung und Token-Management.
Kontext
Die Advoware API verwendet HMAC-512 Authentifizierung, die komplex und fehleranfällig ist. Dieser Proxy abstrahiert die Authentifizierung und bietet einen einfachen HTTP-Endpunkt für GET-Requests. Clients müssen sich nicht um Token-Management, Signatur-Generierung oder Error-Handling kümmern.
Technische Spezifikation
Config
{
'type': 'api',
'name': 'Advoware Proxy GET',
'description': 'Universal proxy for Advoware API (GET)',
'path': '/advoware/proxy',
'method': 'GET',
'emits': [],
'flows': ['advoware']
}
Input
- HTTP Method: GET
- Path:
/advoware/proxy - Query Parameters:
endpoint(required, string): Advoware API endpoint path (ohne Base-URL)- Alle weiteren Parameter werden an Advoware weitergeleitet
Beispiel:
GET /advoware/proxy?endpoint=employees&limit=10&offset=0
Output
Success Response (200):
{
"status": 200,
"body": {
"result": {
// Advoware API Response
}
}
}
Error Response (400):
{
"status": 400,
"body": {
"error": "Endpoint required as query param"
}
}
Error Response (500):
{
"status": 500,
"body": {
"error": "Internal server error",
"details": "Error message from Advoware or network"
}
}
Events
- Emits: Keine
- Subscribes: Keine
Verhalten
Ablauf
- Extrahiere
endpointParameter aus Query-String - Validiere dass
endpointvorhanden ist - Extrahiere alle anderen Query-Parameter (außer
endpoint) - Erstelle AdvowareAPI-Instanz
- Rufe
api_call()mit GET-Methode auf- Intern: Token wird aus Redis geladen oder neu geholt
- Intern: HMAC-Signatur wird generiert
- Intern: Request wird an Advoware gesendet
- Gebe Response als JSON zurück
Fehlerbehandlung
Fehlender endpoint Parameter:
- HTTP 400 mit Fehlermeldung
- Request wird nicht an Advoware weitergeleitet
Advoware API Error:
- HTTP 500 mit Details
- Exception wird geloggt mit Stack-Trace
- Keine Retry-Logik (fail-fast)
Token Expired (401):
- Automatisch behandelt durch AdvowareAPI Service
- Neuer Token wird geholt und Request wiederholt
- Transparent für Client
Network Error:
- HTTP 500 mit Details
- Exception wird geloggt
- Timeout nach
ADVOWARE_API_TIMEOUT_SECONDS(default: 30s)
Side Effects
- Keine Writes: GET-Request modifiziert keine Daten
- Token Cache: Liest aus Redis DB 1 (
advoware_access_token) - Logging: Schreibt INFO und ERROR logs in Motia Workbench
Abhängigkeiten
Services
- AdvowareAPI (
services/advoware.py): API-Clientapi_call(endpoint, method='GET', params, json_data=None)- Handhabt Authentifizierung, Token-Caching, Error-Handling
Redis Keys (gelesen via AdvowareAPI)
- DB 1:
advoware_access_token(string, TTL: 53min): Bearer Tokenadvoware_token_timestamp(string, TTL: 53min): Token Creation Time
Environment Variables
ADVOWARE_API_BASE_URL=https://www2.advo-net.net:90/
ADVOWARE_API_KEY=base64_encoded_key
ADVOWARE_APP_ID=your_app_id
ADVOWARE_USER=api_user
ADVOWARE_PASSWORD=secure_password
ADVOWARE_API_TIMEOUT_SECONDS=30
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB_ADVOWARE_CACHE=1
External APIs
- Advoware API: Alle GET-fähigen Endpoints
- Rate Limits: Unknown (keine offizielle Dokumentation)
Testing
Manual Test
# Test employee list
curl -X GET "http://localhost:3000/advoware/proxy?endpoint=employees&limit=5"
# Test appointments
curl -X GET "http://localhost:3000/advoware/proxy?endpoint=appointments?datum=2026-02-07"
# Test with error (missing endpoint)
curl -X GET "http://localhost:3000/advoware/proxy"
# Expected: 400 Bad Request
Expected Behavior
-
Success Case:
- Status: 200
- Body enthält
resultmit Advoware-Daten - Logs zeigen "Proxying request to Advoware: GET {endpoint}"
-
Error Case (missing endpoint):
- Status: 400
- Body:
{"error": "Endpoint required as query param"}
-
Error Case (Advoware down):
- Status: 500
- Body:
{"error": "Internal server error", "details": "..."} - Logs zeigen Error mit Stack-Trace
Monitoring
Logs
[INFO] Proxying request to Advoware: GET employees
[INFO] Using cached token
[ERROR] Proxy error: ConnectionTimeout
Metrics (potentiell)
- Request Count
- Response Time (avg, p95, p99)
- Error Rate
- Cache Hit Rate (Token)
Alerts
- Error Rate > 10% über 5 Minuten
- Response Time > 30s (Timeout-Grenze)
- Redis Connection Failed
Performance
Response Time
- Cached Token: 200-500ms (typisch)
- New Token: 1-2s (Token-Fetch + API-Call)
- Timeout: 30s (konfigurierbar)
Throughput
- No rate limit auf Motia-Seite
- Advoware API: Unknown rate limits
- Bottleneck: Advoware API Response-Zeit
Security
Secrets
- ❌ Keine Secrets im Code
- ✅ API Key über Environment Variable
- ✅ Token in Redis (lokaler Zugriff nur)
Authentication
- Client → Motia: Keine (TODO: API Key oder OAuth)
- Motia → Advoware: HMAC-512 + Bearer Token
Data Exposure
- GET-Requests lesen nur Daten
- Keine PII in Logs (nur Endpoint-Pfade)
- Response enthält alle Advoware-Daten (keine Filterung)
Änderungshistorie
| Version | Datum | Änderung |
|---|---|---|
| 1.0.0 | 2024-10-24 | Initiale Implementierung |
KI-Assistant Guidance
Typische Änderungen
1. Timeout erhöhen:
# In services/advoware.py, nicht im Step
Config.ADVOWARE_API_TIMEOUT_SECONDS = 60
2. Request-Parameter anpassen:
# Query-Parameter werden automatisch weitergeleitet
# Keine Code-Änderung nötig
3. Response-Transformation:
# Vor return:
result = await advoware.api_call(...)
transformed = transform_response(result) # Neue Funktion
return {'status': 200, 'body': {'result': transformed}}
4. Caching hinzufügen:
# Vor api_call:
cache_key = f'cache:{endpoint}:{params}'
cached = redis_client.get(cache_key)
if cached:
return {'status': 200, 'body': {'result': json.loads(cached)}}
# ... api_call ...
redis_client.set(cache_key, json.dumps(result), ex=300)
Don'ts
- ❌ Keine synchronen Blocking-Calls: Immer
awaitverwenden - ❌ Keine Hardcoded Credentials: Nur Environment Variables
- ❌ Keine unbehandelten Exceptions: Immer try-catch
- ❌ Kein Logging von Secrets: Keine Passwörter/Tokens loggen
Testing-Tipps
# Test mit verschiedenen Endpoints
curl "http://localhost:3000/advoware/proxy?endpoint=employees"
curl "http://localhost:3000/advoware/proxy?endpoint=appointments"
curl "http://localhost:3000/advoware/proxy?endpoint=cases"
# Test Error-Handling
curl "http://localhost:3000/advoware/proxy" # Missing endpoint
# Test mit vielen Parametern
curl "http://localhost:3000/advoware/proxy?endpoint=employees&limit=100&offset=0&sortBy=name"
Related Steps
- advoware_api_proxy_post_step.md - POST-Requests
- advoware_api_proxy_put_step.md - PUT-Requests
- advoware_api_proxy_delete_step.md - DELETE-Requests
Related Services
- services/advoware.py - API-Client Implementierung