Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resource resolver for inheritance #2714

Closed

Conversation

Nek-
Copy link
Contributor

@Nek- Nek- commented Apr 7, 2019

Q A
Bug fix? yes
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #2609 / #2683 / #2759
License MIT
Doc PR N/A
  1. The resource class resolver now works well with inheritance and is able to resolve resources using the ApiPlatform resource list (more clever work, was needed considering isResource is doing it!)
  2. This change adds a new feature: inherited items from API resources now are working as an API, a new behat test proves it
  3. some parts of ApiPlatform were not compatible because it does not uses the resource resolver but "get class" to get the resource, theses parts are also fixed

Notice: the cache from the resource class resolver is removed here. It was introduced in 2015 and was probably a great improvement, but since 2016 resources are not re-generated on each call to the factory but we call instead of a cache factory. This cache was just adding complexity so I removed it.

@Nek- Nek- changed the base branch from master to 2.4 April 7, 2019 13:32
Before this patch, when you configure an interface as resource the
serializer was not understanding the implementation was a resource.

It also fix the behavior of child of ApiResources that were not detected
as it.
@Nek- Nek- force-pushed the feature/resource-resolver-for-inheritance branch 5 times, most recently from a9b5d09 to acc9fda Compare April 7, 2019 18:24
Copy link
Member

@soyuka soyuka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job, few comments and we need to fix mongodb also.

/**
* @ORM\Entity
*/
class DummyTableInheritanceNotApiResourceChild extends DummyTableInheritance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NonApiResourceTableInheritedDummyChild would be better? @teohhanhui do you have a name in mind? :p

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, starting by "DummyTableInheritance" seems to have been a convention for similar objects.

/**
* {@inheritdoc}
*/
public function getIriFromItemWithResource($item, string $resourceClass, int $referenceType = UrlGeneratorInterface::ABS_PATH): string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about getIriFromItemWithContext? Where we'd add a $context['resource_class']? If we have other use cases in the future at least we won't have to change this interface again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any use case soon. I think it's confusing considering the main use case is to pass it from another context (serialization context). This seems good to me.

Also, I hate config-arrays. If you want it I'm in favor of creating a config object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just keep the same interface but add an optional argument that's commented out?

Copy link
Member

@soyuka soyuka May 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not, especially that it doesn't really make sense to not add the resourceClass to the getIriFromItem. We didn't really changed many interfaces though, isn't this a bit cleaner?

src/Bridge/Symfony/Routing/IriConverter.php Show resolved Hide resolved
* @param mixed $value Object you're playing with
* @param string $resourceClass Resource class it is supposed to be (could be parent class for instance)
* @param bool $strict value must be type of resource class given or it will return type
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For next reviewers I'm to keep these comment for future developers because it's hard to guess.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments need to be rewritten as they don't make much sense now.

"properties": {
"@type": {
"type": "string",
"pattern": "^DummyTableInheritance(Child)?$",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not really testing there is at least one child, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the tests are not actually testing the data considering they are verifying "any" of the given definitions. Scenarios are dependants. see #1724

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why the dependency between scenarios is an issue here.
You're right about the first part though. But maybe we can avoid this for this scenario?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why the dependency between scenarios is an issue here.

It's always an issue when you want to run 1 failing test case without running the whole suite. tests should respect the FIRST principle.

Copy link
Member

@alanpoulain alanpoulain Apr 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I agree with this. But I don't see the link with what I said.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are both types. But we should make sure DummyTableInheritanceChild is here at least once.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't wait to use #2608 would much more easier to deal with...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alanpoulain oh, it's possible to be sure the item is here at least once? How?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might be able use tuple validation maybe ? (that's only 3 items... https://json-schema.org/understanding-json-schema/reference/array.html#tuple-validation)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Nek- Nek- force-pushed the feature/resource-resolver-for-inheritance branch 5 times, most recently from 52a7bdf to f1bcbe4 Compare April 15, 2019 14:51
@Nek-
Copy link
Contributor Author

Nek- commented Apr 16, 2019

Appveyor is a liar. I'm pretty sure this is also cool on Windows! è_é

@Nek- Nek- force-pushed the feature/resource-resolver-for-inheritance branch 2 times, most recently from 6dcaee0 to 4956250 Compare April 27, 2019 17:55
@vincentchalamon vincentchalamon mentioned this pull request Apr 29, 2019
4 tasks
@Nek- Nek- force-pushed the feature/resource-resolver-for-inheritance branch from 4956250 to af70ddf Compare April 29, 2019 09:43
features/main/table_inheritance.feature Outdated Show resolved Hide resolved
"properties": {
"@type": {
"type": "string",
"pattern": "^DummyTableInheritance(Child)?$",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might be able use tuple validation maybe ? (that's only 3 items... https://json-schema.org/understanding-json-schema/reference/array.html#tuple-validation)

"type": "string",
"required": "true"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
},
"additionalProperties": false

and the same can be added in other tests to be more accurate

features/main/table_inheritance.feature Outdated Show resolved Hide resolved
features/main/table_inheritance.feature Outdated Show resolved Hide resolved
tests/Serializer/AbstractItemNormalizerTest.php Outdated Show resolved Hide resolved
tests/Api/ResourceClassResolverTest.php Outdated Show resolved Hide resolved
@teohhanhui
Copy link
Contributor

About the Behat test suite, I could only say most of the tests that use JSON Schema are wrong. I started fixing some of them in #2723 but I'm afraid it's been abandoned.

@Nek- Nek- force-pushed the feature/resource-resolver-for-inheritance branch 3 times, most recently from 2f0db8e to 674975f Compare May 2, 2019 14:52
Nek- added 2 commits May 2, 2019 16:54
This commits comes with many changes:

1. The resource class resolver now works well with inheritance and is
able to resolve resources using the ApiPlatform resource list (more
clever)
2. This change adds a new feature: inherited items from api resources
now are working as an api, a new behat test proves it
3. some parts of api platform were not compatible because it does not
uses the resource resolver but "get class" to get the resource, theses
parts are also fixed

Notice: the cache from the resource class resolver is removed here. It
was introduced in 2015 and was probably a great improvement, but since
2016 resources are not re-genarated on each call to the factory but we
call instead a cached factory. This cache was just adding complexity so
I removed it.
Previous commits fix the behavior with non api resources inherited from
resource but relation management was still not ok since the update was
not done on the abstract item normalizer.

The resource class resolver is now used as it should in every
normalizers.

Most of this commit (tests) comes from @vincentchalamon and its PR api-platform#2760
@Nek- Nek- force-pushed the feature/resource-resolver-for-inheritance branch from 674975f to 96d0556 Compare May 2, 2019 14:54
Copy link
Member

@soyuka soyuka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're almost there with this, let's keep the new interface for now.

@teohhanhui
Copy link
Contributor

teohhanhui commented May 3, 2019

Okay, so I think this is not ideal. Why don't we inject ResourceClassResolver into IriConverter? That way we can keep the old interface, and the caller does not need to care about which resource class to pass into IriConverter, as indeed that should not be their job. The IriConverter should know how to do its job.

@teohhanhui
Copy link
Contributor

teohhanhui commented May 3, 2019

See for example https://github.com/api-platform/core/blob/v2.4.2/src/EventListener/WriteListener.php#L80

Are we supposed to do the resource class resolving there? It makes no sense to me. As a caller, I have a resource item, and I want to get the IRI for it. That's all.

@soyuka
Copy link
Member

soyuka commented May 5, 2019

Sounds like a good alternative, wdyt @Nek- ?

@teohhanhui
Copy link
Contributor

teohhanhui commented May 6, 2019

But perhaps the IriConverter would need the attributes, if it needs to do something different based on the resource_class?

@@ -21,6 +21,8 @@
* Converts item and resources to IRI and vice versa.
*
* @author Kévin Dunglas <dunglas@gmail.com>
*
* @deprecated in favor of ResourceIriConverterInterface to be removed in ApiPlatform 3.0
Copy link
Member

@dunglas dunglas Apr 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm against deprecating this interface. It's the heart of API Platform.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think your concern is legit. We could add a new parameter to the existing method. It would lose a bit of its sense. But really I think you're right about that fact.

@Nek-
Copy link
Contributor Author

Nek- commented May 6, 2019

@teohhanhui I will give it a try as soon as I have the time for it. I don't really think it will work considering it will have a huge impact on the whole app. (actually, I was thinking about not deprecating the existing method).

@teohhanhui
Copy link
Contributor

I'm working on an alternative approach at #2797

@Nek-
Copy link
Contributor Author

Nek- commented May 16, 2019

@teohhanhui feel free to take tests

@teohhanhui
Copy link
Contributor

@Nek- Yes, I'll take the Behat tests. 😄

@teohhanhui
Copy link
Contributor

Replaced by #2797

Thanks @Nek- for your work! 😄

@teohhanhui teohhanhui closed this May 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants