graphql / graphql/graphql-http

Accept `q` weights are ignored during response media type negotiation

Open
#152 2 comments 0 reactions 0 assignees View on GitHub
enhancement good first issue
Dominant language
TypeScript
Stars
363
Forks
38
PR merge metrics
No merged PRs in 30d

Description

## Summary

`createHandler` parses `Accept` header parameters but does not appear to apply the `q` weight when selecting the response media type. As a result, `application/json;q=0` can still be selected, and a lower-priority supported media type can win only because it appears earlier in the header.

## Steps to reproduce

Use a handler/media-type negotiation test with supported response types `application/graphql-response+json` and `application/json`, then send requests with:

```http
Accept: application/json;q=0
```

and:

```http
Accept: application/json;q=0, application/graphql-response+json;q=1
```

A source-equivalent repro produced:

```text
application/json;q=0 => application/json
application/graphql-response+json;q=0 => application/graphql-response+json
application/xml, application/json;q=0 => application/json
application/json;q=0, application/graphql-response+json;q=1 => application/json
application/graphql-response+json;q=0.1, application/json;q=1 => application/graphql-response+json
```

## Expected behavior

- `q=0` should make that media type unacceptable.
- `Accept: application/json;q=0` should not select `application/json`; if no other supported media type is acceptable, the handler should take the existing `406 Not Acceptable` path.
- `Accept: application/json;q=0, application/graphql-response+json;q=1` should select `application/graphql-response+json`.

## Actual behavior

The first syntactically matching supported media type wins, even when its `q` value is `0` or lower than another supported media type later in the header.

## Evidence

- The source-equivalent repro above shows `q=0` values still being selected.
- `src/handler.ts` splits the `Accept` header and parameters, has a TODO for handling the weight parameter `q`, assigns `acceptedMediaType`, and breaks on the first matching supported type.
- The same file already has a `406 Not Acceptable` path when no media type is accepted.

## Suggested fix

Parse `q` from each `Accept` media range, default missing `q` to `1`, exclude candidates with `q=0`, and select the supported media type with the highest effective priority before falling back to `406`.

Regression tests could cover `q=0` and two supported media types with conflicting priorities.

## Additional context / Related coverage

A current GitHub search did not identify exact upstream issue/PR coverage for `Accept` `q` weights. Adjacent coverage includes issue `#120` for charset handling and PR `#23` for behavior when `Accept` is missing.

---
Submitted with Codex.

Contributor guide

Open the contributing guide

Research direction

Start in src/handler.ts at the Accept-header parsing, the TODO for the q weight, and the existing 406 Not Acceptable path. Run or add handler/media-type negotiation tests covering q=0 and conflicting priorities; done means zero-weight types are rejected and the highest-priority acceptable supported type is selected.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.