Skip to content

BFF: send API calls through the backend's proxy, and drop apiBaseUrl - #150

Merged
brionmario merged 1 commit into
thunder-id:mainfrom
brionmario:bff-api-on-proxy
Oct 30, 2026
Merged

brionmario merged 1 commit into
thunder-id:mainfrom
brionmario:bff-api-on-proxy

Conversation

@brionmario

Copy link
Copy Markdown
Member

Purpose

In backend mode (endpoints.backend) the backend is the one that knows where the API is: it maps its proxy to the API from its own configuration and attaches the token. #149 still made the app name the API's address in endpoints.backend.apiBaseUrl, so the SDK could recognise absolute API URLs and rewrite them to the proxy. That puts a server-side detail in the frontend's config. With this change the frontend only knows baseUrl (the backend) and proxy.

Approach

  • No apiBaseUrl: endpoints.backend.apiBaseUrl and resolveApiBaseUrl() are removed.
  • The SDK's own API requests (/users/me, /users/me/meta, the management APIs) are built on the backend's proxy, resolved against baseUrl: ${baseUrl}${proxy}/users. The new resolveRequestBaseUrl() returns that base in backend mode, and baseUrl otherwise. The React and Vue context baseUrl, which the account and management hooks build on, follows it. endpoints overrides still win.
  • BackendClient.toProxyUrl:
    • a URL already on the proxy, as a path or a full URL, is sent as it is, with no second prefix;
    • any other path (/users) goes under the proxy;
    • any other absolute URL is refused, since it can't be sent with the session's credentials;
    • the bypass is unchanged.
  • Redirect mode is unchanged.

Related Issues

  • N/A

Related PRs

Checklist

  • Followed the contribution guidelines.
  • Manual test round performed and verified.
  • Documentation provided. (Add links if there are any)
  • Tests provided. (Add links if there are any)
    • Unit Tests (resolveBackendEndpoints.test.ts, BackendClient.test.ts, ThunderIDBrowserClient.backend.test.ts, ThunderIDProvider.test.tsx)
    • Integration Tests
  • Breaking changes. (Fill if applicable)
    • Breaking changes section filled.
    • breaking change label added.
  • Cross-SDK parity. Exactly one of parity/prs-raised or parity/prs-not-needed added.
    • If parity/prs-raised, the port links are posted as a reply on the parity check's comment.

Security checks

  • Followed secure coding standards.
  • Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets.

In backend mode the backend maps its proxy to the API from its own
configuration, so the app doesn't need the API's address.
endpoints.backend.apiBaseUrl and resolveApiBaseUrl() are removed.

- The SDK builds its own API requests, such as /users/me and the
  management APIs, on the backend's proxy, resolved against baseUrl:
  resolveRequestBaseUrl() returns it in backend mode, and baseUrl
  otherwise. The React and Vue context baseUrl, which the account and
  management hooks build on, follows it.
- BackendClient.toProxyUrl sends a URL already on the proxy as it is,
  as a path or a full URL, with no second prefix. Any other path goes
  under the proxy, and any other absolute URL is refused. The bypass is
  unchanged.

Signed-off-by: Brion <info@brionmario.com>
@brionmario brionmario added the parity/prs-raised Ports exist in the other SDKs, or are recorded as not applying there label Oct 30, 2026
@coderabbitai

coderabbitai Bot commented Oct 30, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

🔀 Cross-SDK feature parity, ports raised

This pull request is labelled parity/prs-raised, so the capability it introduces is expected in the other ThunderID SDKs as well.

Ports (DO NOT EDIT)

  • thunder-id/ios-sdks, iOS => #41
  • thunder-id/android-sdks, Android => #49
  • thunder-id/flutter-sdks, Flutter => #62

3 of 3 sibling SDKs accounted for.

Every sibling SDK is accounted for.

The contract is in the SDK development specification.

@brionmario
brionmario merged commit 3f1600c into thunder-id:main Oct 30, 2026
7 of 8 checks passed
brionmario added a commit to brionmario/thunderid that referenced this pull request Oct 30, 2026
Moves @thunderid/react to 1.11.3 and @thunderid/react-router to 1.10.3,
which bring @thunderid/browser 1.9.3 and @thunderid/javascript 1.10.3.

They include three backend-mode (endpoints.backend) changes:

- thunder-id/javascript-sdks#148: useGrantedPermissions reads the
  granted permissions from the backend's session (scope) instead of
  decoding an access token. A console signed in through a backend (BFF)
  then shows the pages its permissions allow, instead of "Nothing to
  manage".
- thunder-id/javascript-sdks#149: the top-level baseUrl is the backend,
  and endpoint paths resolve against it.
- thunder-id/javascript-sdks#150: the SDK's API calls go to the
  backend's proxy (baseUrl + proxy), so the frontend never needs the
  API's own address; the backend maps the proxy to it.

None of them changes redirect mode, which the consoles use by default.

Signed-off-by: Brion <info@brionmario.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

parity/prs-raised Ports exist in the other SDKs, or are recorded as not applying there

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants