fix(swagger): correct /shapes filter[route] parameter description - #1066
Open
Redeem-Grimm-Satoshi wants to merge 1 commit into
Open
fix(swagger): correct /shapes filter[route] parameter description#1066Redeem-Grimm-Satoshi wants to merge 1 commit into
Redeem-Grimm-Satoshi wants to merge 1 commit into
Conversation
The `filter[route]` parameter on `/shapes` was documented via the shared
`filter_param(:id, name: :route)` helper, which renders the description
"Filter by `/data/{index}/relationships/route/data/id`".
That JSON pointer cannot be resolved against a `/shapes` response on any
currently supported API version. `ApiWeb.ShapeView.relationships/2` returns
an empty map for versions >= 2020-05-01, so shape resources carry no
`relationships` member at all. The pointer is accurate for 2019-07-01 and
earlier, where the view still emits `route` and `stops`, but it has been
stale for the default version since 2020-05-01.
Because `/shapes` also accepts `include` without validating it and returns
200, a client that follows the documented pointer and requests
`include=route` receives a success response with no linkage data and no
diagnostic, which makes the mismatch difficult to diagnose from the outside.
This replaces the generated pointer text with an accurate description of
what the filter accepts, keeps the existing comma-separated-list convention
and `required: true`, and notes the 2020-05-01 boundary so callers needing
route attribution know to request a single route at a time.
No behavior change; documentation only.
Redeem-Grimm-Satoshi
requested review from
zyxw59
and removed request for
a team
August 9, 2026 05:23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Asana Ticket: n/a, outside contribution. Context and reproductions below.
Corrects the
filter[route]parameter description onGET /shapes, which documents a JSON pointer that no longer exists in the response on current API versions. Documentation only, no behavior change.Context
I built a trip planner on the V3 API for the 2026 World Cup matches at Boston Stadium: https://matchachusetts.up.railway.app/
The venue is Gillette Stadium in Foxborough, roughly 30 miles south of the city, so most of the useful advice for a visitor turned out to be transit advice. The core of the app is a map drawing nine MBTA routes as coloured polylines with live vehicle positions on top: Red, Orange, Blue, the four Green branches, SL1, and Foxboro/Franklin.
Drawing a route in its own colour means knowing which route each returned polyline belongs to. That is the only reason I went looking at
/shapesrelationships in the first place.Problem
The swagger docs describe
filter[route]on/shapesas filtering by/data/{index}/relationships/route/data/id. Reading that, the obvious approach is a single request for all nine routes, then reading the route id off each shape:That returns
200with a flat list of shapes carrying no relationships and noincludedmember. The documented pointer does not resolve, because shape resources have norelationshipsmember at all on current versions:Because the response is a success, the natural first conclusion is that the query is wrong rather than that the endpoint does not do what the documentation describes. I spent a while varying include syntax and checking JSON:API conformance before working out that the pointer had simply gone stale.
Varying only the
MBTA-Versionheader shows a clean boundary:relationshipsattributesroute,stopsdirection_id,name,polyline,prioritypolylineThat matches
ApiWeb.ShapeView.relationships/2, which returns an empty map for versions at or after2020-05-01. The removal looks deliberate and pairs with the same gate onattributes/2. It is only the generated documentation that was left behind, and since2021-01-09is the default, the stale text is what most callers read.The mismatch is harder to spot than it should be because
/shapesalso acceptsincludewithout validating it, where other endpoints reject it:Solution
ShapeController.indexused the sharedfilter_param(:id, name: :route)helper, which renders the relationship pointer automatically. That helper is correct for/stops, whereStopViewstill emits arouterelationship, but wrong here. This replaces it with an explicit parameter whose description says what the filter actually accepts, keeps the existing comma-separated-list convention andrequired: true, and notes the2020-05-01boundary so callers needing route attribution know to request one route at a time.Before:
After:
I deliberately scoped this to the documentation. Restoring the relationship would resolve the mismatch too, but the removal reads as intentional resource slimming and reversing it is your call, not something to slip into a docs fix.
The
includevalidation is likewise left alone here. Returning400would be correct for consistency, but it converts a currently successful response into an error, and anyone passinginclude=routeto/shapestoday is getting a200, so it presumably needs a newMBTA-Versionthe way the2020-05-01changes were handled. I have raised that on the massdotdevelopers list rather than assume a direction, and I am glad to write that patch if you tell me what shape it should take.Verification
Built against Elixir 1.19.5 and OTP 28, matching
.tool-versions:mix compile --force --warnings-as-errorspassesmix format --check-formattedpasses on the changed filemix credo --strictreports no issues on the changed filemix test test/api_web/controllers/shape_controller_test.exspasses, 14 tests and 0 failures, includingshow conforms to swagger responseI also checked the regenerated
priv/static/swagger.jsondirectly:/shapesno longer referencesrelationships/route/data/id,required: truesurvives, and the comma-separated-list wording is unchanged.