apiaframework / apia-openapi

MIT License
0 stars 0 forks source link

Support nested query params #66

Open paulsturgess opened 2 months ago

paulsturgess commented 2 months ago

Currently the schema will throw an error if we declare an argument for a LookupArgumentSet that points to another ArgumentSet.

This allows us to support nested query params:

?annotation[key]="my-key"&annotation[value]="my-value"

For example:

module CoreAPI
  module ArgumentSets
    class MyLookup < Apia::LookupArgumentSet
      argument :annotation, type: KeyValue

      [...]
    end
  end
end
class KeyValue < Apia::ArgumentSet

  argument :key, type: :string, required: true
  argument :value, type: :string

end

Currently we only support string as a valid type an argument of LookupArgumentSet.

paulsturgess commented 2 months ago

I tried adding support for nested query params.

The Ruby generated client will support it ok. But the jane-php client throws an error:

Fatal error: Uncaught TypeError: Jane\Component\OpenApi3\Generator\Parameter\NonBodyParameterGenerator::convertParameterType():
Return value must be of type array, null returned in /app/php/vendor/jane-php/open-api-3/Generator/Parameter/NonBodyParameterGenerator.php:197

The change I made to try it was in generate_argument_set_params in lib/apia/open_api/objects/parameters.rb

if child_arg.type.argument_set?
  schema = generate_schema_ref(child_arg)
else
  schema = generate_scalar_schema(child_arg)
end

The schema was updated like this as an example:

        "parameters": [
          {
            "name": "address_list[id]",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The address list to return. All 'address_list[]' params are mutually exclusive, only one can be provided."
          },
          {
            "name": "address_list[annotation]",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/KeyValue"
            },
            "description": "The address list to return. All 'address_list[]' params are mutually exclusive, only one can be provided."
          }
        ],

        ...

     "KeyValue": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "key"
        ]
      },

The Ruby client then allowed me to do this:

KatapultAPI.configure do |config|
  config.access_token = ENV['KATAPULT_ACCESS_TOKEN']
  config.host = 'http://katapult-api.localhost/'
  config.scheme = 'http'
end

api_instance = KatapultAPI::CoreApi.new
result = api_instance.get_address_list({ address_list_annotation: { key: 'test.io/something', value: 'abc' } })
puts result.inspect

In RapidAPI we can build a nested query string like this:

Screenshot 2024-08-21 at 08 24 37