{"id":15798583,"url":"https://github.com/codeasashu/openapi-validator","last_synced_at":"2026-05-03T04:32:40.238Z","repository":{"id":56954862,"uuid":"210031134","full_name":"codeasashu/openapi-validator","owner":"codeasashu","description":"Fork of https://gitlab.com/mmalawski/openapi-validator with some improvements","archived":false,"fork":false,"pushed_at":"2019-09-21T18:21:34.000Z","size":340,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-09T22:15:42.171Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codeasashu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-21T18:01:32.000Z","updated_at":"2019-09-21T18:05:08.000Z","dependencies_parsed_at":"2022-08-21T08:50:08.440Z","dependency_job_id":null,"html_url":"https://github.com/codeasashu/openapi-validator","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/codeasashu/openapi-validator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeasashu%2Fopenapi-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeasashu%2Fopenapi-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeasashu%2Fopenapi-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeasashu%2Fopenapi-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codeasashu","download_url":"https://codeload.github.com/codeasashu/openapi-validator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeasashu%2Fopenapi-validator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32558667,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T03:21:47.309Z","status":"ssl_error","status_checked_at":"2026-05-03T03:21:43.884Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-05T00:42:39.979Z","updated_at":"2026-05-03T04:32:40.210Z","avatar_url":"https://github.com/codeasashu.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"## What is this? \n\nValidate data against [openapi v3 spec](https://github.com/OAI/OpenAPI-Specification)\n\n## Features\n\n1. Checks for required fields\n2. Checks types\n3. Supports nested structures\n4. Supports discriminator\n5. Supports allOf, anyOf\n6. Supports nullable\n7. Resolves local references (components)\n8. Supports additionalProperties\n\nUnlike Dredd it does not require examples and does not check that data matches examples\n\n## Installation\n\n```bash\ncomposer req --dev mmal/openapi-validator\n```\n\n## Requirements\n\nYour openapi spec has to be valid, You can use [Speccy](https://github.com/wework/speccy) to check Your schema first\n\nThis library assumes that each operation has operationId\n\n## Examples\n\nGiven we have api described by following OpenAPI specification\n\n```yaml\nopenapi: 3.0.2\ninfo:\n  title: Cards\n  description: Cards and decks api\n  contact:\n    name: Mieszko Malawski\n  license:\n    name: GNU AGPLv3\n    url: https://www.gnu.org/licenses/agpl.txt\n  version: 1.0.0\ntags:\n  -\n    name: Cards\npaths:\n  /cards:\n    summary: Path used to manage the list of cards.\n    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.\n    get:\n      tags:\n        - Cards\n      summary: List All cards\n      description: Gets a list of all card entities.\n      operationId: getcards\n      responses:\n        200:\n          description: Successful response - returns an array of card entities.\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  $ref: '#/components/schemas/card'\ncomponents:\n  schemas:\n    card:\n      title: Root Type for card\n      description: The root of the card type's schema.\n      required:\n      - id\n      - name\n      - power\n      type: object\n      properties:\n        id:\n          description: \"unique id\"\n          type: string\n          format: int64\n          readOnly: true\n        name:\n          type: string\n        power:\n          description: \"how powerfull card is on the board\"\n          format: int32\n          type: integer\n      example:\n        id: \"23423423\"\n        name: \"Geralt\"\n        power: 10\n        \n\n```\n\nWe have server implementation (this is of course example - normally You would fetch data from some storage)\n\n```php\n\u003c?php\ndeclare(strict_types=1);\n\n\nnamespace AppBundle\\Controller;\n\n\nuse GOG\\Common\\OAuthSecurityBundle\\Controller\\OAuthController;\nuse Symfony\\Component\\HttpFoundation\\JsonResponse;\n\nclass CardsController extends OAuthController\n{\n    public function getCardsAction()\n    {\n        return new JsonResponse(\n            [\n                [\n                    'id' =\u003e '123123',\n                    'name' =\u003e 'Geralt',\n                    'power' =\u003e 10,\n                ],\n                [\n                    'id' =\u003e '45653',\n                    'name' =\u003e 'Vernon Roche',\n                    'power' =\u003e 10,\n                ]\n            ]\n        );\n    }\n}\n\n\n```\n\nHow to verify that server implementation works as described? Use openapi-validator with any http client:\n\n```php\n\u003c?php\ndeclare(strict_types=1);\n\n\nnamespace AppBundle\\Tests\\Controller;\n\n\nuse Mmal\\OpenapiValidator\\Validator;\nuse Symfony\\Component\\Yaml\\Yaml;\n\nclass CardsControllerTest extends BaseControllerTest\n{\n    const SPEC_PATH = __DIR__.'/../../../../docs/api.yml';\n    \n    /** @var Validator */\n    static $openaApiValidator;\n\n    static public function setUpBeforeClass()\n    {\n        parent::setUpBeforeClass();\n        self::$openaApiValidator = new Validator(Yaml::parse(self::SPEC_PATH));\n    }\n\n    public function testGetCards()\n    {\n        $this-\u003emakeRequest('GET', '/cards');\n    }\n\n    protected function makeRequest($method, $uri, $content = '')\n    {\n        $client = $this-\u003egetTestClient();\n        $client-\u003erequest(\n            $method,\n            $uri\n        );\n        $response = $client-\u003egetResponse();\n\n        $result = self::$openaApiValidator-\u003evalidateBasedOnRequest(\n            $uri,\n            $method,\n            $response-\u003egetStatusCode(),\n            json_decode($response-\u003egetContent(), true)\n        );\n        self::assertFalse($result-\u003ehasErrors(), $result);\n\n        return RESTResponse::fromHTTPResponse($response);\n    }\n}\n\n\n```\n\n1. Load Your spec to validator\n2. Make request with any http client\n3. Pass request uri, request method, response code and response body to validator (and optionally media type, default is application/json)\n4. Validator will find figure out that for method 'GET', path '/cards' and response code 200, required response schema is:\n\n\n```yaml\ncard:\n  title: Root Type for card\n  description: The root of the card type's schema.\n  required:\n  - id\n  - name\n  - power\n  type: object\n  properties:\n\tid:\n\t  description: \"unique id\"\n\t  type: string\n\t  format: int64\n\t  readOnly: true\n\tname:\n\t  type: string\n\tpower:\n\t  description: \"how powerfull card is on the board\"\n\t  format: int32\n\t  type: integer\n  example:\n\tid: \"23423423\"\n\tname: \"Geralt\"\n\tpower: 10\n\n\n\n```\n\n5. Actual response body is validated against that schema\n6. Result object is produced, if response is invalid then result object will contain errors\n\nIn this case response is valid:\n\n![image info](./assets/openapi_presentation_test_pass1.png)\n\nLets now introduce some errors:\n\n```php\n public function getCardsAction()\n    {\n        return new JsonResponse(\n            [\n                [\n                    'id' =\u003e '123123',\n                    'name' =\u003e 'Geralt',\n                    'power' =\u003e 10,\n                ],\n                [\n                 //   'id' =\u003e '45653',\n                    'name' =\u003e 'Vernon Roche',\n                    'power' =\u003e 10,\n                ]\n            ]\n        );\n    }\n    \n\n```\n\nRequired id field for second item is missing:\n\n![image info](./assets/openapi_presentation_test_fail1.png)\n\nLets break something else \n\n```php\npublic function getCardsAction()\n    {\n        return new JsonResponse(\n            [\n                [\n                    'id' =\u003e '123123',\n                    'name' =\u003e 'Geralt',\n                    'power' =\u003e 10,\n                ],\n                [\n                    'id' =\u003e '45653',\n                    'name' =\u003e 'Vernon Roche',\n                    'power' =\u003e '10',\n                ]\n            ]\n        );\n    }\n    \n\n```\n\npower field should be integer (second item):\n\n![image info](./assets/openapi_presentation_test_fail2.png)\n\n## Other libraries\n\n1. [Dredd](https://github.com/apiaryio/dredd) - currently supports only swagger/openapi v2, support for v3 is not yet there\n2. [Swagger](https://github.com/WakeOnWeb/swagger) - support for v2 only \n\n\n## TODO\n\n1. Support all openapi formats\n2. Support for not keyword\n\n## How this works?\n\nTransform openapi spec into json schema and then uses justinrainbow/json-schema to validate it\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodeasashu%2Fopenapi-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodeasashu%2Fopenapi-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodeasashu%2Fopenapi-validator/lists"}