apispec icon indicating copy to clipboard operation
apispec copied to clipboard

Support nested schema inside object properties

Open zeakd opened this issue 6 years ago • 2 comments

Hi. Maybe I missed, I'm trying to nest a schema to object type properties, but I couldn't found the way to solve this situation.

responses:
  200:
    content:
      application/json:
        schema: 
          type: object
          properties:
            addressInfo:
              $ref: "#/components/schemas/AddressInfo"
              description: Address info.

First I wrote below, but it doesn't work.

schema: 
  type: object
   properties:
     addressInfo:
       $ref: AddressInfo
       description: Address info.

This is one of options, but it can't declare description

schema: 
  type: object
   properties:
     addressInfo: AddressInfo
     # description?

manual binding is not working because AddressInfo is not in #/components/schema

schema: 
  type: object
   properties:
     addressInfo:
       $ref: "#/components/schemas/AddressInfo" # not defined. 
       description: Address info.

Is there a proper solution for this? 🙏 Thanks.

zeakd avatar Feb 03 '19 17:02 zeakd

The marshmallow plugin is not looking for marshmallow schemas nested within properties of a schema defined in a YAML.

You can solve this two ways:

  1. Use your manual binding and manually add your AddressInfo schema to the spec by calling spec.components.schema(name="AddressInfo", schema=AddressInfo)
  2. Create a schema for the entire response with AddressInfo as a nested field. Then you can reference that schema in YAML.

Hope that helps.

Bangertm avatar Feb 11 '19 14:02 Bangertm

Thanks @Bangertm. But I found marshmallow plugin is actually looking for marchmallow schema in the docstring, so

schema: 
  type: object
   properties:
     addressInfo: AddressInfo

this is works without importing AddressInfo schema manually . The only problem is, I can't write description in this way. However in case type of nested schema is array, properties can be written much easier. I want to point out this inconsistency.

schema: 
  type: object
   properties:
     addressInfos:
       type: array
       items: AddressInfoSchema
       description: address infos description.

I love apispec + marshmallow because of its flexibility which can fully use swagger spec, so how about support

addressInfo:
   $ref: AddressInfoSchema

instead of this way?

addressInfo: AddressInfoSchema

IMO, with $ref, apispec can work with all feature of swagger and have much more flexibility.

  1. Use your manual binding and manually add your AddressInfo schema to the spec by calling spec.components.schema(name="AddressInfo", schema=AddressInfo)

manually binding schema has problem when AddressInfo is already registered by another route. Maybe api.core.components needs has method to check whether schema is already registered or not, instead of looking for api.core.components._schema directly

zeakd avatar Feb 12 '19 06:02 zeakd