mrsuh/json-validation-bundle

This bundle provides a way to validate JSON in request/response against a schema

Installs: 6 461

Dependents: 0

Suggesters: 0

Security: 0

Stars: 17

Watchers: 2

Forks: 5

Open Issues: 3

Type:symfony-bundle

4.1.1 2023-03-30 20:15 UTC

This package is auto-updated.

Last update: 2024-10-30 01:53:52 UTC


README

A Symfony bundle that provides an annotation to validate request/response JSON against a schema.

Differences from joipolloi/json-validation-bundle

  • added response validation
  • supporting Symfony >=3.4, 4.*, 5.*, 6.*
  • error/warnings logging
  • single validator usage

Versions

  • ^3 for Symfony < 6.*
  • ^4 for Symfony >= 6.*

Installation

composer require mrsuh/json-validation-bundle ^4

Usage

Create validation schemes
See json-schema for more details

JsonSchema/Request/myAction.json

{
    "description": "Request JSON schema",
    "type": "object",
    "properties": {
        "test": {
            "type": "string",
            "minLength": 1
        }
    },
    "required": [ "test" ]
}

JsonSchema/Response/myAction.json

{
    "description": "Response JSON schema",
    "type": "object",
    "properties": {
        "test": {
            "type": "string",
            "minLength": 1
        }
    },
    "required": [ "test" ]
}

Create controller with annotations ValidateJsonRequest and/or ValidateJsonResponse
Specify $validJson argument if you want get decoded JSON data from the request
Specify the array type of the $validJson argument if you want get decoded JSON data as array
Specify the object type of the $validJson argument or don't specify type if you want get decoded JSON data as object

Controller/MyController.php

<?php

use Mrsuh\JsonValidationBundle\Annotation\ValidateJsonRequest;
use Mrsuh\JsonValidationBundle\Annotation\ValidateJsonResponse;
use Symfony\Component\HttpFoundation\JsonResponse;

class MyController
{
    /**
     * @ValidateJsonRequest("JsonSchema/Request/myAction.json", methods={"POST"}, emptyIsValid=true)
     * @ValidateJsonResponse("JsonSchema/Response/myAction.json", statuses={"200"}, emptyIsValid=true)
     */
    public function myAction(array $validJson): JsonResponse
    {
        return new JsonResponse($validJson);
    }
}

Invalid JSON passed to request

If invalid JSON passed to request and config enable_request_listener, enable_exception_listener enabled
you get response as detailed in RFC7807 with header Content-Type:application/problem+json and error log entry

{
    "detail": "There was a problem with the JSON that was sent with the request",
    "errors": [
        {
            "constraint": "minLength",
            "context": 1,
            "message": "Must be at least 1 characters long",
            "minLength": 1,
            "pointer": "/test",
            "property": "test"
        }
    ],
    "status": 400,
    "title": "Unable to parse/validate JSON"
}
app.ERROR: Json request validation {"uri":"http://127.0.0.1:8000/my","schemaPath":"JsonSchema/Request/myAction.json","errors":[{"property":"test","pointer":"/test","message":"Must be at least 1 characters long","constraint":"minLength","context":1,"minLength":1}]} []

Invalid JSON passed to response

If invalid JSON passed to response and config enable_response_listener enabled
you get warning log entry

app.WARNING: Json response validation {"uri":"http://127.0.0.1:8000/my","schemaPath":"JsonSchema/Response/myAction.json","errors":[{"property":"test","pointer":"/test","message":"Must be at least 1 characters long","constraint":"minLength","context":1,"minLength":1}]} []

Configuration

mrsuh_json_validation:
    enable_request_listener: true #default value
    enable_response_listener: true #default value
    enable_exception_listener: true #default value

Single validator usage

<?php

use Mrsuh\JsonValidationBundle\JsonValidator\JsonValidator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class MyController
{
    public function myAction(Request $request, JsonValidator $validator): Response
    {
        $validator->validate($request->getContent(), 'JsonSchema/Request/myAction.json');
        $errors = $validator->getErrors();
        if(!empty($errors)) {
            // do something with errors
        }
        
        return new Response();
    }
}