# JSON:API Conventions ## Content Type ```http Content-Type: application/vnd.api+json Accept: application/vnd.api+json ``` ## Query Parameters | Feature | Format | Example | |---------|--------|---------| | **Pagination** | `page[number]`, `page[size]` | `?page[number]=2&page[size]=20` | | **Filtering** | `filter[field]`, `filter[field__lookup]` | `?filter[status]=FAIL&filter[inserted_at__gte]=2024-01-01` | | **Sorting** | `sort` (prefix `-` for desc) | `?sort=-inserted_at,name` | | **Sparse fields** | `fields[type]` | `?fields[providers]=id,alias,uid` | | **Includes** | `include` | `?include=provider,scan` | | **Search** | `filter[search]` | `?filter[search]=production` | ## Filter Naming | Lookup | Django Filter | JSON:API Query | |--------|--------------|----------------| | Exact | `field` | `filter[field]=value` | | Contains | `field__icontains` | `filter[field__icontains]=val` | | In list | `field__in` | `filter[field__in]=a,b,c` | | Greater/equal | `field__gte` | `filter[field__gte]=2024-01-01` | | Less/equal | `field__lte` | `filter[field__lte]=2024-12-31` | | Related field | `relation__field` | `filter[provider_id]=uuid` | ## Request Format ```json { "data": { "type": "providers", "attributes": { "provider": "aws", "uid": "123456789012", "alias": "Production" } } } ``` ## Response Format ```json { "data": { "type": "providers", "id": "550e8400-e29b-41d4-a716-446655440000", "attributes": { "provider": "aws", "uid": "123456789012", "alias": "Production", "inserted_at": "2024-01-15T10:30:00Z" }, "relationships": { "provider_groups": { "data": [{"type": "provider-groups", "id": "..."}] } }, "links": { "self": "/api/v1/providers/550e8400-e29b-41d4-a716-446655440000" } }, "meta": { "version": "v1" } } ``` ## Error Response Format ```json { "errors": [ { "detail": "Error message here", "status": "400", "source": {"pointer": "/data/attributes/field_name"}, "code": "error_code" } ] } ``` ## Resource Naming Rules - Use **lowercase kebab-case** (hyphens, not underscores) - Use **plural nouns** for collections - Resource name in `JSONAPIMeta` MUST match URL path segment | Model | resource_name | URL Path | |-------|---------------|----------| | `Provider` | `providers` | `/api/v1/providers` | | `ProviderGroup` | `provider-groups` | `/api/v1/provider-groups` | | `ProviderSecret` | `provider-secrets` | `/api/v1/providers/secrets` | | `ComplianceOverview` | `compliance-overviews` | `/api/v1/compliance-overviews` | | `AttackPathsScan` | `attack-paths-scans` | `/api/v1/attack-paths-scans` | | `TenantAPIKey` | `api-keys` | `/api/v1/api-keys` | | `MuteRule` | `mute-rules` | `/api/v1/mute-rules` | ## URL Endpoints | Operation | Method | URL Pattern | |-----------|--------|-------------| | List | GET | `/{resources}` | | Create | POST | `/{resources}` | | Retrieve | GET | `/{resources}/{id}` | | Update | PATCH | `/{resources}/{id}` | | Delete | DELETE | `/{resources}/{id}` | | Relationship | * | `/{resources}/{id}/relationships/{relation}` | | Nested list | GET | `/{parent}/{parent_id}/{resources}` |