Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

When I first started working on the backend APIs for AtariGamer.com I had to write code that converted JSON input strings sent by the client side into something that the Controller code could use. After adding a few APIs and Controllers it became apparent that I was just repeating the same code over and over so I decided to look for a better, more flexible option. My search ended with with the Silex Middleware feature, specifically the before Middleware.

On the client side I was using Backbone.js to manage all of the entities and generate the required JSON objects to send to the Silex based backend. This meant that the Controller would receive a string representation of the object it had to process. The parsing of this string was trivial of course but it was repeated code across all of the Controllers (actually just the POST/PUT/PATCH Controllers, but that was still a large part of the code base). It also meant that if I wanted to change how I handled input, it would need to be done in many classes.

I wanted to have a single place, outside of the Controller code (not a utility method) that parsed the input and exposed it in a way that the Controller could understand.

This was the kind of input JSON data that was sent (just an example with formatting applied)...
 JSON
{
"gameId":"1513416078",
"category":"1",
"type":"0",
"cartType":"3"
}


To process something like that I added a before Middleware that intercepted and converted the input, for the appropriate methods. It looked something like this:
 PHP
/* decode JSON data for API requests */
$app->before(function (Request $request) {
$method = $request->getMethod();
/* POST, PUT, PATCH */
if (in_array($method,
[Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH]))
{
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
$data = json_decode($request->getContent(), true);
$request->request->replace(is_array($data) ? $data : array());
}
}
});




What the above code did was it first checked whether the submit method was one of POST, PUT or PATCH. It then checked that the content type header was set to 'application/json'. Once both of those conditions were satisfied, the request body content was parsed as a JSON object and converted into an associative array.

Finally, the request parameter list was set to the associative array via the Symfony Request object replace() function. If the string could not be parsed as valid JSON input, an empty array was used instead.

Now it was possible to access each of the JSON object properties as if it was sent in as a standard POST parameter. For example, I could retrieve the 'gameId' property value like so...
 PHP
function upsert(Request $request, Application $app, $id = null) {
$r = $request->request;
$r->get('gameId');
...
}


None of the Controllers had to deal with any JSON string to object conversion any longer!

I've since expanded the before Middleware to do a similar treatment for GET query parameters and added other handy features that I needed like request path validation, etc.

-i

Hope you found this post useful...

...so please read on! I love writing articles that provide beneficial information, tips and examples to my readers. All information on my blog is provided free of charge and I encourage you to share it as you wish. There is a small favour I ask in return however - engage in comments below, provide feedback, and if you see mistakes let me know.

If you want to show additional support and help me pay for web hosting and domain name registration, donations, no matter how small, are always welcome!

Use of any information contained in this blog post/article is subject to this disclaimer.
comments powered by Disqus
Other posts you may like...