connexion icon indicating copy to clipboard operation
connexion copied to clipboard

A `deepObject` query parameter containing a list is not properly deserialized

Open edupo opened this issue 3 years ago • 2 comments

Description

Deep Object deserialization does not work according to swagger UI. I'm not sure if is a bug or lack of specification on the swagger side.

Expected behavior

When adding a list inside a deepObject query parameter like: {'foo': { 'bar': [1, 2, 3, 4]}} the server side must receive the same object.

Actual behavior

Only one element of the list bar list is deserialized.

Steps to reproduce

  • A simple endpoint requiring a query parameter with style deepObject
components:
  schemas: {}
  parameters:
    foo:
      name: foo
      in: query
      required: false
      style: deepObject
      explode: true
      schema: {}
  • Send this query: ?[foo][bar]=1&[foo][bar]=2&[foo][bar]=3&[foo][bar]=4

  • On the server side foo['bar'] is not a list

Additional info:

The query string can be easily created with the Swagger UI. And they encode lists in deepObject like that. But from their documentation is not clear to me how the deepObject serialization must work in the lists... It looks like they fall back to their standard behaviour for exploded arrays.

Output of the commands:

  • python --version Python 3.7.3
  • pip show connexion | grep "^Version\:" Version: 2.7.0

edupo avatar Feb 14 '22 08:02 edupo

Hi @edupo Thanks for the report. Would be great if you could test it with the latest connexion version and provide a minimal working example of your setup.

RobbeSneyders avatar Feb 14 '22 14:02 RobbeSneyders

I've tested in 2.12.0 and I receive the same behavior happens.

Try this code:

import yaml

api_yaml = """openapi: 3.0.0
info:
  title: deserialization_bug
  version: '1.0'
  contact:
    name: edupo
    url: github.com/edupo
  description: Testing array deserialization bug
servers:
  - url: 'http://localhost:3000'
paths:
  /query:
    get:
      summary: Your GET endpoint
      tags: []
      responses:
        '200':
          description: OK
      operationId: get_query
      x-openapi-router-controller: bug
      parameters:
        - schema: 
            type: object
          in: query
          name: items
      description: Bug testing endpoint
components:
  schemas: {}
  parameters: {}
"""

def get_query(items):
    return str(items)

app = connexion.App(__name__)
app.add_api(yaml.load(api_yaml, Loader=yaml.FullLoader))
app.run(port=3000)

And make this request:

http://localhost:3000/query?items[a]=1&items[a]=2

You will receive back:

"{'a': '1'}"

If you generate the URL using this settings in the swagger editor you will get the deep object encoded as I showed before. So I think the spec is not dealing with this case for deepObject serialization and connexion isn't also dealing with it right?

edupo avatar Mar 02 '22 13:03 edupo