Skip to content

Commit 6350ea0

Browse files
committed
Review
1 parent 1ddd7c6 commit 6350ea0

File tree

1 file changed

+51
-34
lines changed

1 file changed

+51
-34
lines changed

docs/adr/0000-subresources-definition.md

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
## Context and Problem Statement
77

8-
Subresources introduced in 2017 ([#904][pull/904]) the `ApiSubresource` annotation. This definition came along with its own set of issues ([#2706][issue/2706]) and needs a refreshment. On top of that, write support on subresources is a wanted feature and it is hard to implement currently ([#2598][pull/2598]) (See [0001-subresource-write-support](./0001-subresource-write-support.md)). How can we revamp the Subresource definition to improve the developer experience and reduce the complexity?
8+
Subresources introduced in 2017 ([#904][pull/904]) the `ApiSubresource` annotation. This definition came along with its own set of issues ([#2706][issue/2706]) and needs a refreshment. On top of that, write support on subresources is a wanted feature and it is hard to implement currently ([#2598][pull/2598]) (See [ADR-0001-subresource-write-support](./0001-subresource-write-support.md)). How can we revamp the Subresource definition to improve the developer experience and reduce the complexity?
99

1010
## Considered Options
1111

@@ -21,6 +21,7 @@ We choose to use multiple `ApiResource` annotations to declare subresources on a
2121
* The `ApiSubresource` annotation is declared on a Model's properties, which was identified as the root of several issues. For example, finding what class it is defined on ([#3458][issue/3458]). Having multiple `ApiResource` would improve a lot the declaration of our internal metadata and would cause less confusion for developers.
2222
* The `path` of these multiple `ApiResource` needs to be implicitly described.
2323
* An `ApiResource` is always defined on the Resource it represents: `/companies/1/users` outputs Users and should be defined on the `User` model.
24+
* PropertyInfo and Doctrine metadata can be used to define how is the Resource identified according to the given path.
2425

2526
### Examples
2627

@@ -32,18 +33,26 @@ Get Users belonging to the company on (`/companies/1/users`);
3233
* @ApiResource(path="/companies/{companyId}/users")
3334
*/
3435
class User {
36+
/** @ApiProperty(identifier=true) */
37+
public int $id;
38+
39+
/** @var Company[] */
3540
public array $companies = [];
3641
}
3742
```
3843

39-
With explicit identifiers:
44+
With explicit identifiers, the tuple is explained in [ADR-0002-identifiers](./0002-identifiers) `{parameterName: {Class, property}}`:
4045

4146
```php
4247
/**
43-
* @ApiResource(path="/users")
44-
* @ApiResource(path="/companies/{companyId}/users", identifiers={"companyId": {Company::class, "id"}})
48+
* @ApiResource(path="/users", identifiers={"id": {User::class, "id"}})
49+
* @ApiResource(path="/companies/{companyId}/users", identifiers={"companyId": {Company::class, "id"}, "id": {User::class, "id"}})
4550
*/
4651
class User {
52+
/** @ApiProperty(identifier=true) */
53+
public int $id;
54+
55+
/** @var Company[] */
4756
public array $companies = [];
4857
}
4958
```
@@ -55,31 +64,53 @@ Two-level subresource to get the Users belonging to the Company #1 located in Fr
5564
* @ApiResource(path="/users")
5665
* @ApiResource(path="/countries/{countryId}/companies/{companyId}/users")
5766
*/
58-
class Users {
67+
class User {
68+
/** @ApiProperty(identifier=true) */
69+
public int $id;
70+
71+
/** @var Company[] */
5972
public array $companies = [];
6073
}
6174

6275
class Company {
76+
/** @ApiProperty(identifier=true) */
77+
public int $id;
78+
79+
/** @var Country[] **/
6380
public array $countries = [];
6481
}
82+
83+
class Country {
84+
/** @ApiProperty(identifier=true) */
85+
public string $shortName;
86+
}
6587
```
6688

6789
With explicit identifiers:
6890

6991
```php
7092
/**
71-
* @ApiResource(path="/users")
72-
* @ApiResource(path="/countries/{countryId}/companies/{companyId}/users", identifiers={"companyId": {Company::class, "id"}, "countryId": {Country::class, "shortName"}})
93+
* @ApiResource(path="/users", identifiers={"id": {User::class, "id"}})
94+
* @ApiResource(path="/countries/{countryId}/companies/{companyId}/users", identifiers={"companyId": {Company::class, "id"}, "countryId": {Country::class, "shortName"}, "id": {User::class, "id"}})
7395
*/
74-
class Users {
96+
class User {
97+
/** @ApiProperty(identifier=true) */
98+
public int $id;
99+
100+
/** @var Company[] */
75101
public array $companies = [];
76102
}
77103

78104
class Company {
105+
/** @ApiProperty(identifier=true) */
106+
public int $id;
107+
108+
/** @var Country[] **/
79109
public array $countries = [];
80110
}
81111

82112
class Country {
113+
/** @ApiProperty(identifier=true) */
83114
public string $shortName;
84115
}
85116
```
@@ -92,41 +123,27 @@ Get the company employees or administrators `/companies/1/administrators`:
92123
* @ApiResource(path="/companies/{companyId}/administrators")
93124
* @ApiResource(path="/companies/{companyId}/employees")
94125
*/
95-
class Users {
96-
public array $companies;
97-
}
98-
99-
class Company {
126+
class User {
127+
/** @ApiProperty(identifier=true) */
100128
public int $id;
101-
public Users $employees;
102-
public Users $administrators;
103-
}
104-
```
105-
106-
With explicit identifiers:
107129

108-
```php
109-
/**
110-
* @ApiResource(path="/users")
111-
* @ApiResource(path="/companies/{companyId}/administrators", identifiers={"companyId": {Company::class, "id"}, "*": {Company::class, "administrators"}})
112-
* @ApiResource(path="/companies/{companyId}/employees", identifiers={"companyId": {Company::class, "id"}, "*": {Company::class, "employees"}})
113-
*/
114-
class Users {
115-
public array $companies;
130+
/** @var Company[] */
131+
public array $companies = [];
116132
}
117133

118134
class Company {
135+
/** @ApiProperty(identifier=true) */
119136
public int $id;
120-
public Users $employees;
121-
public Users $administrators;
137+
138+
/** @var User[] **/
139+
public array $employees;
140+
141+
/** @var User[] **/
142+
public array $administrators;
122143
}
123144
```
124145

125-
## TODO:
126-
127-
* Without explicit identifiers, how do we map `companyId` to Company->id ?
128-
* Do we parse the path to find `administrators` and map it to the property ?
129-
* The Tuple `identifiers={pathParameter: {Class, property}}` should be redefined / validated (and what about `*` for collection?)
146+
This example will require a custom DataProvider as the discriminator needs to be explicit.
130147

131148
## Links
132149

0 commit comments

Comments
 (0)