Skip to content

fix: serve SPA client routes with 200 and keep API 404s out of the fallback - #383

Open
eastagiletracker wants to merge 1 commit into
codechem:mainfrom
eastagiletracker:agile-board/spa-fallback-status
Open

eastagiletracker wants to merge 1 commit into
codechem:mainfrom
eastagiletracker:agile-board/spa-fallback-status

Conversation

@eastagiletracker

Copy link
Copy Markdown

This PR proposes serving the Dappi admin UI's client-side routes with HTTP 200 and keeping unknown /api routes and missing static files out of the SPA fallback in UseDappi. We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/1150. You can sign in with your GitHub ID to claim ownership of the project.

What was wrong

The fallback middleware in AppExtensions.UseDappi rewrites the request to /index.html whenever the first pass ends in an unstarted 404, but it never resets the status. StaticFileMiddleware keeps a non-200 status it finds, so index.html goes out with the original 404: every admin UI page, including GET /, is served as 404 Not Found. That is invisible in a browser but trips uptime checks, load balancer health probes and CDN caching. The same || StatusCode == 404 branch also catches /api/* and file requests, so an unknown API route or a missing JS chunk returns the SPA's HTML instead of a plain 404, which makes client-side errors hard to read.

Reproduced at 65708a5 (current main) with the integration test host plus a wwwroot/index.html:

GET /                    -> 404 text/html  (index.html body)
GET /content-builder     -> 404 text/html  (index.html body)
GET /api/nope            -> 404 text/html  (index.html body)
GET /assets/missing.js   -> 404 text/html  (index.html body)
GET /index.html          -> 200 text/html

The change

The fallback now only applies to GET/HEAD requests for extensionless, non-/api paths that matched no endpoint and ended in an unstarted 404, and it sets the status back to 200 before serving index.html. API responses (success and error) and existing static files are untouched, and a 404 returned by a matched endpoint is left as it is rather than re-run against /index.html.

Verification

  • New Dappi.HeadlessCms.Tests/Middleware/SpaFallbackTests.cs (10 cases) runs the real UseDappi middleware chain with a temporary web root. On the unchanged tree 7 fail (client routes and HEAD / return 404; /api/does-not-exist, /api/auditTrail/ and /assets/missing-chunk.js return the SPA HTML) and the 3 controls pass (/index.html served directly, POST to a client route does not get the SPA, API 401/200/404 responses keep their status and body). With the change all 10 pass. Removing only the status reset turns the 4 client-route cases red again.
  • dotnet test Dappi.HeadlessCms.Tests: 241 passed before, 251 passed after (the 10 new tests), 0 failures. dotnet test Dappi.Core.Tests: 89 passed. dotnet build Dappi.HeadlessCms -c Release succeeds. Touched files formatted with the repo's CSharpier hook.

How this was managed

This work was tracked as https://eastagiletracker.com/projects/1150/stories/1349837 on a board imported from your issues and pull requests (351 stories), https://eastagiletracker.com/projects/1150.

board

If you'd rather not receive contributions like this, reply no-more-prs on this pull request and we won't open any further ones on your repositories.


Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com

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