Walidowanie poprawności JSON-a

avatar icon
Tomasz Trybulewicz

Do wymiany danych między usługami, wielu programistów woli stosować format JSON jako bardziej czytelny i przyjemniejszy niż XML. Wielką zaletą JSON-a jest również niezwykła łatwość pracy z danymi przesyłanymi w ten sposób z poziomu języka JavaScript.

Dla mnie XML ma jednak wiele zalet - jedną z nich jest łatwość weryfikacji poprawności otrzymanego pliku. Sam fakt odczytania XMLa mówi nam że plik był poprawny składniowo. Taki plik można jeszcze sprawdzić pod względem poprawności strukturalnej względem definicji (np. opisanej za pomocą DTD, XML Schema czy RELAX NG).

W JSON-ie obecnie również można walidować poprawność strukturalną. Jednym ze sposobów na to jest format JSON Schema, którego wersję draft-04 pokrótce tu opiszę.

Przykładowa specyfikacja

Załóżmy że chcemy opisać proste API które zwraca informacje o wpisie na blogu w postaci:

{
    "id": 1,
    "title": "Hello World!",
    "content": "First post",
    "author_id": 123,
    "is_visible": true,
    "is_deleted": false,
    "tags": ["post", "sample", "test"]
}

Wszystkie pola niech będą wymagane. W takim wypadku JSON Schema przyjmie postać:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    “type”: “object”,
    "properties": {
        "id": {
            "type": "integer"
        },
        "title": {
            "type": "string"
        },
        "content": {
            "type": "string"
        },
        "author_id": {
            "type": "integer"
        },
        "is_visible": {
            "type": "boolean"
        },
        "is_deleted": {
            "type": "boolean"
        },
        "tags": {
            "type": "array",
            "elements": "string"
        }
    },
    "required": ["id", "title", "content", "author_id", "is_visible", "is_deleted", "tags"]
}

W ten oto sposób zdefiniowaliśmy, że opisujemy obiekt mający pola będące:
liczbami całkowitymi (id, author_id), napisami (title, content), wartościami logicznymi (is_visible, is_deleted) oraz tablicę napisów (tags).

Pełen opis specyfikacji oraz przykłady można znaleźć na stronie projektu JSON Schema.

Walidacja JSON Schema z poziomu PHP

Mając opisany sposób w jaki nasze API ma zwracać dane, sprawdźmy czy nasze API zwraca dane w prawidłowym formacie i postaci.
Do tego celu można znaleźć wiele projektów które walidują dane względem specyfikacji. Ja korzystam z json-schema który jest najaktywniej rozwijany.

Jeśli posiadasz composera, to instalacja powinna być dla Ciebie intuicyjna:

composer require justinrainbow/json-schema

Przykład z dokumentacji projektu pokazuje, jak najłatwiej sprawdzić poprawność danych:

    require_once('vendor/autoload.php');

    $retriever = new JsonSchema\Uri\UriRetriever;
    $schema = $retriever->retrieve('file://' . realpath('schema.json'));
    $data = json_decode(file_get_contents('data.json'));

    $validator = new \JsonSchema\Validator();
    $validator->check($data, $schema);

    if ($validator->isValid()) {
        echo "The supplied JSON validates against the schema.\n";
    } else {
        echo "JSON does not validate. Violations:\n";
        foreach ($validator->getErrors() as $error) {
            echo sprintf("[%s] %s\n", $error['property'], $error['message']);
        }
    }

Oczywiście w prawdziwych projektach warto wpiąć tego typu testy do zestawu testów funkcjonalnych naszej aplikacji - pozwoli to nam mieć pewność że nie zaskoczymy frontendowców dziwnymi wartościami.