Repository navigation
[13.x] Improve JsonApiResource collection and array return types - #62356
Closed
tomasvanrijsse wants to merge 2 commits into
Closed
tomasvanrijsse wants to merge 2 commits into
tomasvanrijsse wants to merge 2 commits into
Conversation
…as string-keyed arrays
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.
JsonApiResourceoverridesnewCollection()to returnIlluminate\Http\Resources\JsonApi\AnonymousResourceCollection. The publiccollection()method is inherited fromJsonResource, and its PHPDoc still says it returnsIlluminate\Http\Resources\Json\AnonymousResourceCollection.Static analysis (PHPStan, Larastan) therefore types every
SomeJsonApiResource::collection(...)as the plain JSON collection. A controller that declares the JSON:API collection as its return type, which is what it actually returns, gets an error:This PR adds a class-level
@method statictag toJsonApiResource, socollection()is typed as the collection it actually creates.Why a
@methodtag#61296 tried to fix this with a PHPDoc-only
collection()override that calledparent::collection(). This PR adds no method at all:collection(), includingpreserveKeys, stays exactly the same.collection()(with or without a native return type) keep working, because the parent's signature doesn't change.collection()call. In an application, overridingcollection()in a resource base class changed the generated OpenAPI spec: collection items lost their schema, and the pagination meta and the sparse fieldset parameters disappeared. With a@methodtag instead, the spec stayed byte-identical while PHPStan picked up the narrower type.String-keyed
toAttributes(),toRelationships(),toLinks()andtoMeta()These methods are documented as returning a bare
array. A resource that overridestoAttributes(Request $request): arraywithout its own PHPDoc inherits that barearray, and PHPStan (level 6 and up) then reportsmissingType.iterableValueon it. Every resource in an application had to repeat@return array<string, mixed>. The four methods now documentarray<string, mixed>, so subclasses inherit the value type.Tests
types/Http/Resources/JsonApi/JsonApiResource.phpasserts the return type ofcollection()forJsonApiResourceitself and for a subclass. It also asserts thatJsonResource::collection()still returns the plain JSON collection. Without the tag, the two JSON:API assertions fail. It also asserts that a subclass overridingtoAttributes()without PHPDoc getsarray<string, mixed>; without the PHPDoc change that assertion fails and the subclass reportsmissingType.iterableValue.Claude