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

A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. Use of any information from my blog posts should be at own risk and I do not hold any liability towards any information misuse or damages caused by following any of my posts.

All content and opinions expressed on this Blog are my own and do not represent the opinions of my employer (Oracle). Use of any information contained in this blog post/article is subject to this disclaimer.
Hi! You can search my blog here ⤵
NOTE: (2022) This Blog is no longer maintained and I will not be answering any emails or comments.

I am now focusing on Atari Gamer.