Nested Resources & Authorization
Key Insights on Nested Resources
Authorization Best Practices
Permissions: Validate parent resource access rights
QuerySets: Scope visible child data
Clear Separation: "Can they access?" vs
## Key Insights on Nested Resources
### Authorization Best Practices
- **Permissions**: Validate parent resource access rights
- **QuerySets**: Scope visible child data
- **Clear Separation**: "Can they access?" vs "What can they access?"
### Sample Code Pattern
# permissions.py
class HasEntityAccess(BasePermission):
def has_permission(self, request, view):
return Entity.objects.filter(
id=view.kwargs['entity_pk'],
organization__members=request.user
).exists()
# views.py
class ProjectViewSet(ModelViewSet):
permission_classes = [IsAuthenticated, HasEntityAccess]
def get_queryset(self):
# Don't re-check access - permissions already did that
# Just scope to the parent
return Project.objects.filter(
entity_id=self.kwargs['entity_pk']
)
### Multi-tenant Organization Pattern
class OrgAccessMixin:
def get_organization(self):
return get_object_or_404(
Organization.objects.filter(members=self.request.user),
pk=self.kwargs['organization_pk']
)
class EntityAccessMixin(OrgAccessMixin):
def get_queryset(self):
return super().get_queryset().filter(
organization=self.get_organization()
)
### Performance Optimization Patterns
def get_queryset(self):
return Project.objects.filter(
entity_id=self.kwargs['entity_pk']
).select_related('entity') # Prevent N+1 queries
### Error Handling Best Practices
class NestedResourceNotFound(APIException):
status_code = 404
default_detail = "The requested nested resource does not exist"
## URL Path Considerations
- Avoid usernames in URLs (security, maintenance issues)
- Consider UUIDs or opaque IDs for production
- Use slugs only with proper constraints and generation
## Framework Notes
- DRF: Comprehensive but complex for nested resources
- Django Ninja: Modern alternative with cleaner pattern
### Performance Optimization Patterns
- **Select Related**: Optimize parent-child queries
def get_queryset(self):
return Project.objects.filter(
entity_id=self.kwargs['entity_pk']
).select_related('entity') # Prevent N+1 queries
### Error Handling Best Practices
- **Graceful Failures**: Custom exception handlers for nested resource scenarios
- **Clear Error Messages**: Distinguish between "not found" and "no access"
class NestedResourceNotFound(APIException):
status_code = 404
default_detail = "The requested nested resource does not exist"
### Security Considerations
- **Resource Enumeration Prevention**: Avoid revealing existence of resources
- **Rate Limiting**: Implement nested-path specific rate limits
- **Audit Logging**: Track access patterns across resource hierarchies
## Testing Strategy
- Unit test both positive and negative permission scenarios
- Integration tests for complete nested resource flows
- Performance tests for N+1 query preventionBy Eduarda Ferreira