Ontwerp een REST API die het Query by Example (QBE) patroon gebruikt voor flexibele query's.
description
Het gebruik van het QBE-patroon maakt het query's intuïtiever, waardoor gebruikers zoekcriteria op een natuurlijke manier kunnen specificeren. Dit kan leiden tot een hogere tevredenheid bij clients en minder complexiteit bij het opstellen van query's.
prompt
try_prompt
Help me een REST API ontwerpen die het Query by Example (QBE) patroon implementeert, waardoor clients query-criteria kunnen specificeren via voorbeeldobjecten. Mijn API-doel is {{api_purpose}}. Beschrijf hoe ik mijn endpoin ... more
generate_helper
...
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een voorstel voor het ontwerpen van een REST API die Query by Example (QBE) gebruikt voor beheer van gebruikersaccounts en profielen.
**Algemene structuur en principes**
- **Endpoint-structuur:**
- `/gebruikers` voor het beheren van gebruikersaccounts
- `/gebruikers/query` voor het uitvoeren van QBE-zoekopdrachten
- **Query-gegevens:**
Clients sturen een voorbeeldobject dat de criteria bevat.
Bijvoorbeeld: een JSON-object waarin velden worden ingevuld om te filteren.
- **Werking:**
- Het server-side systeem interpreteert de niet-nul of ingevulde velden als filters.
- Niet ingevulde velden worden genegeerd.
- Voor complexe voorwaarden kunnen extra velden of structuren worden gebruikt.
---
### 1. Structuur van de API-endpoints
| Methode | Endpoint | Beschrijving |
|---------|----------------------|--------------------------------------------------------|
| GET | `/gebruikers` | Haalt alle gebruikers op (optioneel met query-parameters) |
| POST | `/gebruikers/query` | Voert een QBE-query uit op basis van het voorbeeldobject |
**Aanbevolen:**
Gebruik POST voor de query, omdat je complexe JSON-criteria kunt sturen, wat niet goed gaat met GET-parameters.
---
### 2. Query-voorbeeld (Request)
**Voorbeeld van een query om alle gebruikers te vinden met de naam "Jan" en een leeftijd groter dan 30:**
```json
POST /gebruikers/query
Content-Type: application/json
{
"naam": "Jan",
"leeftijd": { "$gt": 30 }
}
```
**Uitleg:**
- Velden met eenvoudige waarden (zoals `"naam": "Jan"`) worden op gelijkheid vergeleken.
- Velden met een object zoals `{"$gt": 30}` geven een voorwaarde aan (hier: groter dan 30).
---
### 3. Ondersteunde datatypes en voorwaarden
| Type veld | Voorbeeldwaarde | Mogelijke voorwaarden | Opmerking |
|------------------|-----------------------------------|-----------------------------------------------------|---------------------------------------------------------|
| String | `"gebruikersnaam": "jan"` | gelijkheid (`"jan"`), kan uitgebreid worden met `$contains`, `$startsWith` etc. | Basis gelijkheid, uitbreidbaar voor tekstmatch |
| Number (integer/double) | `"leeftijd": 25` | `$gt`, `$gte`, `$lt`, `$lte`, `$eq` (default) | Voor numerieke vergelijkingen |
| Boolean | `"actief": true` | gelijkheid (`true`/`false`) | - |
| Datum/tijd | `"geboortedatum": { "$lt": "2000-01-01" }` | `$gt`, `$gte`, `$lt`, `$lte`, `$eq` | ISO 8601 formaat (`YYYY-MM-DD`) |
| Array velden | `"rollen": { "$contains": "admin" }` | `$contains`, `$in`, `$all` | Voor velden die lijsten bevatten |
---
### 4. Voorbeeld antwoord (Response)
**Succesvolle query:**
```json
{
"resultaten": [
{
"id": 123,
"gebruikersnaam": "janedoe",
"naam": "Jane Doe",
"leeftijd": 35,
"actief": true,
"geboortedatum": "1988-05-12",
"rollen": ["user", "admin"]
},
{
"id": 456,
"gebruikersnaam": "johndoe",
"naam": "John Doe",
"leeftijd": 40,
"actief": true,
"geboortedatum": "1983-03-22",
"rollen": ["user"]
}
],
"totaal": 2
}
```
**Geen resultaten:**
```json
{
"resultaten": [],
"totaal": 0
}
```
---
### 5. Extra overwegingen
- **Validatie:**
Valideer dat voorwaarden correct zijn (bijvoorbeeld, `$gt` wordt gebruikt met numerieke waarden).
- **Extensibility:**
Je kunt extra zoekoperatoren toevoegen zoals `$startsWith`, `$endsWith`, `$not`, `$or`, `$and`.
- **Documentatie:**
Zorg dat je documenteert welke operators ondersteund worden en hoe ze gebruikt worden.
---
### Samenvatting
- Gebruik een **POST** endpoint `/gebruikers/query` die een JSON-voorbeeld bevat.
- Velden met eenvoudige waarden worden op gelijkheid gezocht.
- Velden kunnen complexe voorwaarden bevatten met operator-objecten.
- Ondersteun verschillende datatypes en operatoren voor flexibele queries.
Met deze aanpak kunnen clients op een flexibele, voorbeeld-gebaseerde manier zoeken naar gebruikersprofielen.
Heeft u nog verdere wensen of voorbeelden nodig?
provider: deepseek
model: deepseek-chat
Zeker, ik help je graag een REST API te ontwerpen volgens het Query by Example (QBE) patroon voor gebruikersaccount- en profielbeheer. Hier is een complete uitwerking:
## API Structuur
### Basis Endpoints
```
GET /api/users - Zoek gebruikers op voorbeeld
POST /api/users/search - Zoek gebruikers met complexe voorbeelden
GET /api/users/{id} - Haal specifieke gebruiker op
POST /api/users - Maak nieuwe gebruiker
PUT /api/users/{id} - Update gebruiker
DELETE /api/users/{id} - Verwijder gebruiker
```
## QBE Implementatie
### 1. Query Parameters Approach (Eenvoudige queries)
```http
GET /api/users?email=voorbeeld@domain.com&status=ACTIEF&age=25
```
### 2. Request Body Approach (Complexe queries)
```http
POST /api/users/search
Content-Type: application/json
```
## Data Types en Condities Afhandeling
### Ondersteunde operatoren:
- **Gelijkheid**: `{ "veld": "waarde" }`
- **Vergelijkingen**: `{ "veld": { "gt": 18, "lt": 65 } }`
- **Lijst operatoren**: `{ "veld": { "in": ["waarde1", "waarde2"] } }`
- **String matching**: `{ "veld": { "like": "john%" } }`
- **Null checks**: `{ "veld": null }`
## Voorbeeld Request/Response Formats
### Voorbeeld 1: Eenvoudige gebruikersquery
**Request:**
```http
POST /api/users/search
Content-Type: application/json
{
"voorbeeld": {
"email": "admin@bedrijf.nl",
"role": "ADMIN",
"actief": true
},
"paginering": {
"pagina": 0,
"grootte": 20
},
"sortering": [
{ "veld": "aanmaakDatum", "richting": "DESC" }
]
}
```
**Response:**
```http
HTTP/1.1 200 OK
Content-Type: application/json
{
"content": [
{
"id": "usr-12345",
"gebruikersnaam": "jansen_admin",
"email": "admin@bedrijf.nl",
"voornaam": "Jan",
"achternaam": "Jansen",
"role": "ADMIN",
"actief": true,
"aanmaakDatum": "2024-01-15T10:30:00Z",
"laatstBijgewerkt": "2024-03-20T14:22:00Z",
"profiel": {
"telefoon": "+31612345678",
"afdeling": "IT",
"functie": "Systeembeheerder"
}
}
],
"pagina": {
"nummer": 0,
"grootte": 20,
"totaalElementen": 1,
"totaalPaginas": 1
}
}
```
### Voorbeeld 2: Geavanceerde query met voorwaarden
**Request:**
```http
POST /api/users/search
Content-Type: application/json
{
"voorbeeld": {
"role": { "in": ["USER", "MODERATOR"] },
"actief": true,
"aanmaakDatum": {
"gt": "2024-01-01T00:00:00Z",
"lt": "2024-03-01T00:00:00Z"
},
"profiel": {
"afdeling": "Verkoop",
"functie": { "like": "Manager%" }
}
},
"paginering": {
"pagina": 0,
"grootte": 50
}
}
```
### Voorbeeld 3: Query met null-check en string matching
**Request:**
```http
POST /api/users/search
Content-Type: application/json
{
"voorbeeld": {
"email": { "like": "%@gmail.com" },
"profiel": {
"telefoon": null,
"functie": { "ne": "Stagiair" }
}
}
}
```
## Foutafhandeling
**Error Response:**
```http
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"fout": "VALIDATIE_FOUT",
"bericht": "Ongeldige query parameters",
"details": [
{
"veld": "age",
"bericht": "Leeftijd moet een positief getal zijn"
}
],
"tijdstip": "2024-03-21T10:15:30Z"
}
```
## Implementatie Tips
### 1. Beveiliging
```java
// Valideer query parameters om injectie te voorkomen
public class UserQueryValidator {
public void validate(UserExample example) {
// Limiteer maximum diepte van geneste objecten
// Whitelist toegestane velden
// Valideer datatypes en formaten
}
}
```
### 2. Database Mapping (voorbeeld)
```sql
-- Dynamische WHERE clause generatie op basis van QBE
SELECT * FROM users u
LEFT JOIN profiles p ON u.id = p.user_id
WHERE
u.email LIKE '%@gmail.com'
AND u.role IN ('USER', 'MODERATOR')
AND u.created_at > '2024-01-01'
AND p.department = 'Verkoop'
```
### 3. Response Filtering
```http
GET /api/users?fields=id,email,voornaam,profiel.functie
```
## Best Practices
1. **Consistente naamgeving**: Gebruik camelCase voor alle velden
2. **Documentatie**: Documenteer alle ondersteunde operatoren en velden
3. **Rate limiting**: Implementeer rate limiting voor search endpoints
4. **Caching**: Overweeg caching voor veelgebruikte queries
5. **Indexering**: Optimaliseer database indexen voor veelgebruikte zoekvelden
Deze aanpak biedt flexibiliteit voor clients terwijl de API eenvoudig te gebruiken en te onderhouden blijft.

