Read frontend API_URL
environment variable at runtime
#3934
Labels
🕹 aspect: interface
Concerns end-users' experience with the software
🧰 goal: internal improvement
Improvement that benefits maintainers, not users
🟨 priority: medium
Not blocking but should be addressed soon
🧱 stack: frontend
Related to the Nuxt frontend
Problem
Because of the way Nuxt's build works,
process.env.API_URL
in theenv.ts
file is "baked" at build time, so that it statically references the value at build time:openverse/frontend/src/utils/env.ts
Line 1 in 697f62f
Despite this seeming not to be the case, when you investigate the built code:
It is actually baked into the Nuxt context:
This is complicated by the fact that we do not use Nuxt context to retrieve the default value for
baseUrl
, meaning we necessarily rely on static definitions, that Nuxt will overwrite.This documented and intentional Nuxt behaviour: https://v2.nuxt.com/docs/configuration-glossary/configuration-env/#processenv--
Description
To fix this, we could switch to using
publicRuntimeConfig
, which will read the environment variable at runtime. However, that makes things a big more complicated, because we'd be forced to rely on the Nuxt context$config
to retrieve the variable! That's very hard with the way we've written theapi-service.ts
module and created top-level calls tocreateApiService
that cannot reference runtime context.While that would be the "correct" solution, we can bypass the static injection of the variable at build time by using
process.env.API_URL
instead of the nuxtenv
setting'sapiUrl
. That would require a one-line change, and define the default where it's used, rather than in the global "env" context.The following patch would do that:
It (a) removes the
env.apiUrl
definition, which has the "baked in" feature, as described in the above section, and (b) changes thecreateApiService
function to use a new default that reads from the environment at runtime, falling back to the currently established default.This gets around the build-time injection of the value in the code, and makes it possible to point the built frontend to any API URL desired, just by using the
API_URL
environment variable.Alternatives
I mentioned the
publicRuntimeConfig
alternative. It is better in that it is more "nuxt-y" and would force us into a more maintainable pattern for our API service instance creation.However, I think the best and most flexible option, would be the following:
apiUrl
, use that.process.env.API_URL
is defined, use that.https://api.openverse.engineering/
as the absolute default.This is the best solution because it allows us to change the API url at any time we want for any environment, in order to test whatever API url we like. If we want to point the production frontend to the staging API, we can do so for ourselves without affecting anyone else. Likewise, if we want to default the staging frontend to point to the staging API, we can do that, while allowing developers to easily point the staging frontend to the production API by setting the session variable. Or if we don't want that default, we can individually point the staging frontend to the staging API whenver we want.
It's tremendously flexible, but would require a significant overhaul in our API request handling on the frontend. It's something we should do, but difficult to argue needs to be done, considering the effort it would take, and the fact that there is a usable workaround the achieves the main, immediate needs.
The text was updated successfully, but these errors were encountered: