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

On-demand REST resource embedding #1741

Conversation

bdunogier
Copy link
Member

@bdunogier bdunogier commented Jul 25, 2016

Implements EZP-26033
Specification
Mostly ready for review and testing, one minor (deprecation) todo list item remaining

See the specification for a full technical description of the feature and its implementation.

TODO

  • Rename the value loader, with an interface (HrefRestResourceLoader ?)
  • Cover multi media-type (example: Location.Content loads a ContentInfo. The media-type attribute must be used for the value load request.
  • Apply to other visitors once approved
  • Update specification
  • Design and implement Request format (x-ez-embed-value header)
  • Add unit test for the loader
  • Add support for lists in request format
  • Prevent listElement from showing up twice in the stackPath
  • Update existing tests that break
  • Handle automatic parent expansion in request format (ex: Content.Owner.MainLocation implies automatic expansion of Owner first).
  • Add unit test for the ResourceLink and ResourceRouteReference visitors
  • Add a custom attribute to the reference if loading failed (permissions or multiple load).
  • Add a recursion protected value loader, that refuses to load the same resource more than once. When it happens, throws an exception.
  • Look for remaining $this->generator->generate() calls in visitors that need replacing
  • Rename the parameters property in ResourceRouteReference
  • Add unit test for UniqueUriValueLoader
  • Deprecate the old way to visit stuff, if it turns out to be necessary
  • Rename to REST include to align with JSON API concept wise where query is used instead of header simplifying use/examples

@bdunogier bdunogier changed the title Ezp26033 rest embedding prototype v2 uri based value loading Rest embedding prototype v2 Jul 25, 2016
@bdunogier bdunogier force-pushed the ezp26033-rest_embedding_prototype-v2_uri_based_value_loading branch from 2656556 to 071196d Compare July 25, 2016 16:19
@glye
Copy link
Member

glye commented Jul 26, 2016

Looks good, insofar as less code to write, test and maintain.

@yannickroger
Copy link
Contributor

I like it ! 😄

@pspanja
Copy link
Contributor

pspanja commented Jul 28, 2016

Would it be possible to have a Loader implementation using HttpKernel, making proper sub-requests with ESI?

@bdunogier bdunogier force-pushed the ezp26033-rest_embedding_prototype-v2_uri_based_value_loading branch from 2fe59ef to a9d6ff1 Compare August 25, 2016 10:51
@bdunogier
Copy link
Member Author

bdunogier commented Aug 25, 2016

@pspanja I need to think about it again (it was like a month ago now), but in my vision of this architecture, yes, this was achievable.

I'll be happy to discuss the details with you.

@andrerom
Copy link
Contributor

andrerom commented Aug 26, 2016

I'm assuming @pspanja asks to be able to keep documents separated in Proxy cache to get best possible cache efficiency.

One alternative we could explore is HTTP/2 server push, but I have no idea how Varnish behaves with that. At least with ESI it will be able to. It's just more tricky to get the resulting json(/xml..) document to be valid.

@bdunogier
Copy link
Member Author

Well, there are two main ways to see this:

  1. generate ESI tags in the response, and let the reverse proxy handle it
  2. use HttpKernel (I guess that's what @pspanja meant) during rendering to load the payload of embedded resources.

Problem with 2 is that it doesn't really improve caching: the root resource that is requested will still be cached as a whole, still requiring multi-tagging.

1 is a solution I did think about when specifying this feature, but it has a few implications. The two main ones are making sure that the embedded payload is valid in the context of the parent (XML header for instance), and being able to specify the output format (XML/JSON) by means of an URL alone. We currently do it via the Accept header. Url would require that we add support for .json / .xml.

@bdunogier
Copy link
Member Author

Refactored checking of expansion to a dedicated service, with use-cases in a unit-test: https://github.com/ezsystems/ezpublish-kernel/pull/1741/files#diff-675a7b1950edeb252504e0978c6065e4R50. It specifies how lists content expansion is requested, as well as automatic parent loading.

@bdunogier bdunogier force-pushed the ezp26033-rest_embedding_prototype-v2_uri_based_value_loading branch 4 times, most recently from 7f3bc6e to dfcfe45 Compare September 1, 2016 11:27
- `Content.Owner.Groups`

### Permissions
If the user doesn't have the required permissions to load an embedded
Copy link
Contributor

Choose a reason for hiding this comment

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

could we have something a bit more explicit instead ? Also, it's not written anywhere but I guess the same will happen if for instance the embedded object has been removed (for instance the Owner of a Content Item) ? Ideally, the REST consumer should be able to differentiate those 2 cases. For instance, an attribute on the link would work well I think

Copy link
Member Author

@bdunogier bdunogier Sep 1, 2016

Choose a reason for hiding this comment

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

An attribute on the link is easy. Any preferred format/contents ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added a TODO in any case.

@bdunogier bdunogier changed the title Rest embedding prototype v2 On-demand REST resource embeddoing Sep 1, 2016
@bdunogier bdunogier changed the title On-demand REST resource embeddoing On-demand REST resource embedding Sep 1, 2016
@bdunogier bdunogier force-pushed the ezp26033-rest_embedding_prototype-v2_uri_based_value_loading branch 5 times, most recently from 68a9e26 to 428d52f Compare September 2, 2016 23:10
main location object embedded into the response:

```
curl -X GET http://localhost:8000/api/ezp/v2/content/objects/1 -H 'Cookie: XDEBUG_SESSION=PHPSTORM' -H 'x-ez-embed-value: Content.MainLocation'
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: You can remove 'Cookie: XDEBUG_SESSION=PHPSTORM'

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point :-)

Bertrand Dunogier added 3 commits September 5, 2016 15:44
Based on a value object's REST URI, loads a value object using the controller
action for this URI.
Bertrand Dunogier added 8 commits September 5, 2016 15:44
Used by ValueObjectVisitors to generate a link to a ValueObject.
The visitor may expand the link to a full featured object.
Reverts an old refactoring: visiting a value object requires again that the visitor and generator are passed as arguments.
A decorator for the OutputGenerator that skips the root object element as well as its attributes.
@bdunogier bdunogier force-pushed the ezp26033-rest_embedding_prototype-v2_uri_based_value_loading branch 2 times, most recently from 4ea151e to 83baf8b Compare September 5, 2016 13:46
@bdunogier bdunogier force-pushed the ezp26033-rest_embedding_prototype-v2_uri_based_value_loading branch from 83baf8b to 77c6903 Compare September 5, 2016 13:47
@bdunogier
Copy link
Member Author

bdunogier commented Sep 13, 2016

@pcardiga we should talk about it further, but I think that the feature can be tested by QA.

It won't work for the time being with HTTP cache (as in cache will be stale until ttl expires on embed data), but we have planned on covering that with @andrerom's work. But meanwhile, the feature itself can be tested in order to check that it matches the specifications, I think.

@yannickroger
Copy link
Contributor

Just a note. We should not merge this until we started prototyping the JS Client (and also maybe platform UI) to benefit from this patch. We need to have a real feedback on its usage before having to keep BC on it for a long time.

So before this has been done, I am -1 on merging this.

@bdunogier
Copy link
Member Author

It can not be merged (or at least used) before HTTP cache multi-tagging is implemented as well anyway, Yannick.

@dpobel
Copy link
Contributor

dpobel commented Oct 12, 2016

The PR ezsystems/PlatformUIBundle#687 uses this branch. As written there, I think there are 2 issues:

  1. it seems like the ContentInfo has been removed from the Location response. This is breaking some parts of PlatformUI.
  2. there's a recursion protection which prevents the system from embedding the same object several times. For instance 2 versions can have the same creator (or you can have 2 drafts for the same Content) and this is something very complicated to handle in the PlatformUI.

main location object embedded into the response:

```
curl -X GET http://localhost:8000/api/ezp/v2/content/objects/1 -H 'x-ez-embed-value: Content.MainLocation'
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be possible to instead use query param and align with JSON API? Or are there some implementation details that makes it hard to use query param?

As in:

curl -X GET http://localhost:8000/api/ezp/v2/content/objects/1?include=Content.MainLocation

Copy link
Contributor

Choose a reason for hiding this comment

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

(using header will make it hard to cache for instance)

@andrerom andrerom mentioned this pull request May 23, 2017
3 tasks
@andrerom
Copy link
Contributor

andrerom commented Nov 6, 2017

Regarding the http/2 point earlier, it's pretty much here by now: https://blog.apisyouwonthate.com/lets-stop-building-apis-around-a-network-hack-9a68f7e83dd2 (a very oponionated blog, but worth the read to see how it could work)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

7 participants