Render an array based on accept header - Rob Allen


I'm currently working on an API using Slim 3 and needed a generic way to render arrays to XML, JSON or HTML based on the Request's Acceptheader.

This is just good practice. The Acceptheader is used by a client to specify the media types that it accepts. Therefore if our client would like XML, I'd like to give it XML. Similarly for JSON. I also like to support an HTML rendering on my API if I can as it makes exploration much easier.

This seemed like an ideal thing for a component and so I wrote rka-content-type-renderer ! (One day I'll work out how to name things, but for now, if it starts with rka, then it's probably a reusable component!)

It's PSR-7compliant because if you're going to write something that deals with HTTP nowadays, PSR-7 is the only sensible interface to target. Therefore, this component renders to a PSR-7's Response object's body.

Usage is really simple:

$data = ['items' => [['name' => 'Alex','is_admin' => true,],['name' => 'Robin','is_admin' => false,'link' => '',],],];$renderer = new /RKA/ContentTypeRenderer/Renderer();$response = $renderer->render($request, $response, $data);return $response->withStatus(200);

The $requestand $responseobjects must implement PSR-7's RequestInterfaceand ResponseInterfacerespectively. This makes it very easy to use within say Radar, Expressive, Slimor any other system that can bridge to PSR-7.

In this case, the output for JSON is:

{"items": [{"name": "Alex","is_admin": true},{"name": "Robin","is_admin": false,"link": "http:////"}]}

& for XML:

<?xml version="1.0"?><root> <items> <name>Alex</name> <is_admin>1</is_admin> </items> <items> <name>Robin</name> <is_admin>0</is_admin> <link></link> </items></root>

Finally, it will also render the array as an HTML unsigned list if the content-type is text/html which makes examining an API using a web browser very easy and worth doing:

items: 0: name:Alex is_admin:true 1: name:Robin is_admin:false link:

Obviously, in the HTML, we link any links so that the user can explore the API data, simply by clicking.

Hal support

While doing this, I also added support for rendering Nocarrier/Halobjects too as the HAL specificationsupports both JSON and XML, so it seems logical to send the correct format back to the client based on what they've asked for.

All in all, I've found this to be a useful component and if you have a similar need, then maybe this will help.