Skip to content

Commit 0f30c63

Browse files
committed
feat: JsonApiResource|JsonApiCollection generics type
1 parent 2bfb2a0 commit 0f30c63

File tree

5 files changed

+47
-38
lines changed

5 files changed

+47
-38
lines changed

src/JsonApiCollection.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,20 @@
77
use Illuminate\Http\Resources\Json\JsonResource;
88
use Illuminate\Http\Resources\Json\ResourceCollection;
99

10+
/**
11+
* @template T
12+
* @template R
13+
* @template-extends JsonApiResource<R>
14+
*/
1015
class JsonApiCollection extends ResourceCollection implements Resourceable
1116
{
1217
use Concerns\Relationize,
1318
Concerns\Schema,
1419
Concerns\ToResponse;
1520

21+
/**
22+
* @var class-string<T>
23+
*/
1624
public $collects;
1725

1826
/**

src/JsonApiResource.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
use Ark4ne\JsonApi\Resource\Support\With;
66
use Illuminate\Http\Resources\Json\JsonResource;
77

8+
/**
9+
* @template T
10+
*/
811
abstract class JsonApiResource extends JsonResource implements Resourceable
912
{
1013
use Concerns\Relationize,
@@ -16,6 +19,9 @@ abstract class JsonApiResource extends JsonResource implements Resourceable
1619
Concerns\Schema,
1720
Concerns\ToResponse;
1821

22+
/** @var T */
23+
public $resource;
24+
1925
final public function __construct($resource)
2026
{
2127
parent::__construct($resource);

tests/app/Http/Resources/CommentResource.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Illuminate\Http\Request;
88

99
/**
10-
* @mixin \Test\app\Models\Comment
10+
* @extends JsonApiResource<\Test\app\Models\Comment>
1111
*/
1212
class CommentResource extends JsonApiResource
1313
{
@@ -19,31 +19,31 @@ protected function toType(Request $request): string
1919
protected function toAttributes(Request $request): iterable
2020
{
2121
return [
22-
'content' => fn() => $this->content,
22+
'content' => fn() => $this->resource->content,
2323
];
2424
}
2525

2626
protected function toResourceMeta(Request $request): ?iterable
2727
{
2828
return [
29-
'created_at' => $this->created_at->format(DateTimeInterface::ATOM),
30-
'updated_at' => $this->updated_at->format(DateTimeInterface::ATOM),
29+
'created_at' => $this->resource->created_at->format(DateTimeInterface::ATOM),
30+
'updated_at' => $this->resource->updated_at->format(DateTimeInterface::ATOM),
3131
];
3232
}
3333

3434
protected function toRelationships(Request $request): iterable
3535
{
3636
return [
37-
'user' => UserResource::relationship(fn() => $this->user)
37+
'user' => UserResource::relationship(fn() => $this->resource->user)
3838
->withLinks(fn() => [
39-
'self' => "https://api.example.com/comment/{$this->id}/relationships/user",
40-
'related' => "https://api.example.com/comment/{$this->id}/user",
39+
'self' => "https://api.example.com/comment/{$this->resource->id}/relationships/user",
40+
'related' => "https://api.example.com/comment/{$this->resource->id}/user",
4141
])
4242
->whenIncluded(),
43-
'post' => PostResource::relationship(fn() => $this->post)
43+
'post' => PostResource::relationship(fn() => $this->resource->post)
4444
->withLinks(fn() => [
45-
'self' => "https://api.example.com/comment/{$this->id}/relationships/post",
46-
'related' => "https://api.example.com/comment/{$this->id}/post",
45+
'self' => "https://api.example.com/comment/{$this->resource->id}/relationships/post",
46+
'related' => "https://api.example.com/comment/{$this->resource->id}/post",
4747
])
4848
->whenIncluded(),
4949
];

tests/app/Http/Resources/PostResource.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Illuminate\Http\Request;
88

99
/**
10-
* @mixin \Test\app\Models\Post
10+
* @extends JsonApiResource<\Test\app\Models\Post>
1111
*/
1212
class PostResource extends JsonApiResource
1313
{
@@ -19,28 +19,28 @@ protected function toType(Request $request): string
1919
protected function toAttributes(Request $request): iterable
2020
{
2121
return [
22-
'title' => fn() => $this->title,
23-
'content' => fn() => $this->content,
22+
'title' => fn() => $this->resource->title,
23+
'content' => fn() => $this->resource->content,
2424
];
2525
}
2626

2727
protected function toResourceMeta(Request $request): ?iterable
2828
{
2929
return [
30-
'created_at' => $this->created_at->format(DateTimeInterface::ATOM),
31-
'updated_at' => $this->updated_at->format(DateTimeInterface::ATOM),
30+
'created_at' => $this->resource->created_at->format(DateTimeInterface::ATOM),
31+
'updated_at' => $this->resource->updated_at->format(DateTimeInterface::ATOM),
3232
];
3333
}
3434

3535
protected function toRelationships(Request $request): iterable
3636
{
3737
return [
38-
'user' => UserResource::relationship(fn() => $this->user, fn() => [
39-
'self' => "https://api.example.com/posts/{$this->id}/relationships/user",
38+
'user' => UserResource::relationship(fn() => $this->resource->user, fn() => [
39+
'self' => "https://api.example.com/posts/{$this->resource->id}/relationships/user",
4040
]),
41-
'comments' => CommentResource::relationship(fn() => $this->comments, fn() => [
42-
'self' => "https://api.example.com/posts/{$this->id}/relationships/comments",
43-
'related' => "https://api.example.com/posts/{$this->id}/comments",
41+
'comments' => CommentResource::relationship(fn() => $this->resource->comments, fn() => [
42+
'self' => "https://api.example.com/posts/{$this->resource->id}/relationships/comments",
43+
'related' => "https://api.example.com/posts/{$this->resource->id}/comments",
4444
])->asCollection(),
4545
];
4646
}

tests/app/Http/Resources/UserResource.php

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,10 @@
77
use Illuminate\Http\Request;
88

99
/**
10-
* @mixin \Test\App\Models\User
10+
* @extends JsonApiResource<\Test\app\Models\User>
1111
*/
1212
class UserResource extends JsonApiResource
1313
{
14-
/** @var \Test\app\Models\User $resource */
15-
public $resource;
16-
1714
protected function toType(Request $request): string
1815
{
1916
return 'user';
@@ -22,33 +19,31 @@ protected function toType(Request $request): string
2219
protected function toAttributes(Request $request): iterable
2320
{
2421
return [
25-
'name' => $this->name,
26-
'email' => $this->email,
22+
'name' => $this->resource->name,
23+
'email' => $this->resource->email,
2724
];
2825
}
2926

3027
protected function toResourceMeta(Request $request): ?iterable
3128
{
3229
return [
33-
'created_at' => $this->created_at->format(DateTimeInterface::ATOM),
34-
'updated_at' => $this->updated_at->format(DateTimeInterface::ATOM),
30+
'created_at' => $this->resource->created_at->format(DateTimeInterface::ATOM),
31+
'updated_at' => $this->resource->updated_at->format(DateTimeInterface::ATOM),
3532
];
3633
}
3734

3835
protected function toRelationships(Request $request): iterable
3936
{
4037
return [
41-
'posts' => PostResource::relationship(fn() => $this->posts, fn() => [
42-
'self' => "https://api.example.com/user/{$this->id}/relationships/posts",
43-
'related' => "https://api.example.com/user/{$this->id}/posts",
38+
'posts' => PostResource::relationship(fn() => $this->resource->posts, fn() => [
39+
'self' => "https://api.example.com/user/{$this->resource->id}/relationships/posts",
40+
'related' => "https://api.example.com/user/{$this->resource->id}/posts",
4441
])->asCollection(),
45-
'comments' => CommentResource
46-
::relationship(fn() => $this->whenLoaded('comments'))
47-
->withLinks(fn() => [
48-
'self' => "https://api.example.com/user/{$this->id}/relationships/comments",
49-
'related' => "https://api.example.com/user/{$this->id}/comments",
50-
])
51-
->asCollection()
42+
'comments' => CommentResource::relationship(fn() => $this->whenLoaded('comments'), fn() => [
43+
'self' => "https://api.example.com/user/{$this->resource->id}/relationships/comments",
44+
'related' => "https://api.example.com/user/{$this->resource->id}/comments",
45+
])
46+
->asCollection()
5247
];
5348
}
5449
}

0 commit comments

Comments
 (0)