【问题标题】:How to validate required items of JSON SCHEMA array如何验证 JSON SCHEMA 数组的必需项
【发布时间】:2016-08-04 13:10:12
【问题描述】:

我有一个新订单的 JSON Schema,它由订单列表和地址组成。

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array",
  "properties": {
    "order": {
      "type": "array",
      "items": {
        "type": "array",
        "properties": {
          "product_id": {
            "type": "integer"
          },
          "quantity": {
            "type": "integer"
          }
        },
        "required": [
          "product_id",
          "quantity"
        ]
      }
    },
    "address": {
      "type": "array",
      "properties": {
        "name": {
          "type": "string"
        },
        "phone": {
          "type": "integer"
        },
        "address1": {
          "type": "string"
        },
        "address2": {
          "type": "string"
        },
        "city": {
          "type": "string"
        },
        "state_or_region": {
          "type": "string"
        },
        "country": {
          "type": "string"
        }
      },
      "required": [
        "name",
        "phone",
        "address1",
        "city",
        "state_or_region",
        "country"
      ]
    }
  },
  "required": [
    "order",
    "address"
  ]
}

但它似乎根本没有真正验证这些项目(我使用 Laravel 5.2"justinrainbow/json-schema": "~2.0" ):

$refResolver = new \JsonSchema\RefResolver(new \JsonSchema\Uri\UriRetriever(), new \JsonSchema\Uri\UriResolver());
$schema = $refResolver->resolve(storage_path('schemas\orders.post.json'));

$errors = [];
$input = Request::input();

// Validate
$validator = new \JsonSchema\Validator();
$validator->check($input, $schema);

$msg = [];
if ($validator->isValid()) {
    return Response::json(['valid'], 200, [], $this->pritify);
} else {
    $msg['success'] = false;
    $msg['message'] = "JSON does not validate";
    foreach ($validator->getErrors() as $error) {
        $msg['errors'][] = [
            'error' => ($error['property'] = ' ') ? 'wrong_data' : $error['property'],
            'message' => $error['message']
        ];
    }
    return Response::json($msg, 422, [], $this->pritify);
}

这样的请求总是有效的:

{
    "order": [
        {
            "product_id": 100,
            "quantity": 1
        },
        {
            "product_id": 0,
            "quantity": 2
        }
    ],
    "address": []
}

任何想法我做错了什么?

【问题讨论】:

  • jsonlint.com 。我的 IDE 在 "country" 之后的括号后抛出了关于尾随逗号的错误
  • 抱歉,已删除。还有更多需要验证,这是一个简短的示例

标签: php json laravel jsonschema


【解决方案1】:

您弄乱了数组和对象类型。方案中唯一的数组值必须是 order。固定方案:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "order": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer"
          },
          "quantity": {
            "type": "integer"
          }
        },
        "required": [
          "product_id",
          "quantity"
        ]
      }
    },
    "address": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "phone": {
          "type": "integer"
        },
        "address1": {
          "type": "string"
        },
        "address2": {
          "type": "string"
        },
        "city": {
          "type": "string"
        },
        "state_or_region": {
          "type": "string"
        },
        "country": {
          "type": "string"
        }
      },
      "required": [
        "name",
        "phone",
        "address1",
        "city",
        "state_or_region",
        "country"
      ]
    }
  },
  "required": [
    "order",
    "address"
  ]
}

我在测试数据中遇到的验证错误:

JSON does not validate. Violations:
[address.name] The property name is required
[address.phone] The property phone is required
[address.address1] The property address1 is required
[address.city] The property city is required
[address.state_or_region] The property state_or_region is required
[address.country] The property country is required

【讨论】:

  • 嗯,但在这种情况下我得到"Array value found, but an object is required",因为$input = Request::input(); 创建了一个类似结构的数组
  • 在您的数据示例中 "address": [] 但它将是类似 "address": {"name": "Kostya"} 的对象,因此您的验证错误也是正确的。我相信所有的困惑都是因为 PHP 空数组可以表示为 JSON 空数组或 JSON 空对象,但 PHP 关联数组只能表示为 JSON 对象。
  • 谢谢。我认为这就是 Laravel 处理请求的方式。我通过在请求后添加$input = json_decode(json_encode($input)); 解决了这个问题。
猜你喜欢
  • 2020-02-05
  • 1970-01-01
  • 1970-01-01
  • 2015-10-24
  • 1970-01-01
  • 2021-10-21
  • 2018-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多