I'm trying to create a REST endpoint, returning arbitrary XML with my own custom document root.
Much like my JSON endoints, I tried using ResourceResponse, which works ALMOST perfectly for XML.
If I create a REST endpoint, tell it to return XML, and ask it to return the result of:
$response = new ResourceResponse([
"foo" => [
"bar" => "baz",
"@hello" => "zoo"
]
], 200);
I get the following in response:
<?xml version="1.0"?>
<response>
<foo hello="zoo">
<bar>baz</bar>
</foo>
</response>
Very close! The problem is that tag. I want my own custom xml root.
Digging deep into the code, the fault appears to be in ResourceResponseSubscriber::renderResponseBody():
$serialization_context = [
'request' => $request,
CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY => new CacheableMetadata(),
];
$output = $serializer->serialize($data, $format, $serialization_context);
That $serialization_context gets passed all the way down to vendor/symfony/serializer/Encoder/XmlEncoder.php and would allow me to change the $xmlRootNodeName. But it's hard coded, and I have no way of modifying it.
Now, this is an event subscriber and I've seen a few people suggesting writing their own EventSubscriber, basically creating a new "xml" format which handles the root XML differently. But that feels like it's complete overkill.
Is there some better way of building an XML document as an endpoint? I know I can just render it as a string, but that also seems like a real waste.
A trivial solution might be to make a patch to ResourceResponse and ResourceResponseSubscriber to pass additional context, but I don't want to go this direction if there's a cleaner solution.