Coder Social home page Coder Social logo

cebe / php-openapi Goto Github PK

View Code? Open in Web Editor NEW
462.0 22.0 88.0 688 KB

Read and write OpenAPI yaml/json files and make the content accessible in PHP objects.

License: MIT License

Makefile 1.09% PHP 98.18% Dockerfile 0.72%
openapi openapi3 php api schema api-spec hacktoberfest

php-openapi's Introduction

php-openapi

Read and write OpenAPI 3.0.x YAML and JSON files and make the content accessible in PHP objects.

It also provides a CLI tool for validating and converting OpenAPI 3.0.x Description files.

Latest Stable Version Total Downloads Build Status

Install

composer require cebe/php-openapi

Requirements

  • PHP 7.1 or higher (works fine with PHP 8)

Used by

This library provides a low level API for reading and writing OpenAPI files. It is used by higher level tools to do awesome work:

Usage

CLI Tool

$ vendor/bin/php-openapi help
PHP OpenAPI 3 tool
------------------
by Carsten Brandt <[email protected]>

Usage:
  php-openapi <command> [<options>] [input.yml|input.json] [output.yml|output.json]

  The following commands are available:

    validate   Validate the API Description in the specified input file against the OpenAPI v3.0 schema.
               Note: the validation is performed in two steps. The results are composed of
                (1) structural errors found while reading the API Description file, and
                (2) violations of the OpenAPI v3.0 schema.

               If no input file is specified input will be read from STDIN.
               The tool will try to auto-detect the content type of the input, but may fail
               to do so. You may specify --read-yaml or --read-json to force the file type.

               Exits with code 2 on validation errors, 1 on other errors and 0 on success.

    convert    Convert a JSON or YAML input file to JSON or YAML output file.

               If no input file is specified input will be read from STDIN.
               If no output file is specified output will be written to STDOUT.
               The tool will try to auto-detect the content type of the input and output file, but may fail
               to do so. You may specify --read-yaml or --read-json to force the input file type.
               and --write-yaml or --write-json to force the output file type.

               By default all references are resolved (replaced with the object referred to). You can control
               handling of references with the following arguments:

               --resolve-none      Do not resolve references.
               --resolve-external  Only resolve references that point to external files.
                                   This process is often referred to as "inlining".
               --resolve-all       Resolve all references (default).
                                   Recursive pointers will stay references.

    inline     Convert a JSON or YAML input file to JSON or YAML output file and
               resolve all external references. The output will be a single API Description file.
               This is a shortcut for calling convert --resolve-external.

    help       Shows this usage information.

  Options:

    --read-json   force reading input as JSON. Auto-detect if not specified.
    --read-yaml   force reading input as YAML. Auto-detect if not specified.
    --write-json  force writing output as JSON. Auto-detect if not specified.
    --write-yaml  force writing output as YAML. Auto-detect if not specified.
    -s, --silent  silent mode. Will hide all success/information messages and only print errors.

Reading API Description Files

Read OpenAPI Description from JSON file:

use cebe\openapi\Reader;

// realpath is needed for resolving references with relative Paths or URLs
$openapi = Reader::readFromJsonFile(realpath('openapi.json'));

Read OpenAPI Description from YAML:

use cebe\openapi\Reader;

// realpath is needed for resolving references with relative Paths or URLs
$openapi = Reader::readFromYamlFile(realpath('openapi.yaml'));
// you may also specify the URL to your API Description file
$openapi = Reader::readFromYamlFile('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/3.0.2/examples/v3.0/petstore-expanded.yaml');

Access API Description data:

echo $openapi->openapi; // openAPI version, e.g. 3.0.0
echo $openapi->info->title; // API title
foreach($openapi->paths as $path => $definition) {
    // iterate path definitions
}

Object properties are exactly like in the OpenAPI Specification. You may also access additional properties added by specification extensions.

Writing API Description Files

use cebe\openapi\spec\OpenApi;
use cebe\openapi\spec\PathItem;

// create base API Description
$openapi = new OpenApi([
    'openapi' => '3.0.2',
    'info' => [
        'title' => 'Test API',
        'version' => '1.0.0',
    ],
    'paths' => [],
]);
// manipulate description as needed
$openapi->paths['/test'] = new PathItem([
    'description' => 'something'
]);
// ...

$json = \cebe\openapi\Writer::writeToJson($openapi);

results in the following JSON data:

{
    "openapi": "3.0.0",
    "info": {
        "title": "Test API",
        "version": "1.0.0"
    },
    "paths": {
        "/test": {
            "description": "something"
        }
    }
}

Writing API Description Files using prepared Objects

Since version 1.2.0, the above example can also be written like this (passing objects instead of arrays):

use cebe\openapi\spec\OpenApi;
use cebe\openapi\spec\PathItem;
use cebe\openapi\spec\Info;


// create base API Description
$openapi = new OpenApi([
    'openapi' => '3.0.2',
    'info' => new Info([
        'title' => 'Test API',
        'version' => '1.0.0',
    ]),
    'paths' => [
        '/test' => new PathItem([
            'description' => 'something'
        ]),
    ],
]);
$json = \cebe\openapi\Writer::writeToJson($openapi);

Reading API Description Files and Resolving References

In the above we have passed the raw JSON or YAML data to the Reader. In order to be able to resolve references to structures in external files, we must provide the full context.

use cebe\openapi\Reader;
use cebe\openapi\spec\OpenAPI;
use cebe\openapi\ReferenceContext;

// there are two different modes for resolving references:
// ALL: resolve all references, which will result in a large description with a lot of repetition
// but no references (except if there are recursive references, these will stop at some level)
$mode = ReferenceContext::RESOLVE_MODE_ALL;
// INLINE: only references to external files are resolved, references to places in the current file
// are still Reference objects.
$mode = ReferenceContext::RESOLVE_MODE_INLINE;

// an absolute URL or file path is needed to allow resolving external references
$openapi = Reader::readFromJsonFile('https://www.example.com/api/openapi.json', OpenAPI::class, $mode);
$openapi = Reader::readFromYamlFile('https://www.example.com/api/openapi.yaml', OpenAPI::class, $mode);

If data has been loaded in a different way you can manually resolve references like this by giving a context:

$openapi->resolveReferences(
    new \cebe\openapi\ReferenceContext($openapi, 'https://www.example.com/api/openapi.yaml')
);

Validation

The library provides simple validation operations, that check basic OpenAPI spec requirements. This is the same as "structural errors found while reading the API Description file" from the CLI tool. This validation does not include checking against the OpenAPI v3.0 JSON schema, this is only implemented in the CLI.

// return `true` in case no errors have been found, `false` in case of errors.
$specValid = $openapi->validate();
// after validation getErrors() can be used to retrieve the list of errors found.
$errors = $openapi->getErrors();

Note: Validation is done on a very basic level and is not complete. So a failing validation will show some errors, but the list of errors given may not be complete. Also a passing validation does not necessarily indicate a completely valid spec.

Completeness

This library is currently work in progress, the following list tracks completeness:

  • read OpenAPI 3.0 JSON
  • read OpenAPI 3.0 YAML
  • OpenAPI 3.0 Schema
    • OpenAPI Object
    • Info Object
    • Contact Object
    • License Object
    • Server Object
    • Server Variable Object
    • Components Object
    • Paths Object
    • Path Item Object
    • Operation Object
    • External Documentation Object
    • Parameter Object
    • Request Body Object
    • Media Type Object
    • Encoding Object
    • Responses Object
    • Response Object
    • Callback Object
    • Example Object
    • Link Object
    • Header Object
    • Tag Object
    • Reference Object
    • Schema Object
      • load/read
      • validation
    • Discriminator Object
    • XML Object
    • Security Scheme Object
    • OAuth Flows Object
    • OAuth Flow Object
    • Security Requirement Object

Development

You may use the docker environment for local development:

docker-compose build
make IN_DOCKER=1 install
make IN_DOCKER=1 test
...

Support

Need help with your API project?

Professional support, consulting as well as software development services are available:

https://www.cebe.cc/en/contact

Development of this library is sponsored by cebe.:cloud: "Your Professional Deployment Platform".

php-openapi's People

Contributors

canvural avatar cebe avatar dependabot[bot] avatar elazar avatar gitetsu avatar il-m-yamagishi avatar insolita avatar izucken avatar karsa-mistmere avatar lezhnev74 avatar lookyman avatar marcelthole avatar mfrischbutter avatar nadar avatar om4csaba avatar om4james avatar recchia avatar samdark avatar scaytrase avatar shadowhand avatar silverfire avatar simpod avatar ssfinney avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-openapi's Issues

Validation crash when creating loops

The validation should detect recursion and must not crash.

When building (unwanted) loops in a description file the validator results in a fatal error

Fatal error: Uncaught Error: Maximum function nesting level of '256' reached, aborting!

SomeResponse:
  type: object
  properties:
    type:
      type: string
      example: some string
    id:
      type: number
      description: "id"
      example: "1"
    attributes:
      type: object
    relationships:
      type: object
    include:
      type: array
      items:
        anyOf:
          - $ref: '#/components/schemas/SomeResponse'

Move to symfony console

I think it will be easier to manage things if you move to symfony console (with is de-facto standard for the console apps in php).

Some boolean/array properties have wrong values

When you are defining a Parameter like this:

"properties": {
    "code": {
        "description": "The Code of the Exception",
        "type": "integer",
        "example": 0
    },
    //...
}

and you try to get settings on that "code"-Property that are not set you will get values instead of null or undefined.
For example trying to get the "exclusiveMinimum"-Property will return "false" instead of null/undefined. This causes other frameworks like "justinrainbow/json-schema" to be unable to handle this.
I found the code responsible for this behaviour in src/SpecBaseObject.php::__get (Line 341):

337    if (isset($this->attributes()[$name])) {
338        if (is_array($this->attributes()[$name])) {
339            return [];
340        } elseif ($this->attributes()[$name] === Type::BOOLEAN) {
341            return false;
342        }
343        return null;
344    }

Is there a reason why array and boolean are specially handled here? From my POV that is strange because when I am trying to get the value of a setting that is not set I would expect those to be undefined.
Best example is the "exclusiveMinimum"-Setting of the Integer-Type which will be set to false by this function if not set what will cause the schema to be invalid because there is no minimum defined.

Should x-* references be parsed?

I'm using x-* extensions in a number of places and wanted to split up my OAS doc over multiple files. If I have a x-subscription content inline in the main file at root level, like this:

    "x-subscriptions": [
        {
            "on": "some.event",
            "do": [
                {
                    //...
                }
            ]
        }

Then after I do $specs = Reader::readFromJsonFile(realpath($specPath)); I can access the subscriptions, eg var_dump($spec->{'x-subscriptions'}); gives me:

array(1) {
  [0]=>
  array(2) {
    ["on"]=>
    string(32) "some.event"
    ["do"]=>
    array(1) {
        ...

But if I have:

    "x-subscriptions": {
        "$ref": "./x-subscriptions/some-event.json"
    },

with the full array moved to another file, the same $spec calls returns:

array(1) {
  ["$ref"]=>
  string(46) "./x-subscriptions/some-event.json"
}

I've tried a variety of ways (using 'allOf', having the array be in the root and reference individual events, etc.) but the reference doesn't resolve.

So I guess my question is; should it?

Thanks!

Test justinrainbow/json-schema version 1.6

The current dependency justinrainbow/json-schema is locked to ^5.0. Maybe it would be possible to allow older versions in order to support a wider ranger of package dependencies.

Support OpenAPI 3.1

OpenAPI 3.1 has just been released... Can we hope for support in this library?

Changes in the spec seems really small, but there are some small BCs that could complicate the stuff further: https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0

Main differences:

  • no more nullable
-type: string
-nullable: true
+type:
+ - "string"
+ - "null" 
  • exclusiveMinimum and exclusiveMaximum are used directly
-minimum: 7
-exclusiveMinimum: true
+exclusiveMinimum: 7
  • examples, no more example
-example: fedora
+examples:
+ - fedora
  • Describing File Upload Payloads
  • declaring JSON Schema dialect explicitly

Support for fixed arrays

Hello,

Given a JSON schema like below:

{
  "type": "array",
  "items": [
    {
      "type": "string"
    },
    {
      "type": "integer"
    },
    {
      "type": "boolean"
    }
  ]
}

this library produces a Schema object, which it's items property is also a single Schema object. In this inner Schema there is no way to access to the data. Data is in the private _properties property.

private $_properties =>
  array(3) {
    [0] =>
    array(1) {
      'type' =>
      string(6) "string"
    }
    [1] =>
    array(1) {
      'type' =>
      string(6) "string"
    }
    [2] =>
    array(1) {
      'type' =>
      string(6) "string"
    }
  }

To support this I think $schema->items should return an array of Schema objects.

Also, I'm not sure if this is really a missing feature or a bug.

Can't install on Symfony 4.4

The allowed symfony versions are: ^3.0 | ~4.0.0 | ~4.1.0 | ~4.2.0 | ~4.3.0 | ^5.0 but not 4.4, this is a transition version to 5. In 4.4 you can fix/remove deprecated code before migrate to version 5

allOf is not properly merged

Given a schema that uses allOf to combine two different object schemas, the properties of the two schemas are not combined:

{
  "components": {
    "schemas": {
      "identifier": {
        "type": "object",
        "properties": {
           "id": {"type": "string"}
        }
      },
      "person": {
        "allOf": [
          {"$ref": "#/components/schemas/identifier"},
          {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              }
            }
          }
        ]
      }
    }
  }
}

Not 100% sure that schema validates, but it should be a good start.

Get request / response model definition from specifications

I think it would be great to have some kind of "finder" to retrieve the model as associative array based on parameters.

For Request body we need :

  • a concrete URI
  • an http method

For Responses we need :

  • a concrete URI
  • an http method
  • a status code
  • content-type

It could be usefull in PHPUnit for example to retrieve the specific model and test it against jsonschema validator.

ReferenceContext::reduceDots shows `Undefined array key 7` error when `..` repeatedly appeared in path

Thank you for the great library.

I found to occur ErrorException when .. repeatedly appeared in path at ReferenceContext::reduceDots. PHP 8.0.0.

ErrorException {#587
  #message: "Undefined array key 7"
  #code: 0
  #file: "./vendor/cebe/php-openapi/src/ReferenceContext.php"
  #line: 123
  #severity: E_WARNING
  trace: {
    ./vendor/cebe/php-openapi/src/ReferenceContext.php:123 { …}
    ./vendor/cebe/php-openapi/src/ReferenceContext.php:195 { …}
    ./vendor/cebe/php-openapi/src/spec/Reference.php:307 { …}
    ./vendor/cebe/php-openapi/src/spec/Reference.php:315 { …}
    ./vendor/cebe/php-openapi/src/spec/Reference.php:315 { …}
    ./vendor/cebe/php-openapi/src/spec/Reference.php:315 { …}
    ./vendor/cebe/php-openapi/src/spec/Reference.php:229 { …}
    ./vendor/cebe/php-openapi/src/spec/PathItem.php:156 { …}
    ./vendor/cebe/php-openapi/src/spec/Paths.php:254 { …}
    ./vendor/cebe/php-openapi/src/SpecBaseObject.php:387 { …}
    ./vendor/cebe/php-openapi/src/Reader.php:134 { …}
    ...
$path = /var/www/app/contracts/api/paths/account/../../../responses/InternalServerError.yml
$parts = array:10 [
  0 => "var"
  1 => "www"
  2 => "app"
  3 => "contracts"
  4 => "api"
  5 => "paths"
  8 => ".."
  9 => ".."
  10 => "responses"
  11 => "InternalServerError.yml"
]
# /var/www/app/contracts/api/openapi.yml
openapi: 3.0.3
paths:
  /account/create:
    $ref: 'paths/account/createPaths.yml'
# /var/www/app/contracts/api/paths/account/createPaths.yml
post:
  requestBody:
    $ref: createRequest.yml
  responses:
    default:
      $ref: '../../../responses/InternalServerError.yml'
    '200':
      $ref: createResponse.yml
# /var/www/app/contracts/responses/InternalServerError.yml
content:
  application/json:
    schema:
      type: object
      properties:
        error:
          type: string

References fail to resolve in directory structure

This may be a replica of issue #13 , but I thought I'd report it - I'm using php-openapi by way of the lezhnev openapi/psr7-validator, and am coming up against the following:

I have a file structure like this:

open-api.yaml
Paths
 - pathdef1.yaml
 - pathdef2.yaml
Requests
 - requestschema1.yaml
 - requestschema2.yaml
Responses
 - responseschema1.yaml
 - responseschema2.yaml

open-api.yaml contains the "components" collection, and inside that, "schemas". Schemas contains a list of keys, each with a $ref variable pointed at an external file.

components:
   schemas:
      Request.1:
         $ref: "Requests/requestschema1.yaml"
      Request.2:
         $ref: "Requests/requestschema2.yaml"
      Response.1:
         $ref: "Responses/responseschema1.yaml"
      Response.2:
         $ref: "Responses/responseschema2.yaml"

Sometimes cases come up where a Response schema contains objects defined in another response schema:

title: "Response 2 object"
description: "A response containing some Response 1 objects"
type: "object"
properties:
    id:
        type: "integer"
        format: "int32"
    payload:
        $ref: "../open-api.yaml#/components/schemas/Response.1"

Additionally, the open-api.yaml file contains the path declarations. Each is defined in an external file (as above), and inside those files if any schemas are needed, they're referenced as keys in the open-api.yaml#/components/schemas collection, rather than directly to files.

The chief problems I'm getting are:

  1. From stepping through the code, I think that every time the open-api.yaml file refers to an external file that file has to be loaded, and then every time that file references open-api.yaml the parent file is reloaded again. If running with XDebug active this times out and isn't able to complete to help me understand where/why the second bug is taking place.

  2. If left to run without debug, at some point the file referencing fails and one of the external files seems to lose track of where in the file structure to look for the next link - one fo the objects is resolving a $ref to "file:///var/www/html/public/api-doc/../open-api.yaml" instead of "file:///var/www/html/public/api-doc/open-api.yaml", but with a timing out debug process I can't see where. The "root" file path is file:///var/www/html/public/api-doc/open-api.yaml, so any $ref'd files inside that file would be file:///var/www/html/public/api-doc/Responses/{filename} or file:///var/www/html/public/api-doc/Requests/{filename} or file:///var/www/html/public/api-doc/Paths/{filename} - but if those external files contain a link back, they're referencing "../open-api.yaml#/components/schemas/{etc}".

My questions are:

  • would caching (the way you're thinking about implementing it) solve the repeated reloading of the "base" open-api.yaml file?
  • if open-api.yaml were able to be parsed as some kind of dictionary, would that likely address the problem of objects containing $refs which contain objects which contain $refs losing track of what level of the filesystem they represent?

The OAS document I have validates using wework/speccy 11.0 and swagger-cli, and opens in redoc - so I'm reasonably confident between the 3 of those it's syntactically correct...

Happy to provide more detail offline if it helps.

Change handling of default values

Currently default values are set when loading data via constructor.

This results in the output of writer to contain all fields for which we have default data being set to these values.

Ideally default values should only be returned when asked for in __get.

Support PHP 8

Hello,

Are there any plans for adding support for PHP 8?

Today I checked what needs to be updated. All dependencies except php-cs-fixer have PHP 8 compatible versions. So the issues I found are:

  1. php-cs-fixer needs to updated. There is an issue about it there. Looks like it's still a work in progress. But as mentioned in the discussion here, it is not really a blocker. PHAR release can be downloaded and used in CI. Or something like https://github.com/bamarni/composer-bin-plugin

  2. Some PHPUnit methods used in tests are deprecated in newer versions. But that's easy to fix I guess.

What are your thoughts?

Implement Spec Objects

For those willing to contribute:

  • The task is to fill the classes in /src/spec with information in the OpenAPI specification.
  • Take a class that is not implemented yet (see README) and do the following according to the spec (See @link tag in class phpdoc):
    • add @property-read phpdoc annotations for all properties defined in the spec
    • implement attributes() method and list all properties defined in the spec, add their Type as it has been done in other classes already.
    • implement performValidation() method to validate the property values.

References to references fail as "cyclic reference"

Consider this simple YAML:

openapi: 3.0.2
info:
  title: 'City API'
  version: dev
paths:
  '/city':
    get:
      description: 'Get City'
      responses:
        '200':
          description: 'success'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/City'

components:
  schemas:
    City:
      $ref: '#/components/schemas/Named'
    Named:
      type: string
(new League\OpenAPIValidation\PSR7\ValidatorBuilder)
    ->fromYaml($yaml)
    ->getResponseValidator();

Response schema references "City" schema, which itself references "Named" schema, which is perfectly valid. However, the library throws the following exception:

cebe\openapi\exceptions\UnresolvableReferenceException : Cyclic reference detected, setReferenceContext() called on a Reference Object.

OpenAPI writer

Hello @cebe! Thank you for a great package!

Do you plan to add writer functionality to it?

Empty SecurityRequirement in YAML file

When trying to write a Security Requirement object to a YAML file:
$openapi->security = [new SecurityRequirement(['Bearer' => []])];
The result is:

security:
        -
          Bearer: {  }

When expected:

security:
        -
          Bearer: []

When writing to a JSON file, everything is fine:

"security": [
    {
         "Bearer": []
    }
]

No "security" same as empty "security"

I have an example of contract that has the following structure (summerized to highlight the relevant):

# [...]
paths:
  /path/one:
    post:
      # [...]
      security: []

  /path/two:
    post:
      # [...]
      # No security entry defined there

components:
  securitySchemes:
    Bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT

security:
  - Bearer: []

Theoreticaly, I expect:

  • In /path/one:
    • __isset() in the Operation object returns true, and __get() returns empty array.
  • In /path/two:
    • __isset() in the Operation object returns false, and __get() returns either empty array or null.
    • Alternativelly, I also might expect __isset() to return false, but __get() return the default security defined at contract root level. I consider this possibility as it is a solution similar like how references work in the scope of this library.

However, the problem is that what I actually get in both paths, is __isset() = true and __get() = empty array. As I get the same result in both, there is no way to determine that /path/one does not have at all security (and therefore, could be called directly), and that /path/two has default security.

Doesn't pass nullable for references

As far as I can see, it is valid to set a property $ref to be nullable. But I don't think this library handles that.

e.g.

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "address": {
      "nullable": "true",
      "$ref": "#/components/schemas/Address"
    },
    "age": {
      "type": "integer",
      "format": "int32",
      "minimum": 0
    }
  }
}

I would expect the address property to be nullable when this schema is parsed/loaded.

validate() returns true with wrong top level elements

Hi,
I tried to run validate like this:

$spec   = cebe\openapi\Reader::readFromJson($jsonstring);
$spec->resolveReferences(new cebe\openapi\ReferenceContext($spec, "/"));
$spec->validate();

on a OpenAPI 3 schema that has, for example the property "AAAAAcomponents" instead of "components", and the call returns true.
Is this correct?
Thanks,
Frank

Incompatible with symfony/yaml ^5

Steps to reproduce:

  1. require symfony/yaml ^5
  2. try executing composer require cebe/php-openapi

Result:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - cebe/php-openapi 1.3.3 requires symfony/yaml ^3.0 | ^4.0 -> no matching package found.
    - cebe/php-openapi 1.3.2 requires symfony/yaml ^3.0 | ^4.0 -> no matching package found.
    - cebe/php-openapi 1.3.1 requires symfony/yaml ^3.0 | ^4.0 -> no matching package found.
    - cebe/php-openapi 1.3.0 requires symfony/yaml ^3.0 | ^4.0 -> no matching package found.
    - Installation request for cebe/php-openapi ^1.3 -> satisfiable by cebe/php-openapi[1.3.0, 1.3.1, 1.3.2, 1.3.3]

NormalizeUri does not normalizes windows file urls

I was running tests locally on windows for library and got an exception instead of green test

image

Looks like code ignores windows path notation while all other code work OK with it (since file still could be read)

How to use Security and SecurityRequirement

I am not sure how to use Security in combination with SecurityRequirements.

The Security Schema defined:

new OpenApi([
    'components' => new Components([
            'securitySchemes' => [
                'BearerAuth' => new SecurityScheme([
                    'type' => 'http',
                    'scheme' => 'bearer',
                    'bearerFormat' => 'AuthToken and JWT Format' # optional, arbitrary value for documentation purposes
                ])
            ],
   ]),
]);

Now the security schema is created (components).

How do i assign this security schema for an specific operation?

return new PathItem([
    'get' => new Operation([
        'security' => [new SecurityRequirement(['BearerAuth'])],
    ])
]);

Thanks for the great library and maybe it clarifies this task also for others.

Empty security array incorrectly converted to empty object (YAML)

When using $schema = Reader::readFromYaml($content) followed by Writer::writeToYaml($schema) any instances of security: [] are incorrectly converted to security: { }. This is invalid (it should remain as an empty array) and causes any tooling that reads the newly written spec to fall over.

Wrong type hint for some properties

As an example, in class Operation, requestBody property is defined as:

* @property RequestBody|Reference $requestBody

However, if the requestBody property is NOT in the contract, getting the property results in null. Therefore, the type hint should be updated to reflect that.

This might happen with other properties in the same or other objects: what I've just posted is an example.

Cannot use reference to component referenced from external file.

If I have defined a component externally, like this:

components:
  schemas:
    Pet:
      $ref: definitions.yaml#/Pet

Then I expect to be able to use it like this:

paths:
  '/pet':
    get:
      responses:
        200:
          description: return a pet
          content:
            'application/json':
              schema:
                $ref: "#/components/schemas/Pet"

However, when I do so, I get an error: cebe\openapi\exceptions\UnresolvableReferenceException : Cyclic reference detected, setReferenceContext() called on a Reference Object.

My experience using the lib. Inputs for performance improvement

First of all, Thanks for this amazing library.

I am using this library and would like to share experience that will give you data when you refactor code to improve performance

  • When $openapi object is initialised by reading spec file it is taking significant time that can be reduced ($openapi = Reader::readFromJsonFile(realpath('openapi_spec.json'));)
  • When I print_r a Schema object (cebe\openapi\spec\Schema) it takes a lot of time, browser crashes sometimes. (Workaround print_r property directly echo $schema->title)
  • Above issue also occurs when I try to print other object such as MediaType
  • php.ini: max_execution_time & memory_limit are needed to increase. If possible, changes can be made to be within limit of PHP defaults

Note: I have not done concrete profiling. This are just my primary observation while using the lib

I will share further experiences when I go come across any

Feature Request: Access component schemas by name

In OAS, I can reference schemas by name: #/components/schemas/MySchema. While playing with cebe/php-openapi, I attempted to access a schema through a similar path, like this:

$openapi->components->schemas->MySchema
// or
$openapi->components->schemas['MySchema']

Unfortunately, neither approach works because schemas is a 0-indexed array and not a hash or object with named properties.

Consider modifying $openapi->components->schemas so that it is an object with properties named according to the named schemas in the path #/components/schemas.

getErrors falls in infinite recursion

What: Bug
Severity: 1

How to reproduce:
Use the scheme with cyclic references

The result:
Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 262144 bytes) in .../vendor/cebe/php-openapi/src/SpecBaseObject.php on line 161

Inconsistent typehints for Reader

public static function readFromJson(string $json, string $baseType = OpenApi::class): SpecObjectInterface

all reader method declare returning SpecObjectInterface while phpdocs say that it should be the OpenApi object instance. Also phpdocs are redundand, since SpecObjectInterface|OpenApi equals to SpecObjectInterface as OpenApi implements SpecObjectInterface.

It looks like having OpenApi as return typehint signature is more straightforward, as it would agree with return phpdoc and comment and the expectations of end user

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.