From b9efa459d77fc8dfa3886240d16bbdf3e048a6e6 Mon Sep 17 00:00:00 2001 From: Adam Sachs Date: Tue, 19 Sep 2023 18:37:52 -0400 Subject: [PATCH] avoid n+1 queries on bulk `GET /system` endpoint (#4120) --- CHANGELOG.md | 1 + src/fides/api/api/v1/endpoints/system.py | 4 ++-- src/fides/api/schemas/system.py | 24 +++++++++++++++++++----- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0853760a15..1b5528c806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ The types of changes are: ### Fixed - Allows CDN to cache empty experience responses from fides.js API [#4113](https://github.com/ethyca/fides/pull/4113) +- Avoid un-optimized query pattern in bulk `GET /system` endpoint [#4120](https://github.com/ethyca/fides/pull/4120) ## [2.20.0](https://github.com/ethyca/fides/compare/2.19.1...2.20.0) diff --git a/src/fides/api/api/v1/endpoints/system.py b/src/fides/api/api/v1/endpoints/system.py index d4b965a639..253bb4629a 100644 --- a/src/fides/api/api/v1/endpoints/system.py +++ b/src/fides/api/api/v1/endpoints/system.py @@ -50,7 +50,7 @@ from fides.api.schemas.connection_configuration.saas_config_template_values import ( SaasConnectionTemplateValues, ) -from fides.api.schemas.system import SystemResponse +from fides.api.schemas.system import BasicSystemResponse, SystemResponse from fides.api.util.api_router import APIRouter from fides.api.util.connection_util import ( connection_status, @@ -361,7 +361,7 @@ async def create( scopes=[SYSTEM_READ], ) ], - response_model=List[SystemResponse], + response_model=List[BasicSystemResponse], name="List", ) async def ls( # pylint: disable=invalid-name diff --git a/src/fides/api/schemas/system.py b/src/fides/api/schemas/system.py index 731e73ebcb..76545270ee 100644 --- a/src/fides/api/schemas/system.py +++ b/src/fides/api/schemas/system.py @@ -20,9 +20,25 @@ class PrivacyDeclarationResponse(PrivacyDeclaration): cookies: Optional[List[Cookies]] = [] -class SystemResponse(System): - """Extension of base pydantic model to include additional fields like `privacy_declarations`, connection_config fields - and cookies in responses""" +class BasicSystemResponse(System): + """ + Extension of base pydantic model to include additional fields on the DB model that + are relevant in API responses. + + This is still meant to be a "lightweight" model that does not reference relationships + that may require additional querying beyond the `System` db table. + """ + + created_at: datetime + + +class SystemResponse(BasicSystemResponse): + """Extension of base pydantic response model to include additional relationship fields that + may require extra DB queries, like `privacy_declarations`, connection_config fields and cookies. + + This response model is generally useful for an API that returns a detailed view of _single_ + System record. Attempting to return bulk results with this model can lead to n+1 query issues. + """ privacy_declarations: List[PrivacyDeclarationResponse] = Field( description=PrivacyDeclarationResponse.__doc__, @@ -38,8 +54,6 @@ class SystemResponse(System): cookies: Optional[List[Cookies]] = [] - created_at: datetime - class SystemHistoryResponse(BaseModel): """Response schema for a single system history entry"""