Nelmioapidocbundle: How to describe a Response schema?

Created on 24 Sep 2017  路  8Comments  路  Source: nelmio/NelmioApiDocBundle

Hi,
Branch: dev-master.

How can I model a response that look like this:
[{"key":"val"}]

For example, ConstraintViolationList:
[{"property_path":"username","message":"This value is too short. It should have 5 characters or more."},{"property_path":"email","message":"This value is not a valid email address."}]

I tried to annotate it:

     * @SWG\Response(
     *      response="400",
     *      description="Validation Error",
     *      @SWG\schema(
     *          type="array",
     *          @SWG\items(
     *              type="object",
     *              @SWG\Property(property="name", type="string"),
     *              @SWG\Property(property="category", type="string"),
     *          ),
     *      ),
     *     examples={"Invalid Email and Username"="{""property_path"":""username"",""message"":""This value is too short. It should have 5 characters or more.""},{""email"":""3089"",""message"":""This value is not a valid email address.""}"}
     * )

Which lead to more issues, Examples doesn't show up as expected (Inspiration):

"{\"property_path\":\"username\",\"message\":\"This value is too short. It should have 5 characters or more.\"},{\"code\":\"3089\",\"message\":\"This value is not a valid email address.\"}"
Look like someone added slashes or forgot to remove them.

And the Model of the 400 response looks like (array with an empty object):

[{}]

Please advise.
Thanks

Most helpful comment

Removing Scheme worked for me:

 * @SWG\Response(
     *     response=200,
     *     description="Get partner",
     *     @Model(type=Partner::class)
     * )

Good documentation is really needed.... :)

All 8 comments

I reviewed my annotation once more, it seems like a bug.

This annotation:

     * @SWG\Response(
     *      response="400",
     *      description="Validation Error",
     *      @SWG\schema(
     *          type="array",
     *              @SWG\items(
     *                  type="object",
     *                  @SWG\Property(property="name", type="string"),
     *                  @SWG\Property(property="category", type="string"),
     *              ),
     *      )
     * )

Rresult in this example value:

[
  {}
]

While it should be:

[
  {"name":"string", "category":"string"}
]

Please advise,
Thanks!

Same here.

     * @SWG\Response(
     *     response=200,
     *     description="Get partner",
     *     @SWG\Schema(
     *         type="object",
     *         @Model(type=Partner::class)
     *     )
     * )

Results:

Example value/model:
{}

Removing Scheme worked for me:

 * @SWG\Response(
     *     response=200,
     *     description="Get partner",
     *     @Model(type=Partner::class)
     * )

Good documentation is really needed.... :)

Same here.

Given this works:

    /**
     * @SWG\Response(
     *     response=200,
     *     description="Some response",
     *     @SWG\Schema(
     *             required={"email", "first_name", "last_name"},
     *             @SWG\Property(property="id", type="string", description="UUID"),
     *             @SWG\Property(property="email", type="string"),
     *             @SWG\Property(property="password", type="string"),
     *             @SWG\Property(property="first_name", type="string"),
     *             @SWG\Property(property="last_name", type="string"),
     *             @SWG\Property(property="active", type="boolean"),
     *     )
     * )
     */


View JSON output

{
               "responses":{  
                  "200":{  
                     "description":"Some response",
                     "schema":{  
                        "required":[  
                           "email",
                           "first_name",
                           "last_name"
                        ],
                        "properties":{  
                           "id":{  
                              "description":"UUID",
                              "type":"string"
                           },
                           "email":{  
                              "type":"string"
                           },
                           "password":{  
                              "type":"string"
                           },
                           "first_name":{  
                              "type":"string"
                           },
                           "last_name":{  
                              "type":"string"
                           },
                           "active":{  
                              "type":"boolean"
                           }
                        }
                     }
                  }
               }
}

But this doesn't:

    /**
     * @SWG\Response(
     *     response=200,
     *     description="Some response",
     *     @SWG\Schema(
     *          type="array",
     *          @SWG\Items(
     *              type="object",
     *              required={"email", "first_name", "last_name"},
     *              @SWG\Property(property="id", type="string", description="UUID"),
     *              @SWG\Property(property="email", type="string"),
     *              @SWG\Property(property="password", type="string"),
     *              @SWG\Property(property="first_name", type="string"),
     *              @SWG\Property(property="last_name", type="string"),
     *              @SWG\Property(property="active", type="boolean"),
     *          )
     *     )
     * )
     */


View JSON output

{
               "responses":{  
                  "200":{  
                     "description":"Some response",
                     "schema":{  
                        "items":{  
                           "type":"object"
                        },
                        "type":"array"
                     }
                  }
               }
}

I'm also inclined to believe that a bug is found. Now need to find out which part (the bundle or Swagger-PHP) causes this...

First of all, this is the second day after I installed this bundle and get to know about all these swagger stuff. So I don't know good enough about what's going on. My apology.

Anyway, the cause seems to be the \EXSyst\Component\Swagger\Items class of the exsyst/swagger library (i.e. not this bundle nor swagger-php).

The JSON file generated by the swagger-php library is correct.

But ApiDocBundle uses exsyst/swagger to create the structure, which will eventually create an object representation of the "items" array.

It looks like the following (code untested):

$emailField = new stdClass();
$emailField->description = 'E-mail';
$emailField->type = 'string';

$firstNameField = new stdClass();
$firstNameField->description = 'First name';
$firstNameField->type = 'string';

$props = new stdClass();
$props = $emailField;
$props = $firstNameField;

$data = [
    'required' => ['email', 'first_name'],
    'properties' => $props,
    'type' => 'object',
];

$items = new \EXSyst\Component\Swagger\Items($data);

Theoretically this Items object should store the properties data. But look at the doMerge() method of the Items class:

swagger-items-class

There is no code to merge the "properties" data!! So once the object is constructed the item properties are lost.

mmm... looks like the implementation of "Items" annotation between zircode/swagger-php and exsyst/swagger is out of sync.

We can define child properties in @Items thanks to this commit:
https://github.com/zircote/swagger-php/commit/1ce1711fb3941b7acf86d84e2de7cceb54f37075

From the changeset I found that the Items annotation before modification is exactly the representation of the current exsyst/swagger's Items object. So specs aside (I didn't have time to read it yet), fixing the issue seems straightforward - just change EXSyst\Component\Swagger\Items to extend EXSyst\Component\Swagger\Schema will do. Also needed is to remove the final keyword from EXSyst\Component\Swagger\Schema so that it can be extended.

The modified Items and Schema class looks like the following:
https://gist.github.com/tamcy/beb86b024d468f6ef8e8b6831d74dd64

And viola!
fixed

That's it. Let's wait for some well-informed people to review if this makes sense.

Ref:

The above issues don't relate directly to this one, but from their description it seems that

  • exsyst/swagger's implementation is done according to the spec
  • the change by zircode/swagger-php violates the spec (OpenAPI spec 2.0 aka Swagger 2.0)

Now I am extremely confused.

I decided to merge https://github.com/GuilhemN/swagger/pull/3, it shouldn't hurt much and it seems a lot of people want it. So I guess this can be closed?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kojidev picture kojidev  路  6Comments

BraisGabin picture BraisGabin  路  7Comments

astronati picture astronati  路  3Comments

GuilhemN picture GuilhemN  路  6Comments

NicolasGuilloux picture NicolasGuilloux  路  4Comments