core
core copied to clipboard
Add NotExposed operation
Q | A |
---|---|
Branch? | 2.7 |
Tickets | #4879 |
License | MIT |
Doc PRs | https://github.com/api-platform/docs/pull/1590, https://github.com/api-platform/docs/pull/1592 |
1. Generating a default NotExposed operation to generate the IRI if the resource has no Get operation available
Description
The following resource:
#[GetCollection] // path will be: /users
class User
When I call GET /users
, I get the following error:
"Operation "" not found for resource "User"."
That's because API Platform cannot find any Get operation to generate the IRI for each collection member. A trick currently used is to manually add a Get operation with read: false, output: false, controller: NotFoundAction::class
, which is not ideal.
Solution
Detect that this resource has no Get operation, and automatically add a NotExposed operation. This operation could be used to generate an IRI like /users/{id}
is the resource has an identifier, or a Skolem IRI /.well-known/genid/{id}
if the resource doesn't have any identifier.
TODO
- [x] Add NotExposedOperationResourceMetadataCollectionFactory
- [x] Add NotExposedAction
- [x] Add Behat tests
- [x] Add unit tests
- [x] Add documentation about NotExposed auto-generated operation
2. Disabling operation from OpenApi documentation
Description
The following resource:
#[GetCollection]
#[Get(uriTemplate: '/foo')] // I don't want this operation to be exposed on OpenApi documentation
class User
For any reason, I want an operation to not be exposed on the OpenApi documentation. It also implies the NotExposed auto-generated operation explained on the previous use case.
Even if it is available in the Symfony routing, it should not be available on the OpenApi documentation.
Solution
Add a openapi
boolean option on Operation to disable this operation from the OpenApi documentation.
Note: in a later version, it should be better to merge
openapiContext
intoopenapi
to improve DX and reduce confusion and multiple options.
#[GetCollection]
#[Get(openapi: false, uriTemplate: '/foo')]
class User
TODO
- [x] Add
openapi
boolean option on operation classes - [x] Ignore operation from OpenApi documentation if
openapi
is strictly false - [x] Update unit tests
- [x] Add documentation about
openapi
new operation option
3. Specifying the operation to use to generate the IRI
Description
The following resource:
#[GetCollection] // path will be: /users
#[Get] // path will be: /users/{id}
#[GetCollection(uriTemplate: '/companies/{companyId}/users', ...)]
#[Get(uriTemplate: '/companies/{companyId}/users/{id}', ...)]
class User
When I call GET /companies/{companyId}/users
, the members IRI will be the first Get operation found, so /users/{id}
. But it should be /companies/{companyId}/users/{id}
to be consistent with the operation initially called.
Solution
Add a itemUriTemplate
string option on Operation to specify which operation to use to generate the IRI. If this option is not set, then the default behavior is applied (select the first Get operation detected).
This option is only useful for collection operations (GetCollection and Post).
#[GetCollection] // the "itemUriTemplate" option is not used, it will use the first Get operation available
#[Get]
#[GetCollection(itemUriTemplate: '/companies/{companyId}/users/{id}', uriTemplate: '/companies/{companyId}/users', ...)]
#[Get(uriTemplate: '/companies/{companyId}/users/{id}', ...)]
class User
TODO
- [x] Add
itemUriTemplate
option on operation, and use it on$this->resourceMetadataCollectionFactory->getOperation()
calls if available and from a collection operation context - [x] Add Behat tests
- [x] Update unit tests
- [x] Add documentation about
itemUriTemplate
option
4. Handling output on a resource with a GetCollection operation but with no Get operation available
Description
The following resource:
#[GetCollection(output: UserOutput::class)] // path will be: /users
// A NotExposed operation is automatically generated
When I call GET /users
on a GetCollection with output, API Platform is trying to find a Get operation available on the output resource to generate the IRI, but it is not a resource. The following error occurs:
"Operation "" not found for resource "User"."
Solution
The best solution would be to support ApiResource and ApiProperty on DTO, but it could be done in another PR. Meanwhile, it's better to return a Skolem IRI.
TODO
- [x] Generate a Skolem IRI
- [x] Add Behat tests
5. Miscellaneous
- [x] Fix Doctrine errors on PHPStan
- [x] Fix Swagger v2 generation