Skip to content

feat: API_URL_PREFIX setting — let the SPA call a separately-mounted django-admin-rest-api (#559)#560

Merged
MartinCastroAlvarez merged 1 commit into
mainfrom
feat/api-url-prefix-setting-559
May 28, 2026
Merged

feat: API_URL_PREFIX setting — let the SPA call a separately-mounted django-admin-rest-api (#559)#560
MartinCastroAlvarez merged 1 commit into
mainfrom
feat/api-url-prefix-setting-559

Conversation

@MartinCastroAlvarez
Copy link
Copy Markdown
Owner

Closes #559.

Why

Today the SPA reaches the JSON API by an implicit convention: django_admin_react.urls inline-includes django-admin-rest-api at <spa-mount>/api/v1/, and the SPA derives its API base from request.path. Plug-and-play, but it locks the consumer into "API is under the SPA mount."

For shared deployments where one /api/ mount also serves django-admin-mcp-api and non-browser clients, the SPA needs to call that URL instead.

What

New optional DJANGO_ADMIN_REACT["API_URL_PREFIX"]:

DJANGO_ADMIN_REACT = {
    "API_URL_PREFIX": "/api/api/v1/",   # talk to the shared mount
}
  • Backend: urls.py skips the inline api/v1/ include when the override is set (no double-mount). views.py.SpaIndexView resolves the prefix (override or <mount>/api/v1/ default, trailing-slash-normalized) and injects it as <meta name="dar-api-prefix">.
  • Frontend: main.tsx reads the meta + passes apiPrefix to ApiClient; client.ts.url() uses it directly. When omitted, the client defaults to <mount>api/v1/ so existing consumers see no change.

Verification

  • Backend (test_spa_index.py): meta defaults to <mount>/api/v1/, honours the override verbatim, and adds a trailing slash if the consumer omits it. Full suite 45 passed.
  • Frontend (client.test.ts): override routes every request, missing-trailing-slash gets one, omitted prefix preserves the legacy URL. Full vitest 145 passed.

Tier 4-ish (backend + frontend, no contract surface change — additive setting + additive meta tag).

🤖 Generated with Claude Code

…API (#559)

Today the SPA reaches the JSON API by an *implicit* convention:
`django_admin_react.urls` inline-includes `django-admin-rest-api` at
`<spa-mount>/api/v1/`, and the SPA derives its API base from
`request.path`. That's plug-and-play but locks the consumer into the
assumption that the API lives **under** the SPA's mount.

A new optional `DJANGO_ADMIN_REACT["API_URL_PREFIX"]` setting lets a
consumer point the SPA at a separately-mounted `django-admin-rest-api`
so the API can be a single shared mount (also reachable by
`django-admin-mcp-api` or non-browser clients), and the SPA hits
**that** URL instead of the inline include.

## What changes
- `conf.py`: new `"API_URL_PREFIX": None` default. Unset → today's
  behaviour, unchanged.
- `urls.py`: when `API_URL_PREFIX` is set, the inline
  `include("django_admin_rest_api.api.urls")` is **skipped** so there's
  no double-mount.
- `views.py`: `_resolve_api_prefix(request)` resolves the prefix
  (consumer override → trailing-slash-normalized; else
  `<mount>/api/v1/`), injected into the SPA template.
- `templates/admin_react/index.html`: new
  `<meta name="dar-api-prefix" content="…">`.
- Frontend `main.tsx`: reads the meta + passes `apiPrefix` to the
  `ApiClient`.
- Frontend `client.ts`: `ApiClient` accepts optional `apiPrefix` and
  uses it to build every URL; defaults to `<mount>api/v1/` so consumers
  who don't set the override see no change.

## Tests
- Backend (`test_spa_index.py`): default → meta is `<mount>/api/v1/`;
  override → meta is the override verbatim; missing-trailing-slash →
  resolver adds one. Full suite **45 passed**.
- Frontend (`client.test.ts`): override routes every request through
  it; missing-trailing-slash gets one; omitted prefix keeps the legacy
  `<mount>api/v1/` path. Full vitest **145 passed**.

Closes #559

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MartinCastroAlvarez MartinCastroAlvarez merged commit b11fa85 into main May 28, 2026
5 checks passed
@MartinCastroAlvarez MartinCastroAlvarez deleted the feat/api-url-prefix-setting-559 branch May 28, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an explicit API_URL setting so the SPA can talk to a separately-mounted django-admin-rest-api

2 participants