SuluHeadlessBundle
SuluHeadlessBundle copied to clipboard
Prevent resolving content twice for requests without .json suffix
At the moment, if a page that uses the HeadlessWebsiteController
is requested without the .json
suffix, the
controller will render the Twig of the page by reusing the functionality of the Sulu WebsiteController
. Additionally, the HeadlessWebsiteController
will set the data resolved by the StructureResolver
of the bundle to the attributes that are passed to the twig template.
This means, that the content of the page will be resolved two times if it is requested without the .json
suffix at the moment.
- The
HeadlessWebsiteController
uses theStructureResolver
to resolve the data into the headless format which might be passed to a single page application - The Sulu
WebsiteController
uses theParameterResolver
to resolve the date into the default format of Sulu which will be compatible with existing templates
This is not a great thing for performance, especially for big pages that are using expensive content types such as smart_content
. Unfortunately, I am not sure how to solve this in a flexible manner without neglecting DX. I think there are two relevant usecases of the bundle when thinking about an eventual solution:
1. Using the HeadlessWebsiteController
to provide an additional API for external applications
In this case, the bundle is used for providing an additional API for external applications such as mobile apps. The API will not used by the website itself. Instead, pages are still rendered via twig on a .html
request. This case is especially common if the bundle is added to an existing project with existing templates.
In this case, the data in the headless format is not used in the twig template and we would not need to call the StructureResolver
. One solution for this would be to make the the resolving of this data optional. For example, the HeadlessWebsiteController
would only call the StructureResolver
if some configuration is set or if the template of the page contains a tag like:
<tag name="sulu_headless.pass_headless_data_to_twig" value="true" />
2. Using the HeadlessWebsiteController
with a SPA that is started on the first request
In this case, the .html
request renders a minimal HTML document which starts a SPA. To prevent a second request when the SPA is initialized, the data of the page is passed to the SPA from the rendered HTML. Once the SPA is started, it will only make .json
requests to gather the content of pages.
In this case, the data in the headless format is used in the twig template to startup the SPA with the correct data. But the data in the default format of sulu is probably not needed. One solution for this would be to provide an additional PureHeadlessWebsiteController
that overwrites the getAttributes
method of the WebsiteController
which would call the ParameterResolver
:
class PureHeadlessWebsiteController extends HeadlessWebsiteController
{
protected function getAttributes($attributes, StructureInterface $structure = null, $preview = false)
{
return $attributes;
}
}
I am a bit sceptic about this solution because it makes the setup of the bundle more complicated. Also, I am not sure if it is worth to solve this case at all, because the twig template will only be rendered on the first request of the user anyway. After the first request, the SPA will only send .json
requests.