Skip to content

Align SoF async export to the simplified async interaction pattern#155

Merged
smunini merged 1 commit into
mainfrom
feature/sof-export-async-interaction-pattern
Jun 14, 2026
Merged

Align SoF async export to the simplified async interaction pattern#155
smunini merged 1 commit into
mainfrom
feature/sof-export-async-interaction-pattern

Conversation

@smunini

@smunini smunini commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Updates the $viewdefinition-export and $sqlquery-export operations to follow the FHIR Asynchronous Interaction Request Pattern per HL7/sql-on-fhir#369, replacing the prior Bulk Data completion behavior.

The core behavioral change: completion (and failure) is now signalled by a 303 See Other redirect from the status poll to a separate result URL — instead of returning 200 OK with the manifest directly on the status poll.

Changes

crates/rest

  • routing/fhir_routes.rs — Added GET /export/{job_id}/result. The static result segment takes priority over the existing {filename} download route (matchit 0.8 supports this overlap).
  • handlers/sof/export.rs
    • get_export_status_handler — the Completed/Failed arms now return 303 See Other with an empty body and a Location header carrying the absolute result URL. The status endpoint no longer communicates job outcome (still 202 while running, 404 for unknown/cancelled).
    • Added get_export_result_handler — serves the manifest Parameters with 200 OK + Expires (24h) on success, the error status + OperationOutcome on failure, and 404 when the job is unknown/cancelled/still running.
    • Updated the module-level doc comment.
  • handlers/sof/mod.rs — re-exported the new handler.

Tests (crates/rest/tests/sof_export.rs)

  • Updated the poll_to_manifest helper to follow the 303 → result URL → 200 flow.
  • Reworked the three tests that assumed the old direct-200-on-poll completion, and the failure test (now asserts 303 → 500 at the result URL).
  • Added test_export_completion_redirects_to_result (empty-body 303, Location, stable repeat fetch, Expires) and test_export_result_unknown_job_returns_404.

Not implemented (optional / client-side)

  • 429 Too Many Requests for excessive polling — spec says the server MAY; we don't rate-limit polls.
  • Opaque-URL requirement — a client-side MUST; our URLs are already non-guessable (UUID job IDs).

Caveat

HL7/sql-on-fhir#369 is still open, and the cited async-interaction pattern currently links an in-progress incubator branch — the exact 303/result-URL contract could shift before it lands.

Test plan

  • cargo fmt --all
  • cargo clippy --all-targets --all-features -- -D warnings ... (clean)
  • cargo test -p helios-rest --test sof_export — 44 passed, 0 failed

Updates the $viewdefinition-export and $sqlquery-export operations to follow
the FHIR Asynchronous Interaction Request Pattern per HL7/sql-on-fhir#369,
replacing the prior Bulk Data completion behavior.

Completion and failure are now both signalled by a 303 See Other redirect
from the status poll to a separate result URL with an empty body. The new
GET /export/{job_id}/result endpoint returns the manifest Parameters with
200 OK on success, or the error status code with an OperationOutcome on
failure (404 when the job is unknown, cancelled, or not yet finished). The
status endpoint no longer carries the job outcome.

- Add get_export_result_handler and the /export/{job_id}/result route
  (static segment takes priority over the {filename} download route).
- Status poll Completed/Failed arms now return 303 + Location to the result
  URL; Expires (24h) moves to the result response.
- Update sof_export tests to follow the 303 -> result flow and add coverage
  for the redirect contract and the unknown-job result 404.
@codecov

codecov Bot commented Jun 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.10526% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/rest/src/handlers/sof/export.rs 91.78% 6 Missing ⚠️

📢 Thoughts on this report? Let us know!

@smunini smunini merged commit b756c45 into main Jun 14, 2026
18 checks passed
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.

1 participant