slogan3

Ontwerp een REST API met het State Machine Design Pattern voor Workflowbeheer

description

Helpt gebruikers bij het ontwerpen van API's die complexe workflows beheren met duidelijke statusbeheer, waardoor fouten door ongeldige overgangen worden verminderd en de onderhoudbaarheid verbetert. Biedt praktische richtlijnen voor het modelleren van statussen en overgangen, essentieel voor API's die processen zoals orderbeheer, ticketing of goedkeuringssystemen afhandelen.

prompt

Help mij een REST API te ontwerpen die het State Machine Design Pattern toepast om workflows te beheren met gedefinieerde statussen en overgangen. Mijn API doel: <voer het doel van je API in>. Beschrijf hoe ik de statussen, overgangen en ...

try_prompt

generate_helper
disclaimerOnPageApi

ai_answers

provider: openai
model: gpt-4.1-nano
Hier is een uitgebreide beschrijving van het ontwerpen van een REST API voor orderverwerking gebaseerd op het State Machine Design Pattern, inclusief modellen, endpoints, request- en response-formaten, en best practices: 1. Modellering van Statussen, Overgangen en Acties a. States (Statussen): Definieer een enumeratie van mogelijke statussen: - in_afwachting - goedgekeurd - verzonden - geleverd b. Overgangen: Beperk overgangen volgens logica, bijvoorbeeld: - in_afwachting → goedgekeurd - goedgekeurd → verzonden - verzonden → geleverd c. Acties: Bij elke overgang kunnen acties horen, zoals: - goedkeuren order - verzenden order - bevestigen levering 2. Endpoints en Functionaliteiten a. Orders Resources - GET /orders/{orderId} Haalt de details van een order op, inclusief status en geschiedenis. - POST /orders Creëert een nieuwe order in de initiële status ('in_afwachting'). - PATCH /orders/{orderId}/status Wijzigt de status van een order, mits de overgang geldig is. - GET /orders/{orderId}/history Opvragen van de transactiegeschiedenis van statuswijzigingen. b. Voorbeeld Endpoint-structuur ```plaintext GET /orders/{orderId} POST /orders PATCH /orders/{orderId}/status GET /orders/{orderId}/history ``` 3. Request- en Response-Format a. Nieuwe order aanmaken (POST /orders) Request: ```json { "klantId": "K12345", "producten": [ {"productId": "P001", "aantal": 2}, {"productId": "P002", "aantal": 1} ] } ``` Response: ```json { "orderId": "O123456", "status": "in_afwachting", "aangemaaktOp": "2023-10-23T14:55:00Z", "statusGeschiedenis": [ { "status": "in_afwachting", "timestamp": "2023-10-23T14:55:00Z", "actie": "Order aangemaakt" } ] } ``` b. Statuswijziging (PATCH /orders/{orderId}/status) Request: ```json { "nieuwStatus": "goedgekeurd" } ``` Response: ```json { "orderId": "O123456", "oudestatus": "in_afwachting", "nieuwestatus": "goedgekeurd", "timestamp": "2023-10-23T15:00:00Z", "message": "Status succesvol gewijzigd" } ``` 4. Validatie en Afhandeling van Ongeldige Overgangen - Controleer of de gevraagde overgang geldig is volgens het state machine model. - Bij ongeldige overgang: ```json { "error": "Ongeldige statuswijziging", "huidigeStatus": "in_afwachting", "proposedStatus": "verzonden", "beschrijving": "Deze overgang is niet toegestaan zonder goedkeuring." } ``` - API moet een passende HTTP-statuscode geven, bijvoorbeeld 400 Bad Request. 5. Best Practices voor Consistentie en Traceerbaarheid - Gebruik duidelijke en consistente status- en actie-velden. - Log elke statuswijziging met timestamp, oude en nieuwe status, en actie. - Voeg een 'statusGeschiedenis' toe aan elke order voor audit-doeleinden. - Maak gebruik van idempotente bewerkingen waar mogelijk (bijvoorbeeld bij statuswijzigingen). - Documenteer alle mogelijke statussen en overgangen in de API-documentatie. - Overweeg het gebruik van HATEOAS om clients te begeleiden bij beschikbare acties afhankelijk van de huidige status. 6. Samenvatting van het State Machine Model - States: - in_afwachting - goedgekeurd - verzonden - geleverd - Valid Overgangen: - in_afwachting → goedgekeurd - goedgekeurd → verzonden - verzonden → geleverd - Acties kunnen worden getriggerd afhankelijk van de status. Met dit ontwerp kan je workflowbeheer helder, traceerbaar en robuust worden ingericht conform het State Machine Pattern binnen een REST API.
provider: deepseek
model: deepseek-chat
Zeker! Ik help je bij het ontwerpen van een REST API voor orderverwerking met het State Machine Pattern. Hier is een complete uitwerking: ## 1. Status en Overgangen Model ### Statussen ```json { "statuses": ["PENDING", "APPROVED", "SHIPPED", "DELIVERED", "CANCELLED"] } ``` ### Toegestane overgangen ```json { "transitions": { "PENDING": ["APPROVED", "CANCELLED"], "APPROVED": ["SHIPPED", "CANCELLED"], "SHIPPED": ["DELIVERED"], "DELIVERED": [], "CANCELLED": [] } } ``` ## 2. Database Model ```sql -- Orders tabel CREATE TABLE orders ( id UUID PRIMARY KEY, customer_id UUID NOT NULL, total_amount DECIMAL(10,2), current_status VARCHAR(50) NOT NULL, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Status geschiedenis tabel CREATE TABLE order_status_history ( id UUID PRIMARY KEY, order_id UUID REFERENCES orders(id), from_status VARCHAR(50), to_status VARCHAR(50) NOT NULL, transition_reason TEXT, performed_by UUID, created_at TIMESTAMP DEFAULT NOW() ); ``` ## 3. API Endpoints ### 3.1 Order aanmaken **POST** `/api/orders` ```json { "customer_id": "123e4567-e89b-12d3-a456-426614174000", "items": [ {"product_id": "prod-001", "quantity": 2, "price": 25.50} ], "total_amount": 51.00 } ``` **Response:** ```json { "id": "123e4567-e89b-12d3-a456-426614174000", "customer_id": "123e4567-e89b-12d3-a456-426614174000", "current_status": "PENDING", "total_amount": 51.00, "created_at": "2024-01-15T10:30:00Z", "status_history": [] } ``` ### 3.2 Status overgang uitvoeren **POST** `/api/orders/{orderId}/transitions` ```json { "target_status": "APPROVED", "reason": "Betaling ontvangen", "performed_by": "user-123" } ``` **Response:** ```json { "order_id": "123e4567-e89b-12d3-a456-426614174000", "previous_status": "PENDING", "new_status": "APPROVED", "transition_time": "2024-01-15T11:00:00Z", "transition_id": "transition-001" } ``` ### 3.3 Order details ophalen **GET** `/api/orders/{orderId}` ```json { "id": "123e4567-e89b-12d3-a456-426614174000", "customer_id": "123e4567-e89b-12d3-a456-426614174000", "current_status": "APPROVED", "total_amount": 51.00, "created_at": "2024-01-15T10:30:00Z", "status_history": [ { "from_status": null, "to_status": "PENDING", "transition_time": "2024-01-15T10:30:00Z", "reason": "Order aangemaakt" }, { "from_status": "PENDING", "to_status": "APPROVED", "transition_time": "2024-01-15T11:00:00Z", "reason": "Betaling ontvangen" } ] } ``` ### 3.4 Beschikbare overgangen ophalen **GET** `/api/orders/{orderId}/available-transitions` ```json { "current_status": "APPROVED", "available_transitions": ["SHIPPED", "CANCELLED"] } ``` ## 4. State Machine Implementatie ### State Machine Klasse ```python class OrderStateMachine: def __init__(self): self.transitions = { 'PENDING': ['APPROVED', 'CANCELLED'], 'APPROVED': ['SHIPPED', 'CANCELLED'], 'SHIPPED': ['DELIVERED'], 'DELIVERED': [], 'CANCELLED': [] } def can_transition(self, from_status, to_status): return to_status in self.transitions.get(from_status, []) def get_available_transitions(self, current_status): return self.transitions.get(current_status, []) ``` ### Service Laag ```python class OrderService: def __init__(self): self.state_machine = OrderStateMachine() def transition_order(self, order_id, target_status, reason, user_id): order = self.get_order(order_id) if not self.state_machine.can_transition(order.current_status, target_status): raise InvalidTransitionError( f"Ongeldige overgang van {order.current_status} naar {target_status}" ) # Update order status previous_status = order.current_status order.current_status = target_status order.updated_at = datetime.utcnow() # Log status wijziging self.log_status_transition( order_id, previous_status, target_status, reason, user_id ) return order ``` ## 5. Foutafhandeling ### Custom Exceptions ```python class InvalidTransitionError(Exception): pass class OrderNotFoundError(Exception): pass ``` ### Error Response ```json { "error": "INVALID_TRANSITION", "message": "Ongeldige overgang van PENDING naar DELIVERED", "current_status": "PENDING", "available_transitions": ["APPROVED", "CANCELLED"], "timestamp": "2024-01-15T11:00:00Z" } ``` ## 6. Best Practices ### 6.1 Consistentie en ACID - Gebruik database transacties voor status updates - Implementeer optimistic locking met `version` veld - Valideer business rules voor elke overgang ### 6.2 Traceerbaarheid - Log alle status wijzigingen met reden en gebruiker - Implementeer audit logging - Bewaar complete status geschiedenis ### 6.3 Idempotentie ```python # Idempotente status overgang def transition_order(order_id, target_status, idempotency_key): if self.is_transition_processed(idempotency_key): return self.get_existing_transition(idempotency_key) # Verwerk overgang return self.process_transition(order_id, target_status, idempotency_key) ``` ### 6.4 CQRS Pattern - Scheid read en write operations - Gebruik materialized views voor status rapportages - Cache veelgebruikte queries ## 7. Event-Driven Architecture ### Status Change Events ```json { "event_type": "ORDER_STATUS_CHANGED", "order_id": "123e4567-e89b-12d3-a456-426614174000", "previous_status": "PENDING", "new_status": "APPROVED", "timestamp": "2024-01-15T11:00:00Z", "metadata": { "reason": "Betaling ontvangen", "user_id": "user-123" } } ``` ## 8. Security Considerations - Authenticatie en autorisatie voor status wijzigingen - Role-based access control voor verschillende overgangen - Rate limiting op status update endpoints - Input validatie en sanitization Deze architectuur biedt een robuuste foundation voor orderverwerking met duidelijke status overgangen, volledige traceerbaarheid en goede foutafhandeling.