OpenAPI-Specification icon indicating copy to clipboard operation
OpenAPI-Specification copied to clipboard

Group multiple parameter definitions for better maintainability

Open cansik opened this issue 8 years ago • 94 comments

Idea

Sometimes you have some parameters you want to provide on every path. At the moment it is possible to reference them with the $ref tag. This works great if you have a lot of different parameter combination for each route.

But we now have a complex api with a lot of optional get parameters for every path. Now the problem we encounter is, that if we have to add new parameters to this get parameters, it is very cumbersome and inconvenient to set the reference to them on each path. Often it happens that you forget one.

It would be great if we could group parameter definitions for a better maintainability and usability.

Example

As already presented on stackoverflow here an example of the definition (how it could look like):

parameters:
  MetaDataParameters:
    # Meta Data Properties
    - name: id
      in: query
      description: Entry identification number
      required: false
      type: integer

    - name: time_start
      in: query
      description: Start time of flare
      required: false
      type: string

    - name: nar
      in: query
      description: Active region number
      required: false
      type: string

And here is how I would like to reference it:

/test/:
  get:
    tags:
      - TEST
    operationId: routes.test
    parameters:
      - $ref: "#/parameters/MetaDataParameters"
    responses:
        200:
          description: OK

To get more on the user experience, this definition is much more readable than 20 parameters for each route.

Other Ideas?

Have you already thought about something like this or do you want us swagger users to go another way to deal with this problem?

Regards Florian

cansik avatar Aug 20 '15 07:08 cansik

Thanks for opening the issue, there's just one thing that's not clear. On one hand, you're saying that you want to provide them for 'every path' which implies a global definition that won't require you to reference it, and on other hand, you go ahead and reference from a specific method to the group of parameters. So which of the two are you looking for? or is it both?

webron avatar Aug 20 '15 09:08 webron

Ok the formulation every path is maybe wrong (too open). We still have paths which do not need this parameter. We would like to use it as described in the example to reference a group of parameter with one reference. Otherwise it would look like this:

/test/:
  get:
    tags:
      - TEST
    operationId: routes.test
    parameters:
      # In path parameter
      - $ref: "#/parameters/event_type"
      - $ref: "#/parameters/appearance_date"

      # Meta Data Properties
      - $ref: "#/parameters/param1"
      - $ref: "#/parameters/param2"
      - $ref: "#/parameters/param3"
      - $ref: "#/parameters/param4"
      - $ref: "#/parameters/param5"
      - $ref: "#/parameters/param6"

      # Data Properties
      - $ref: "#/parameters/param7"
      - $ref: "#/parameters/param8"
      - $ref: "#/parameters/param9"
      - $ref: "#/parameters/param10"

      # Specific Properties
      - $ref: "#/parameters/param11"
      - $ref: "#/parameters/param12"
      - $ref: "#/parameters/param13"
      - $ref: "#/parameters/param14"
      - $ref: "#/parameters/param15"
      - $ref: "#/parameters/param16"
      - $ref: "#/parameters/param17"
    responses:
        200:
          description: OK

With the enhancement we could write it like this and manage the items of each group in one place:

/test/:
  get:
    tags:
      - TEST
    operationId: routes.test
    parameters:
      # In path parameter
      - $ref: "#/parameters/event_type"
      - $ref: "#/parameters/appearance_date"

      # Meta Data Properties
      - $ref: "#/parameters/MetaDataParamGroup"

      # Data Properties
      - $ref: "#/parameters/DataParamGroup"

      # Specific Properties
      - $ref: "#/parameters/SpecificParamGroup"
    responses:
        200:
          description: OK

cansik avatar Aug 20 '15 09:08 cansik

Okay, thank you for the clarification. The reason I asked is because we have a feature request for global parameters already.

People have asked for parameter groups in various places, but nobody opened a feature request, so thank you for taking the time to do so. The value of it is understandable. I'm not sure the syntax you shared works, but we can evaluate it further over time.

webron avatar Aug 20 '15 09:08 webron

If $ref: "#/parameters/MetaDataParamGroup" resolves to a hash (as described above) parameters will have that hash in it which is not valid as Swagger 2.0. Unless we change the parameters array format to allow hashs (which I don't think it's a good idea) it will not work.

mohsen1 avatar Aug 20 '15 18:08 mohsen1

@mohsen1 Ok and what is the problem with hashes for parameters? Is there a discussion in another issue about this?

cansik avatar Aug 24 '15 06:08 cansik

parameters is an array of parameter objects. I'm not sure if we want parameterName:parameterObject hashs in the spec also.

mohsen1 avatar Aug 24 '15 06:08 mohsen1

@cansik, @mohsen1: /parameters is a hash of parameter objects but /paths/{path}/parameters and /paths/{path}/{operation}/parameters are arrays of parameters objects. There is no confusion.

dolmen avatar Oct 07 '15 16:10 dolmen

@cansik For your request, I suggest that you define your own vendor extension for parameter groups, and write a processing tool that would inline your group references into a pure Swagger 2.0 spec for external consumption. This is how I work for my own API: I write my spec in YAML (that allows me to use comments) and will only publish the JSON version of it.

I already find that many tools do not fully support the current spec (for example I found issues with /parameters and /paths/{path}/parameters and I had to write a processor to inline them). We don't need now to complexify the spec if tools do not follow it.

dolmen avatar Oct 07 '15 16:10 dolmen

+1 Want to see this feature as well.

project0 avatar Nov 23 '15 22:11 project0

+1 we too have predefined query params to almost all api paths

0x62ash avatar Nov 29 '15 21:11 0x62ash

+1 this would save me a lot of time and lines in my doc spec

renanmt avatar Dec 07 '15 19:12 renanmt

+1 this too, everything that gets me to reuse code is a huge +1.

Growiel avatar Dec 30 '15 06:12 Growiel

+1 would love to see it

mkostin avatar Jan 21 '16 21:01 mkostin

+1

rafael84 avatar Feb 08 '16 11:02 rafael84

It's worth noting that RAML take on this, 'traits' (really not much different from the proposed structure). http://raml.org/developers/raml-200-tutorial#traits

jharmn avatar Feb 08 '16 16:02 jharmn

+1

ranacseruet avatar Feb 17 '16 17:02 ranacseruet

Reference #560

fehguy avatar Feb 19 '16 18:02 fehguy

+1

clemensberndt avatar Mar 06 '16 23:03 clemensberndt

+1

lggmonclar avatar Mar 23 '16 20:03 lggmonclar

Just as a note for everyone wanting to vote this up: Github recently added a feature allowing a "reaction" to each post, using the button in the top left corner of each post. This will not clutter the thread with contentless comments.

ePaul avatar Mar 23 '16 22:03 ePaul

How about allowing us to organize parameters into sets? Then a path could reference parameter sets to automatically get all the parameters in those sets:

parameters:
    - name: id
      in: query
      description: Entry identification number
      required: false
      type: integer
      sets: [ "MetaData" ]

    - name: time_start
      in: query
      description: Start time of flare
      required: false
      type: string
      sets: [ "MetaData", "Alternate" ]

    - name: nar
      in: query
      description: Active region number
      required: false
      type: string
      sets: [ "Alternates" ]

paths:
  /test/:
    get:
      parameters:
        - $ref: "#/parameters/event_type"             <<<< $ref still works
        - $ref: "#/parameters/appearance_date"
      parameterSets: [ "MetaData", "Alternate" ] <<< yields id, time_start and nar
  /other/:
    get:
      parameters:
      parameterSets: [ "Alternate" ]         <<< yields time_start and nar


This is analogous to tags, but I used "sets" to avoid ambiguity. It's basically a shorthand for multiple $ref, but I think would be easier to read, maintain and reuse. It would not require changing the structure of parameters as in the OP, and would allow parameters to be in multiple sets, which the OP proposal does not allow (I think).

(I don't think there is a UI aspect to these sets, so no set descriptions are needed. Syntax for describing parameter sets would be added for documentation purposes, though.)

DavidBiesack avatar Mar 24 '16 13:03 DavidBiesack

+1

k-omukai avatar Mar 25 '16 02:03 k-omukai

@OAI/tdc propose closing this with no action. The fix in #633 will help with this

fehguy avatar Apr 11 '16 21:04 fehguy

I think we still need to support this, and should be fairly easy.

#633 doesn't really help with this. This is not about global parameters, and reusable parameters existed in 2.0 already.

webron avatar Apr 12 '16 05:04 webron

FWIW, I would like OAS to use structural abstractions (such as the tags I suggest above) over $ref representation "tricks" which IMHO hide or obscure the intent. The API designer's goal is to reuse common API constructs such as sets of parameters. Implementing that through $ref and JSON schema inclusion works, but doing so adds a level of redirection (which to me equates to obfuscation.)

DavidBiesack avatar Apr 12 '16 14:04 DavidBiesack

I agree with @webron that sets deserve consideration on their own.

earth2marsh avatar Apr 14 '16 05:04 earth2marsh

This should absolutely be a feature. For API endpoints with many shared configuration parameters, it is a huge hassle to maintain those same params everywhere.

ralusek avatar May 05 '16 16:05 ralusek

+ 1 this would save me time and lines

rochifebo avatar Jul 13 '16 14:07 rochifebo

+1

jackkong avatar Aug 19 '16 02:08 jackkong

+1

matiman avatar Oct 04 '16 20:10 matiman