Skip to content

POC WIP#6498

Open
fhennig wants to merge 7 commits into
mainfrom
feat/lapis-proxy
Open

POC WIP#6498
fhennig wants to merge 7 commits into
mainfrom
feat/lapis-proxy

Conversation

@fhennig
Copy link
Copy Markdown
Contributor

@fhennig fhennig commented May 26, 2026

@fhennig fhennig added the preview Triggers a deployment to argocd label May 26, 2026
@fhennig fhennig self-assigned this May 26, 2026
fhennig and others added 2 commits May 26, 2026 12:34
Adds a generic wildcard proxy at `/{organism}/lapis/**` that forwards
GET and POST requests to the upstream LAPIS service, enabling the
website to route all LAPIS calls through the backend instead of hitting
LAPIS directly.

Changes:
- Add `lapisUrl` field to `InstanceConfig` so each organism config
  carries its upstream LAPIS URL
- New `LapisProxyController` using Java 21 `HttpClient`, streaming
  response via `StreamingResponseBody` (handles large FASTA downloads
  without memory buffering), strips `Authorization` and hop-by-hop
  headers
- `SecurityConfig`: permit `/*/lapis/**` for GET + POST, disable CSRF
- `WebConfig`: exclude `/*/lapis/**` from `ReadOnlyModeInterceptor`
  (LAPIS POSTs are reads, not writes)
- Test fixture JSONs: add `lapisUrl` to each organism entry
- Helm `_common-metadata.tpl`: inject `lapisUrl` per organism into
  backend config using internal K8s service name
- Helm `_urls.tpl`: add `loculus.generateInternalLapisUrlsViaBackend`
  helper that builds LAPIS URLs routed through the backend proxy
- `loculus-website-config.yaml`: serverSide `lapisUrls` now point at
  the backend proxy (`backend-service:8079/{organism}/lapis`)
- `vitest.setup.ts`: test config `lapisUrls` updated to match the
  backend-proxy URL pattern

Website TypeScript changes (remove `lapisUrls` from `ServiceUrls` type,
rewrite `getLapisUrl()`) are tracked in POC_PLAN.md and will follow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`lapisUrls` is no longer injected into `runtime_config.json` — the
LAPIS URL for any organism is now derived as
`{backendUrl}/{organism}/lapis`, matching the backend proxy routes
added in the previous commit.

Changes:
- `runtimeConfig.ts`: remove `lapisUrls` field from `serviceUrls` Zod
  schema
- `config.ts`: rewrite `getLapisUrl()` to compute from `backendUrl`
  instead of reading a config map; no more runtime error on unknown
  organisms
- `GroupPage.tsx`: replace `clientConfig.lapisUrls[key]` (with null
  guard) with `getLapisUrl(clientConfig, key)`
- `SeqSetRecordsTableWithMetadata.tsx`: add `organisms: string[]` prop;
  iterate that list and compute each URL via `getLapisUrl` — removes the
  hacky `lapisUrls` dummy-organism filter
- `SeqSetItem.tsx`: thread `organisms` prop through to
  `SeqSetRecordsTableWithMetadata`
- `seqsets/[seqSetId].[version].astro`: pass
  `Object.keys(websiteConfig.organisms)` as `organisms`
- `api-documentation/index.astro`: compute LAPIS doc links from
  `backendUrl` + organism keys (already available as `organismKeys`)
- `loculus-info/index.ts`: compute `lapis` response field from
  `backendUrl` + organism keys instead of reading `lapisUrls`
- `_common-metadata.tpl`: remove `lapisUrls` from `publicRuntimeConfig`
- `loculus-website-config.yaml`: remove `lapisUrls` from serverSide
  block (URL is now computed client-side)
- test files: replace `testConfig.serverSide.lapisUrls[testOrganism]`
  with `getLapisUrl(testConfig.serverSide, testOrganism)`

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@fhennig fhennig force-pushed the feat/lapis-proxy branch from 59bc74b to 02fcb00 Compare May 26, 2026 11:34
fhennig and others added 2 commits May 27, 2026 08:20
…d is local

When `disableBackend=true` (i.e. the backend runs locally outside the
cluster), the generated backend_config.json must point lapisUrl at
the port-forwarded LAPIS address (http://localhost:8080/{organism})
rather than the K8s-internal service name, which is unreachable from
outside the cluster.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds /query/{organism}/{versionGroup}/... endpoints as a typed alternative
to the generic LAPIS proxy. The versionGroup segment ("current" or
"allVersions") controls whether versionStatus=LATEST_VERSION is injected
into the forwarded LAPIS request body.

Extracts shared HTTP proxy logic into LapisProxyService so both
LapisProxyController and QueryController can reuse it without duplication.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
val url = lapisBaseUrl.trimEnd('/') + lapisPath
log.debug { "Proxying POST $url" }
val request = HttpRequest.newBuilder()
.uri(URI.create(url))
val url = lapisBaseUrl.trimEnd('/') + lapisPath + query
log.debug { "Proxying GET $url" }
val request = HttpRequest.newBuilder()
.uri(URI.create(url))
fhennig and others added 2 commits May 27, 2026 11:36
Route metadata/aggregated/mutations/sequences queries through the new
structured /query/{organism}/{versionGroup}/... backend endpoints instead
of the generic LAPIS proxy, so the backend can inject version filters
automatically per path rather than requiring callers to supply them.

- Add getQueryUrl() to config.ts for building query endpoint URLs
- New queryApi.ts with Zodios endpoint definitions for QueryController paths
- LapisClient: add currentUrl/allVersionsUrl fields, requestFull() helper,
  migrate 6 methods (getSequenceEntryVersionDetails, getLatestAccessionVersion,
  getAllSequenceEntryHistoryForAccession, getSequenceMutations nucleotide,
  getUnalignedSequences); remove explicit versionStatus from getLatestAccessionVersion
- serviceHooks: optional queryCurrentUrl param routes useAggregated/useDetails
  through QueryController when provided, falls back to proxy otherwise
- SearchFullUI: compute and pass queryCurrentUrl to lapisClientHooks
- GroupPage: use getQueryUrl for sequence count and time series queries
- SeqSetRecordsTableWithMetadata: use allVersions for versioned accessions,
  current for bare accessions
- Update vitest mocks for new endpoint paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…te download button

GET /query/{organism}/{versionGroup}/{path} endpoints mirror the existing
POSTs but accept query string parameters and inject versionStatus as a
query param (for the current group) rather than into a JSON body. This
enables browser-navigable download URLs to go through the structured
endpoint instead of the raw LAPIS proxy.

Backend:
- Add prepareQuery() that appends versionStatus=LATEST_VERSION for current
- Add get() helper mirroring post()
- Add GET endpoints: metadata, sequences, sequences/{segment},
  sequencesAligned, sequencesAligned/{referenceName}, translations/{gene}
- Remove @hidden annotation so all QueryController endpoints show in Swagger

Website:
- DownloadUrlGenerator: use downloadBaseUrl + new paths (/metadata,
  /sequences, /sequencesAligned, /translations/{gene}) instead of the
  old /sample/... LAPIS proxy paths
- SearchFullUI: pass queryCurrentUrl to DownloadUrlGenerator
- Update DownloadDialog tests to match new endpoint paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Triggers a deployment to argocd

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants