Skip to content

feat(dispatcher): 404 を Accept header で content-negotiation する (#312)#322

Merged
hideyukiMORI merged 1 commit into
mainfrom
feat/312-404-accept-negotiation
May 22, 2026
Merged

feat(dispatcher): 404 を Accept header で content-negotiation する (#312)#322
hideyukiMORI merged 1 commit into
mainfrom
feat/312-404-accept-negotiation

Conversation

@hideyukiMORI
Copy link
Copy Markdown
Owner

Summary

FT7 F-1 (Issue #312) の本体 fix。

何を直したか

`Dispatcher::notFoundResponse()` は常に `404.html` (`Content-Type: text/html`) を返していて、REST client が `Accept: application/json` を付けても HTML が返る → ADR-0003 envelope の契約が 404 だけ守られていなかった。

新たに `Dispatcher::wantsJson(string $acceptHeader): bool` を導入し、JSON-preferring client (`application/json` または `application/*` で q-value が `text/html` を上回る) には新 error code `NOT-FOUND` の JSON envelope を返す。HTML caller (`text/html`, 空 header, ワイルドカードのみ等) は従来どおり `404.html`。

仕様

  • 新 error code: `NOT-FOUND` (HTTP 404, `The requested resource was not found.`)
  • 判定ロジック: q-value 比較で JSON が HTML 以上のときに JSON envelope を返す
  • 既存 `404.html` は HTML caller 用に残す (UX 後退なし)

Test plan

  • `composer test` 50/50 (新規 5 ケース: `wantsJson()` 単体)
  • `composer test:http` 23/23 (新規 2 ケース: Accept 無し → HTML 404, Accept: JSON → NOT-FOUND envelope)
  • live verify: `curl http://127.0.0.1:8080/no-such-controller/foo\` → HTML / `curl -H 'Accept: application/json' ...` → JSON envelope

Doc updates

  • `docs/development/error-codes.md` — NOT-FOUND row
  • `docs/api/openapi.yaml` — `NotFound` response component
  • `docs/api/reference-client.md` — failure-mode row

Closes #312.

FT7 F-1 で確認した「REST client が Accept: application/json を付けても
404.html を返す → ADR-0003 envelope の契約が 404 だけ守られていない」
問題を解消する。

- Dispatcher::notFoundResponse() に Accept ヘッダ判定を追加。JSON-preferring
  client (application/json or application/* で q が text/html を上回る) には
  ApiResponse->failure('NOT-FOUND') の JSON envelope を返す。HTML / browser
  default (text/html, \*/\* 等) は従来どおり 404.html。
- NOT-FOUND code を config/error_codes.php に追加 (HTTP 404)。
- docs/development/error-codes.md / docs/api/openapi.yaml / docs/api/reference-client.md
  に新 code とその branch 仕様を documentation。
- Unit test: Dispatcher::wantsJson() の content-negotiation を 5 ケース追加。
- HTTP smoke test: Accept 無し → HTML、Accept: application/json → JSON envelope
  を 2 ケース追加。

Closes #312.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hideyukiMORI hideyukiMORI merged commit f9e015c into main May 22, 2026
2 checks passed
@hideyukiMORI hideyukiMORI deleted the feat/312-404-accept-negotiation branch May 22, 2026 08:01
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.

FT7 F-1: 404 を Accept ヘッダで content-negotiation する (REST には JSON envelope を返す)

1 participant