Ability to specify the site for a request #16367
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Adds the ability to specify the current site via an
X-Craft-Site
HTTP header.The need for this feature is apparent in headless projects where the front end and control panel are decoupled.
Example project setup
example.com
example.com
,example.com/us
,example.com/uk
etc)cms.example.com
headlessMode
config setting is set totrue
In this setup requests from the headless front end will be sent to the control panel. With the fact that
headlessMode
is on and the base site URLs are separate from the control panel, it means there is a need for extra steps for making site-specific requests.Taking the element API plugin requests as an example with the following config in
element-api.php
A request to
cms.example.com/articles.json
will return entries with thesiteId
for the primary site. Because of the decoupled natured of the project you can't callcms.example.com/uk/articles.json
as there is no routing for that.It, of course, would be possible to pass the site handle as a parameter to the endpoint and then this would need to be done for all of the endpoints. The developer would also need to pass that parameter to everything else they were doing (say if there were other element queries in the transformer).
This PR adds the header
X-Craft-Site
(a site handle) to be able to tell Craft that the whole request is for a specified site. This way it can be done once, there is no need to pass around a handle/ID to each thing that happens. The current site will be set to the one in the header and things (element queries etc) will work as if it was that site was being requested (and be more like a non-headless implementation).The above example is for the Element API plugin but this method will also work if you are calling the GraphQL endpoint as well. Again, the developer could specify the
site
orsiteId
in the GQL query but with this method only header would be needed.The PR would also benefit Commerce. Commerce has front end controller actions that are currently looking at the requested site to figure out the store and set other data on products, orders etc. All of these actions could be updated to pass around a site ID/handle, making sure to pass down that data throughout all the code ensuring no site related queries are missed. However, with the feature outlined in this PR, those controllers and code would not need to change.
A couple of final notes.
I debated whether this should be a parameter (
site
) that could be specified in a query string or body or if it should be a header. I settled on a header due to the fact that it would be a new concept that wouldn't cause any conflicting issues with current code in projects.The issue that this PR solves only shows itself in projects that are set up as highlighted above. There is a possibility that this could be a header that only is used with
headlessMode
on. But there could potentially be projects setup where the front end and CP are decoupled but the project isn't truly "headless"