【问题标题】:How to validate structure of json using phpleague/json-guard如何使用 phpleague/json-guard 验证 json 的结构
【发布时间】:2017-10-20 11:20:13
【问题描述】:

我将 Laravel 5.4 用于 api,并且有一个接受 JSON 的端点:

{
    "input": {
        "owner": "name of owner",
        "content": [
        ] 
    }
}

我只想获取 input 中的 JSON,并确保它在结构上和基于内容上都是有效的。

使用http://json-guard.thephpleague.com 和他们来自overview 页面的基本示例,无论我如何更改输入,所有内容都会返回有效,因此我认为我使用错误。

根据他们的示例,我构建了以下内容。它通过了验证。问题是我不能让它失败。

路由文件

Route::post('validate', 'TestController@validateJson');

TestController@validateJson

public function validateJson()
{
    $dereferencer  = \League\JsonReference\Dereferencer::draft4();
    $schema        = json_decode('{ "properties": { "id": { "type": "string", "format": "uri" } } }');
    $data          = json_decode('{ "id": "https://json-guard.dev/schema#" }');

    $validator     = new \League\JsonGuard\Validator($data, $schema);

    if ($validator->fails()) {
        return response($validator->errors());
    }

    return response('all ok');
}

我相信我可能需要使用 JSON 参考并定义一个自定义架构,但在我完全理解该示例并让它失败之前,我不想做任何更复杂的事情。

【问题讨论】:

    标签: json validation laravel-5.4


    【解决方案1】:

    无论我如何更改输入,所有内容都会返回有效,因此我认为我使用错误。

    如果没有看到您尝试过的输入示例,就很难准确地说出问题出在哪里。由于示例架构验证 id 是具有 uri 格式的 string,因此当您提供不是有效 URI 的字符串时,它应该会失败。以下示例将返回格式错误:

    <?php
    
    require __DIR__ . '/vendor/autoload.php';
    
    $schema        = json_decode('{ "properties": { "id": { "type": "string", "format": "uri" } } }');
    $data          = json_decode('{ "id": "hello world" }');
    $validator     = new \League\JsonGuard\Validator($data, $schema);
    
    echo json_encode($validator->errors(), JSON_PRETTY_PRINT);
    

    JSON Schema 的某些部分不直观,您可能不会期望通过。

    约束仅验证它是否适用于该类型。如果您不通过对象验证将通过,因为properties 约束仅适用于对象:

    $data = null;
    var_dump((new \League\JsonGuard\Validator($data, $schema))->passes()); // true
    

    要使非对象输入失败,您需要指定"type": "object"。请注意,无效的 JSON 也会发生这种情况,因为 json_decode 将在失败时返回 null

    验证也将通过一个空对象:

    $data = json_decode('{}');
    var_dump((new \League\JsonGuard\Validator($data, $schema))->passes()); // true
    

    要使属性成为必需的,您必须使用 required 关键字。

    我只想获取内部输入的 JSON,并确保它在结构上和基于内容上都是有效的。

    这个架构应该作为一个起点:

    {
        "type": "object",
        "properties": {
            "input": {
                "type": "object",
                "properties": {
                    "owner": {
                        "type": "string",
                        "minLength": 1"
                    },
                    "content": {
                        "type": "array"
                    }
                },
                "required": ["owner", "content"],
                "additionalProperties": false
            }
        },
        "required": ["input"],
        "additionalProperties": false
    }
    

    我们要求输入是一个对象,它有一个输入属性并且没有其他属性,并且输入是一个具有属性所有者和内容的对象。 owner 的 minLength 规则是为了防止空字符串通过。

    我相信我可能需要使用 JSON 参考并定义自定义架构

    您可以编写非常复杂的模式,而无需使用 JSON 参考。这只是一种无需复制和粘贴即可重用模式的方法。例如,您可以定义一个“金钱”模式并将其用于 API 中的任何美元金额。

    您肯定需要编写自定义架构。该架构取代了您将为每个端点编写的 Laravel 验证规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-05
      • 2017-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-28
      • 1970-01-01
      相关资源
      最近更新 更多