Add the ability to declare empty item operations#3079
Conversation
soyuka
commented
Sep 18, 2019
| Q | A |
|---|---|
| Bug fix? | no |
| New feature? | yes |
| BC breaks? | no |
| Deprecations? | no |
| Tests pass? | yes |
| Fixed tickets | #3051 |
| License | MIT |
| Doc PR | na |
| * @return object | ||
| */ | ||
| public function __invoke($data) | ||
| public function __invoke($data = null) |
There was a problem hiding this comment.
Should I maybe do a new controller instead of changing this?
There was a problem hiding this comment.
Yes, a new one that directly throw a 404 (so we can simplify the metadata).
b65fb5d to
373c57a
Compare
|
|
||
| $resourceMetadata = $resourceMetadata->withItemOperations($this->createOperations($methods)); | ||
| } else { | ||
| if (!$itemOperations) { |
There was a problem hiding this comment.
You must explicitly check for a get operation (only PUT could be defined for instance).
There was a problem hiding this comment.
how can this be done without links to the Router? I can move the method guess from ApiLoader to metadata first, but when using a route_name, we won't be able to check the method without retrieving the route from the RouteCollection right?
There was a problem hiding this comment.
when using a route_name, we won't be able to check the method without retrieving the route from the RouteCollection right?
Applying the 80/20 rule, I'd say let's do nothing when we encounter such edge cases?
| $resourceMetadata = $resourceMetadata->withItemOperations($this->createOperations($methods)); | ||
| } else { | ||
| if (!$itemOperations) { | ||
| $itemOperations = ['placeholder' => ['method' => 'GET', 'read' => false, 'serialize' => false, 'status' => 404]]; |
There was a problem hiding this comment.
The operation name should be get instead of placeholder.
There was a problem hiding this comment.
Can't we use 'output' => false here?
There was a problem hiding this comment.
I wanted to be able to differentiate the get operation but sure can do!
There was a problem hiding this comment.
to be able to differentiate the get operation
I know. I'm against that. 😆
I think there should be nothing special about it. Just a good / safe default when the get item operation is missing.
373c57a to
57236d6
Compare
| { | ||
| public function __invoke() | ||
| { | ||
| return new Response(null, 404); |
There was a problem hiding this comment.
Would you prefer to throw an HttpException here?
There was a problem hiding this comment.
Yes, it will trigger the custom error page system etc
57236d6 to
b026ae7
Compare
f5acf5d to
2f3ea1d
Compare
| if ($this->needsDefaultGetOperation($resourceMetadata)) { | ||
| $resourceMetadata = $resourceMetadata->withItemOperations(array_merge( | ||
| $resourceMetadata->getItemOperations(), | ||
| ['get' => ['method' => 'GET', 'read' => false, 'serialize' => false, 'output' => ['class' => false], 'controller' => NotFoundAction::class]]) |
There was a problem hiding this comment.
I think that serialize can be omitted, because the controller throw anyway.
2f3ea1d to
5aa6f20
Compare
|
Could you open a docs PR for that @soyuka? |
| if ($this->needsDefaultGetOperation($resourceMetadata)) { | ||
| $resourceMetadata = $resourceMetadata->withItemOperations(array_merge( | ||
| $resourceMetadata->getItemOperations(), | ||
| ['get' => ['method' => 'GET', 'read' => false, 'output' => ['class' => false], 'controller' => NotFoundAction::class]]) |
There was a problem hiding this comment.
I believe you've made a mistake here, it's supposed to be null:
| } | ||
|
|
||
| if (null === ($inputOrOutput['class'] ?? null)) { | ||
| if (false === ($inputOrOutput['class'] ?? false)) { |
There was a problem hiding this comment.
Should be reverted. See https://github.com/api-platform/core/pull/3079/files#r327557730
| $itemOperations = $resourceMetadata->getItemOperations(); | ||
|
|
||
| foreach ($itemOperations as $itemOperation) { | ||
| if ('GET' === ($itemOperation['method'] ?? false)) { |
There was a problem hiding this comment.
Why not ?? null instead?
There was a problem hiding this comment.
Actually, on second thought, this check is unsafe. There might be a custom GET item operation.
The only safe option seems to me to be for the user to declare this get operation themselves:
/**
* @ApiResource(
* itemOperations={
* "get"={
* "method"="GET",
* "controller"=NotFoundAction::class,
* "read"=false,
* "output"=false,
* },
* },
* )
*/Which to me seems like we should revert and make this a doc entry instead, while providing the NotFoundAction. (I'm of the opinion that we don't need another shortcut to declare this.)
There was a problem hiding this comment.
We could document the custom get operation with one that disables it! I'm fixing what you said!
There was a problem hiding this comment.
We could document the custom get operation with one that disables it!
What do you mean?
Anyway, I've given it more thought and it's still unsafe anyway. We don't know that there's not already a GET item operation because of route_name. So I really think we must revert this.
There was a problem hiding this comment.
There was a problem hiding this comment.
you said it yourself it's not recommended to use route_name?
There was a problem hiding this comment.
Yes, but if there's an operation using route_name which is the GET item operation, we could never tell, and we would be creating this get item operation with NotFoundAction. And there's nothing the user could do to fix that.