HTTP Request Validation With Silex

This article covers three validation scenarios:

  • routes
  • Query strings
  • POST with a JSON body

First lets start with some rough and ready example code. The following “snippet” creates a basic “RESTful” api using Silex.

The API is for retrieving emoji and has 3 end points:

  • [GET] /emoji/
  • [GET] /emoji/{id}
  • [POST] /emoji/

The code has a dependency on Silex and will use the built in Validator Provider from Silex and constraints from Symfony for validation. There is a repo on GitHub with the composer.json.

Sidebar on testing: quickly test the silex application with PHP’s built in web server by running “php -S localhost:8080 -t .” from the project’s route directory and then use Postman, curl or your browser.

Route Validation

The first validation to do is to make sure that the route variables can only match on certain requirements. This is done by adding a regex pattern to the route. The following snippet ensures that the “{id}” in “/emoji/{id}” can only be a positive integer:

If the assert doesn’t match then Silex will serve a 404 as long as no other route matches. This logic is the basis for all route variables and can be used to set up more complicated requirements. Check out the code in context on the repo.

GET Request Validation

The thing to bear in mind when validating the query string is that all the values are strings. This means that the validation code you use needs to treat everything as strings and then you cast/convert to the required type before usage.

Side bar on Constraints: map them “as Assert” this will make the code read better. To apply several constraints to one variable place them in an array. To apply constraints to indices in an associative array use the collection constraint. Also don’t forget to run `composer require symfony/validator`

Before using the asserts the code needs to have some GET query params laid out:

  • hasSkinTone: a boolean true or false
  • idBelow: any positive integer (a contrived example).

Then import the constraints and the validator provider:

Then build the assertions inside of the route:

Pass them to the validator along with the query bag:

Then process the error messages and return if any are found:

Otherwise filter the emoji using the query values:

The code there is a bit piecemeal so it might be clearer to view everything in context on the getrequest branch.

Side bar On Boolean Strings: For more on converting string values to boolean types check out “How To Evaluate String ‘False’ In PHP

POST Request Validation

Seeing as the POST data is limited to a JSON body the data has a type associated with it. This means the constraint class for type validation can be used instead of the regex constraint. There is also no need to cast the post data.

The POST data format is:

{
"id": 10,
"code": "U+1F4A9",
"value": "💩",
"description": "pile of poo",
"hasSkinTone": false
}

Then the validation code is pretty much the exact same the main thing to be aware of is that the JSON needs to be decoded and validated before being passed to the route. Taking all that in to account the route now looks like this:

View the whole thing in context on the postrequest branch.

Job Done

That’s the basics of route and request validation using Silex.