diff --git a/website/docs/contributing/ADRs/ADRs.md b/website/docs/contributing/ADRs/ADRs.md index d213083a37..ff307054b1 100644 --- a/website/docs/contributing/ADRs/ADRs.md +++ b/website/docs/contributing/ADRs/ADRs.md @@ -26,6 +26,7 @@ We are in the process of defining ADRs for the back end. At the time of writing * [POST/PUT API payload](./back-end/POST-PUT-api-payload.md) * [Specificity in database column references](./back-end/specificity-db-columns.md) * [Write model vs Read models](./back-end/write-model-vs-read-models.md) +* [Frontend API Design](./back-end/frontend-api-design.md) ## Front-end ADRs diff --git a/website/docs/contributing/ADRs/back-end/frontend-api-design.md b/website/docs/contributing/ADRs/back-end/frontend-api-design.md new file mode 100644 index 0000000000..e2dec01124 --- /dev/null +++ b/website/docs/contributing/ADRs/back-end/frontend-api-design.md @@ -0,0 +1,34 @@ +--- +title: "ADR: Frontend API design" +--- + +## Background + +Previous version of the Frontend API (known as proxy API) had memory and I/O issues when a large number of tokens was used. + +To better understand how it worked you need to know that Frontend API is Unleash Node SDK exposed over the API. +Node SDK allows to plug in a custom repository so that it can fetch the toggles from a database instead of making remote HTTP calls. + +Every time a new Frontend API token was used we created a new SDK client with its own proxy repository. Proxy repository was fetching +the flags for a project and environment extracted from a token. +Every time there was a revision ID change (e.g. after some flag changed the status) the repository was updating itself. +Since every token had a dedicated repository with 10 tokens we were making 10 DB calls on each change. +What's more each repository kept its own copy of the flags. What it means in practice is that two different tokens with the same +project and environments would store the same flags twice. + +[Frontend API before](/img/frontend-api-before.png) + +## Decision + +To address these challenges, we came up with a new design: + +[Frontend API after](/img/frontend-api-after.png) + +We decided to swap ProxyRepository with a drop-in replacement FrontendApiRepository. FrontendApiRepository doesn't store any flags on its own but always filters +the flags that we keep in a GlobalFrontendApiCache. The cache stores all the flags and updates on every revision ID change. + +Consequences: +* memory improvements: for a large number of tokens the memory footprint is reduced since we only store one copy of each flag in the cache and every repository +filters the data that it needs for a given project and environment obtained from the token +* I/O improvements: for a large number of tokens the number of DB calls is reduced to one per revision ID update since only the cache needs to be updated + diff --git a/website/static/img/frontend-api-after.png b/website/static/img/frontend-api-after.png new file mode 100644 index 0000000000..8b730f4062 Binary files /dev/null and b/website/static/img/frontend-api-after.png differ diff --git a/website/static/img/frontend-api-before.png b/website/static/img/frontend-api-before.png new file mode 100644 index 0000000000..d01df44401 Binary files /dev/null and b/website/static/img/frontend-api-before.png differ