codeasashu / openapi-validator
验证数据是否符合提供的openapi规范
1.0.0
2019-09-21 18:04 UTC
Requires
- php: >=7.0
- justinrainbow/json-schema: ^5.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.13
- phpunit/phpunit: ^6.5
- symfony/yaml: ^3.4
README
验证数据是否符合 openapi v3规范
功能
- 检查必填字段
- 检查数据类型
- 支持嵌套结构
- 支持区分符
- 支持allOf, anyOf
- 支持可为空
- 解析本地引用(组件)
- 支持additionalProperties
与Dredd不同,它不需要示例,也不检查数据是否与示例匹配
安装
composer req --dev mmal/openapi-validator
要求
您的openapi规范必须有效,您可以使用Speccy先检查您的模式
此库假设每个操作都有operationId
示例
假设我们有一个由以下OpenAPI规范描述的api
openapi: 3.0.2 info: title: Cards description: Cards and decks api contact: name: Mieszko Malawski license: name: GNU AGPLv3 url: https://gnu.ac.cn/licenses/agpl.txt version: 1.0.0 tags: - name: Cards paths: /cards: summary: Path used to manage the list of cards. description: The REST endpoint/path used to list and create zero or more card entities. This path contains a GET and POST operation to perform the list and create tasks, respectively. get: tags: - Cards summary: List All cards description: Gets a list of all card entities. operationId: getcards responses: 200: description: Successful response - returns an array of card entities. content: application/json: schema: type: array items: $ref: '#/components/schemas/card' components: schemas: card: title: Root Type for card description: The root of the card type's schema. required: - id - name - power type: object properties: id: description: "unique id" type: string format: int64 readOnly: true name: type: string power: description: "how powerfull card is on the board" format: int32 type: integer example: id: "23423423" name: "Geralt" power: 10
我们有服务器实现(这当然是一个示例 - 通常您会从某些存储中获取数据)
<?php declare(strict_types=1); namespace AppBundle\Controller; use GOG\Common\OAuthSecurityBundle\Controller\OAuthController; use Symfony\Component\HttpFoundation\JsonResponse; class CardsController extends OAuthController { public function getCardsAction() { return new JsonResponse( [ [ 'id' => '123123', 'name' => 'Geralt', 'power' => 10, ], [ 'id' => '45653', 'name' => 'Vernon Roche', 'power' => 10, ] ] ); } }
如何验证服务器实现按描述工作?使用openapi-validator与任何HTTP客户端
<?php declare(strict_types=1); namespace AppBundle\Tests\Controller; use Mmal\OpenapiValidator\Validator; use Symfony\Component\Yaml\Yaml; class CardsControllerTest extends BaseControllerTest { const SPEC_PATH = __DIR__.'/../../../../docs/api.yml'; /** @var Validator */ static $openaApiValidator; static public function setUpBeforeClass() { parent::setUpBeforeClass(); self::$openaApiValidator = new Validator(Yaml::parse(self::SPEC_PATH)); } public function testGetCards() { $this->makeRequest('GET', '/cards'); } protected function makeRequest($method, $uri, $content = '') { $client = $this->getTestClient(); $client->request( $method, $uri ); $response = $client->getResponse(); $result = self::$openaApiValidator->validateBasedOnRequest( $uri, $method, $response->getStatusCode(), json_decode($response->getContent(), true) ); self::assertFalse($result->hasErrors(), $result); return RESTResponse::fromHTTPResponse($response); } }
- 将您的规范加载到验证器中
- 使用任何HTTP客户端发送请求
- 将请求URI、请求方法、响应代码和响应体传递给验证器(可选地,媒体类型,默认为application/json)
- 验证器将确定对于方法'GET'、路径'/cards'和响应代码200,所需的响应模式是
card: title: Root Type for card description: The root of the card type's schema. required: - id - name - power type: object properties: id: description: "unique id" type: string format: int64 readOnly: true name: type: string power: description: "how powerfull card is on the board" format: int32 type: integer example: id: "23423423" name: "Geralt" power: 10
- 实际响应体将根据该模式进行验证
- 将生成结果对象,如果响应无效,则结果对象将包含错误
在这种情况下,响应是有效的
现在让我们引入一些错误
public function getCardsAction() { return new JsonResponse( [ [ 'id' => '123123', 'name' => 'Geralt', 'power' => 10, ], [ // 'id' => '45653', 'name' => 'Vernon Roche', 'power' => 10, ] ] ); }
第二个项目的必填字段id缺失
让我们再破坏一些其他东西
public function getCardsAction() { return new JsonResponse( [ [ 'id' => '123123', 'name' => 'Geralt', 'power' => 10, ], [ 'id' => '45653', 'name' => 'Vernon Roche', 'power' => '10', ] ] ); }
power字段应该是整数(第二个项目)
其他库
待办事项
- 支持所有openapi格式
- 支持not关键字
这是如何工作的?
将openapi规范转换为json模式,然后使用justinrainbow/json-schema进行验证


