Allowing arbitrary query parameters


#1

Moving the discussion from github (https://github.com/raml-org/raml-spec/issues/6) to here:

jazzu asked:


Suppose you have a service, in which customers can define their own fields for data. Then there’s the API which allows said customers to access and filter said data. Now, there are common parts in the API for all customers: the endpoints, pagination params, sorting params, etc. Only the filtering bits change according to customer specific choices.

Example:

A: /people?sort=surname&field_not_defined_for_B=some_filtering_value

vs.

B: /people?sort=surname&field_not_defined_for_A=some_other_filtering_value

How would this kind of API best described? Should there be some sort of catch-all queryParameters entry/reserved word/attribute to denote, that “this end point accepts possible customer-specific filter key-value pairs”?

This API representation question is an issue only when trying to present a general view of the API. Obviously, in specific customer cases the API description could be complemented with some sort of automatically generated, customer specific include file. The presence of said include tag might also suffice for such a clue for the reader:

# main_spec.raml
/people:
  get:
    queryParameters:
      query:
        description: A search string
        type: string
      !include customer_people_params.raml

This definition would mean, that /people endpoint accepts a parameter “query” and is supposed to accept whatever is defined for a specific customer, even if specified file is not available.

What do you think?

On another note, is this GitHub issue tracker even right place to discuss this kind of things?

I responded:


It is indeed interesting to try to capture the ability to add more parameters that are not fixed at design time; filtering/querying is certainly a good, common usecase.

The example you have, with !include, won’t work as is, because !include has to be the right-hand value of something. We should probably clarify that better in that section of the spec. But regardless, using !include won’t help make things more dynamic – it’ll still be fixed statically at design time, just by an external file that’s probably being read/used at design time. That may work for one particular usecase but won’t solve for the more general case of dynamic filter parameters.

Let’s keep thinking about this…

idris responded:


JSON-schema has an interesting way of dealing with this. It’s a bit different for query parameters, but perhaps you could borrow some inspiration from json-schema. See:


#2

In my case the applicable query parameters depend on the resource being accessed, where each parameter roughly correspond to some variable defined in an underlying database query. Solving this in an elegant way isn’t easy but maybe one alternative would be to support a description and example clause that applies not to an individual parameter but to the queryParameters clause itself, e.g.:

/people:
  get:
    queryParameters:
      description: List of supported parameters
      example: |
         /people?a=1&b=2&c=3

The problem with this approach is of course that the two keywords would become reserved, since we shouldn’t rule out the definition of known query parameters either. Another alternative would be to use some parameter as a placeholder string parameter with required: false and put the same comment/example there… But this requires some careful thinking. Any other ideas that come to mind?