This website uses cookies to ensure you get the best possible experience. See our Cookies Policy.

PMG Digital Made for Humans

Using Custom Symfony Validation Constraints to Clarify Business Logic

3 MINUTE READ | April 15, 2014

Using Custom Symfony Validation Constraints to Clarify Business Logic

Making sure that a web application’s forms consume the correct values is a big job. It’s gets even more difficult when you consider complex and ever changing business logic that often goes into an application.

When PMG builds PHP applications, we rely heavily on Symfony’s validator component to help use ensure that our apps take in and use valid values. The most powerful part of the validator component is the ability to create custom validation constraints to help encapsulate that logic.

The real strength of a custom validator is it’s name: a custom validator name can instantly convey why it exists and what it does. Symfony’s generic validation constraints are amazingly powerful, but they don’t really convey any sort of information about the business reasoning for their usage.

Let’s say you’re building an application that deals with bidding for animaginary ad network called Adze. Adze has some rules about bids:

  • To disable an ad, send an -1

     
    bid

  • All other bids must be between 0.1 and 100.0

This leave us with two possible valid bids: -1 or a number between 0.1 and 100.

So now we need to build a form that only takes in valid bids. The best wayto ensure the conditions above is probably to use an 

Expression
 constraint.

<?php
use SymfonyComponentValidatorConstraintExpression;

/** @var SymfonyComponentFormFormBuilderInterface $builder */
$builder->add('bid', 'text', [
    // ...
    'constraints'   => [
        new Expression([
            'expression'    => 'value == -1 or value >= 0.1 and value < 100',
            'message'       => 'Not a valid bid.'
        ]),
    ],
]);

There’s nothing wrong with this, but it’s not very reusable and it is very muchopaque to the very crucial question of why.

Here’s an example with a custom validator:

<?php
use AcmeAdzePlatformValidatorConstraintValidAdzeBid;

/** @var SymfonyComponentFormFormBuilderInterface $builder */
$builder->add('bid', 'text', [
    // ...
    'constraints'   => [
        new ValidAdzeBid(),
    ]
]);

This has several advantages:

  • The purpose of the constraint is clear: someone reading this code doesn’t need to puzzle out why the expression is what it is like they would have in the first example.

  • It’s reusable — if multiple bid inputs are accepted (like a file upload and along with a web form) the bid validation logic doesn’t need to recreated each time.

  • A custom constraint can provide better error messages about what’s wrong with the bid and give the user better feedback.

  • The bid validation logic is testable on its own without being tied to a specific usage.

Insights meet inbox

Sign up for weekly articles & resources.

Those benefits, especially testing, are huge. Not every set of constraints needs this sort of treatment, but critical and complex parts of an application can definitely benefit from it.


Posted by Christopher Davis

Related Content

thumbnail image

Get Informed

PMG Innovation Challenge Inspires New Alli Technology Solutions

4 MINUTES READ | November 2, 2021

Get Informed

Applying Function Options to Domain Entities in Go

11 MINUTES READ | October 21, 2019

thumbnail image

Get Informed

My Experience Teaching Through Jupyter Notebooks

4 MINUTES READ | September 21, 2019

Get Informed

Trading Symfony’s Form Component for Data Transfer Objects

8 MINUTES READ | September 3, 2019

Get Inspired

Working with an Automation Mindset

5 MINUTES READ | August 22, 2019

Get Informed

Parsing Redshift Logs to Understand Data Usage

7 MINUTES READ | May 6, 2019

Get Inspired

3 Tips for Showing Value in the Tech You Build

5 MINUTES READ | April 24, 2019

thumbnail image

Get Informed

Testing React

13 MINUTES READ | March 12, 2019

Get Inspired

Tips for Designing & Testing Software Without a UX Specialist

4 MINUTES READ | March 6, 2019

Get Informed

A Beginner’s Experience with Terraform

4 MINUTES READ | December 20, 2018

All POST