Preskočiť na obsah

Príklad: parametre a validácia ​

Zoznam používateľov s filtrami, GET /api/v1/users, a vytvorenie používateľa s JSON telom, POST /api/v1/users.

Otvoriť diagram v plnej veľkosti

Query parametre ​

php
<?php

declare(strict_types=1);

namespace App\Api;

use App\UserRepository;
use Tomaj\NetteApi\Handlers\BaseHandler;
use Tomaj\NetteApi\Output\JsonOutput;
use Tomaj\NetteApi\Params\GetInputParam;
use Tomaj\NetteApi\Response\JsonApiResponse;
use Tomaj\NetteApi\Response\ResponseInterface;
use Tomaj\NetteApi\Validation\InputType;

final class UserListHandler extends BaseHandler
{
    public function __construct(private UserRepository $users)
    {
        parent::__construct();
    }

    public function summary(): string
    {
        return 'List users';
    }

    public function tags(): array
    {
        return ['users'];
    }

    public function params(): array
    {
        return [
            // ?status=active, only the listed values pass
            (new GetInputParam('status'))
                ->setAvailableValues(['active', 'blocked'])
                ->setDescription('Only users with this status'),
            // ?id[]=1&id[]=3, every item must be an integer
            (new GetInputParam('id', InputType::INTEGER))
                ->setMulti()
                ->setDescription('Only users with these ids'),
            // ?limit=2, converted to int before handle() gets it
            (new GetInputParam('limit', InputType::INTEGER))
                ->setDefault(10)
                ->setDescription('Maximum number of users'),
        ];
    }

    public function handle(array $params): ResponseInterface
    {
        // a value that is not numeric (?limit=abc) arrives as null, not as an error
        $limit = $params['limit'] ?? 10;
        $users = $this->users->find($params['status'], $params['id'] ?? [], $limit);
        return new JsonApiResponse(200, ['users' => $users]);
    }

    public function outputs(): array
    {
        return [
            new JsonOutput(200, (string) file_get_contents(__DIR__ . '/schema/user-list.json'), 'The matching users'),
        ];
    }
}
  • status povoľuje len active alebo inactive; ?status=deleted vráti 400.
  • id má viac hodnôt, ?id[]=2&id[]=3.
  • limit je celé číslo. ?limit=abc v 3.x nie je chyba: hodnota sa zmení na null a handler použije 10. Pozrite si Parametre.

JSON telo ​

php
<?php

declare(strict_types=1);

namespace App\Api;

use App\UserRepository;
use Tomaj\NetteApi\Handlers\BaseHandler;
use Tomaj\NetteApi\Output\JsonOutput;
use Tomaj\NetteApi\Params\JsonInputParam;
use Tomaj\NetteApi\Response\JsonApiResponse;
use Tomaj\NetteApi\Response\ResponseInterface;

final class UserCreateHandler extends BaseHandler
{
    public function __construct(private UserRepository $users)
    {
        parent::__construct();
    }

    public function summary(): string
    {
        return 'Create a user';
    }

    public function tags(): array
    {
        return ['users'];
    }

    public function params(): array
    {
        return [
            // the whole request body, validated against a JSON schema
            (new JsonInputParam('user', (string) file_get_contents(__DIR__ . '/schema/user-create.json')))
                ->setRequired()
                ->addExample('Alice', ['name' => 'Alice', 'email' => 'alice@example.com']),
        ];
    }

    public function handle(array $params): ResponseInterface
    {
        $user = $this->users->add($params['user']['name'], $params['user']['email']);
        return new JsonApiResponse(201, ['user' => $user]);
    }

    public function outputs(): array
    {
        return [
            new JsonOutput(201, (string) file_get_contents(__DIR__ . '/schema/user.json'), 'The new user'),
        ];
    }
}
json
{
    "type": "object",
    "properties": {
        "name": { "type": "string", "minLength": 1 },
        "email": { "type": "string", "format": "email" }
    },
    "required": ["name", "email"],
    "additionalProperties": false
}

Chýbajúci email, pokazený JSON alebo prázdne telo vráti 400.

Test ​

bash
#!/usr/bin/env bash
# End-to-end check: valid and invalid query parameters and JSON bodies.
set -euo pipefail
cd "$(dirname "$0")"
[[ -f vendor/autoload.php ]] || { echo "fail: vendor/ is missing, run composer install first" >&2; exit 1; }
source ../ci/lib.sh
serve 8082

request "$BASE/api/v1/users?status=active&limit=1"
expect_status 200 "filtered list"
expect_body '{"users":[{"id":1,"name":"Alice","email":"alice@example.com","status":"active"}]}' "filtered list"
ok "GET ?status=active&limit=1 returns one active user"

request "$BASE/api/v1/users?id%5B%5D=2&id%5B%5D=3"
expect_status 200 "multi id"
expect_body '"name":"Bob"' "multi id"
expect_body '"name":"Carol"' "multi id"
ok "GET ?id[]=2&id[]=3 returns both users"

request "$BASE/api/v1/users?status=deleted"
expect_status 400 "value outside setAvailableValues"
expect_body '"message":"wrong input"' "value outside setAvailableValues"
expect_body '"status":["Field contains not available value(s)"]' "value outside setAvailableValues"
ok "GET ?status=deleted answers 400 with the field error"

request "$BASE/api/v1/users?limit=abc"
expect_status 200 "non-numeric integer"
expect_body '"name":"Carol"' "non-numeric integer"
ok "GET ?limit=abc passes as null, the handler falls back to 10"

request "$BASE/api/v1/users?id%5B%5D=x"
expect_status 200 "non-numeric multi item"
ok "GET ?id[]=x passes too, the item becomes null"

request -X POST -H 'Content-Type: application/json' -d '{"name":"Dave","email":"dave@example.com"}' "$BASE/api/v1/users"
expect_status 201 "valid body"
expect_body '"user":{"id":4,"name":"Dave","email":"dave@example.com","status":"active"}' "valid body"
ok "POST a valid body answers 201"

request -X POST -H 'Content-Type: application/json' -d '{"name":"Dave"}' "$BASE/api/v1/users"
expect_status 400 "missing property"
expect_body 'The property email is required' "missing property"
ok "POST without email answers 400 with the schema error"

request -X POST -H 'Content-Type: application/json' -d '{"name":' "$BASE/api/v1/users"
expect_status 400 "broken JSON"
expect_body '"user":["Syntax error"]' "broken JSON"
ok "POST broken JSON answers 400"

request -X POST "$BASE/api/v1/users"
expect_status 400 "empty body"
expect_body '"user":["missing data"]' "empty body"
ok "POST without a body answers 400"

Časté otázky ​

Čo obsahuje odpoveď 400? ​

{"status":"error","message":"wrong input"} a pri zapnutých detailoch chyby jednotlivých polí v detail. Pozrite si Parametre.

Prečo sú deklarované aj výstupy? ​

Zoznam aj vytvorený používateľ sa pri vývoji kontrolujú voči user-list.json a user.json. Pozrite si Výstupy.

Ako urobím parameter povinným? ​

Zavolajte setRequired(). Chýbajúca hodnota vráti 400 s Field is required.

Môžem namiesto JSON validovať POST formulár? ​

Pre každé pole použite PostInputParam. Pozrite si Parametre.

Zobrazia sa schémy v OpenAPI? ​

Áno, ako schémy tela požiadavky a odpovede. Pozrite si OpenAPI.

Vydané pod licenciou MIT.