Calling external API from forge app - CORS issue and is that "from URL" changing?

AD 1.

What is this uuid? Is that changing?

In my experience the UUID doesn’t change between deployments. Once the app is installed, the ID stays the same and you can modify your CORS rules to allow traffic from Forge iframes (that’s how I’ve retrieved the UUID for my app).

The only exception to that is that if you’re using sandbox, and have a staging version of your app installed, then this one will have a different URL, so you need to account in your CORS for that too. But this is just different UUID per fresh installation, not new UUID every time.

The pain point is that this iframe URL/UUID isn’t known ahead of time, so if you need to bootstrap it without causing any disruptions (or shipping broken apps) you could probably install your app first with modules that return empty markup, note down iframe URL, modify your external backend CORS rules, then it should just work. Take this paragraph with some caution though, as our app is tailored just for our need, so I can’t guarantee the same will apply to “It will be a different value for every confluence instance that has the app installed?”.

AD 2.

Is there a best practice to deal with those CORS issues? For example, should I do the request from the frontend resource or from the backend with the fetch from @forge/api?

CORS should only apply to browser-sent requests. If you were to use fetch directly on the backend you should not face the CORS issues. You probably don’t need to use @forge/api if you intend to communicate with external APIs (since these packages are more directed towards usage with Atlassian APIs). In our case we use regular fetch to call our own external APIs just fine.