Skip to content

Inter parameter dependencies

José Ramón Fernández edited this page May 13, 2020 · 25 revisions

Table of contents

  1. What is an inter parameter dependency?
  2. IDL: a language to specify inter parameter dependencies
    1. Defining the inter parameter dependencies with IDL: YouTube Data API
  3. An OpenAPI extension: x-dependencies

What is an inter parameter dependency?

There are many APIs that restrict the use of two or more parameters combined in a request. That's what we call inter parameter dependencies. We will take the YouTube Data API as an example. The GET operation of the /search path describes a considerable amount of inter parameter dependencies. For example, you can only specify one of the following parameters: forContentOwner, forDeveloper, forMine or relatedToVideoId, or if the location parameter is set, you must specify the locationRadius one. If the request does not comply with the restrictions, the API will return a bad request status.

IDL: a language to specify inter parameter dependencies

Currently, the OpenAPI specification does not support parameter dependencies and mutually exclusive parameters, as stated in the OpenAPI specification documentation. This is the option OpenAPI offers:

What you can do is document the restrictions in the parameter description and define the logic in the 400 Bad Request response.

It is infeasible to infer the inter parameter dependencies from a formal description in many cases, so it is necessary to design a language which describes those dependencies with a machine-readable definition.

RESTest uses IDL, a language that allows the inter parameter dependencies to be defined in a machine-readable way, so it can be interpreted by an algorithm.

Defining the inter parameter dependencies with IDL: YouTube Data API

We will use the GET operation of the /search path for this example again. YouTube indicates that you can only use zero or one of the following parameters: forContentOwner, forDeveloper, forMine or relatedToVideoId. You can declare this inter parameter dependency with IDL using the ZeroOrOne function:

ZeroOrOne(forContentOwner, forDeveloper, forMine, relatedToVideoId);

Another dependency is the following one:

The API returns an error if your request specifies a value for the location parameter but does not also specify a value for the locationRadius parameter.

You can use the function AllOrNone to declare this dependency:

AllOrNone(location, locationRadius);

You can also use the logical operators AND, OR and NOT, the comparison operators >, <, >=, <= and ==, and the conditional operator IF (...) THEN (...). For example, the following restriction:

If forContentOwner is set to true, the request must also meet these requirements:

  • The onBehalfOfContentOwner parameter is required.
    [...]
  • The type parameter value must be set to video.
  • None of the following other parameters can be set: videoDefinition, videoDimension, videoDuration, videoLicense, videoEmbeddable, videoSyndicated, videoType.

can be declared as:

IF forContentOwner==true THEN onBehalfOfContentOwner AND type=='video' AND NOT (videoDefinition OR videoDimension OR videoDuration OR videoLicense OR videoEmbeddable OR videoSyndicated OR videoType);

You can see more examples in the IDL repository.

An OpenAPI extension: x-dependencies

As you can see, IDL is very helpful, as it gives us a tool to model the inter parameter dependencies without using formal language. But where can we declare those dependencies if the OpenAPI specification does not support them?

OpenAPI does not support inter parameter dependencies, but it supports extensions, which are custom properties for describing extra functionalities that are not covered by the OpenAPI specification. RESTest makes use of an extension for the operations called x-dependencies, which is an array where you can specify the inter parameter dependencies using IDL. Here you can see how you can declare the inter parameter dependencies of the YouTube Data API GET operation of the /search path in the OpenAPI specification file:

# (...)

/search:
    get:
      description: 'Returns a collection of search results that match the query parameters specified in the API request. By default, a search result set identifies matching video, channel, and playlist resources, but you can also configure queries to only retrieve a specific type of resource.'
      operationId: youtube.search.list
      parameters:

#       (...)

      x-dependencies:
        - ZeroOrOne(forContentOwner, forDeveloper, forMine, relatedToVideoId);
        - IF forContentOwner==true THEN onBehalfOfContentOwner AND type=='video' AND NOT (videoDefinition OR videoDimension OR videoDuration OR videoLicense OR videoEmbeddable OR videoSyndicated OR videoType);
        - IF forMine==true THEN type=='video' AND NOT (videoDefinition OR videoDimension OR videoDuration OR videoLicense OR videoEmbeddable OR videoSyndicated OR videoType);
        - IF relatedToVideoId THEN type=='video' AND NOT (channelId OR channelType OR eventType OR location OR locationRadius OR onBehalfOfContentOwner OR order OR publishedAfter OR publishedBefore OR q OR topicId OR videoCaption OR videoCategoryId OR videoDefinition OR videoDimension OR videoDuration OR videoEmbeddable OR videoLicense OR videoSyndicated OR videoType);
        - IF eventType THEN type=='video';
        - AllOrNone(location, locationRadius);
#        - publishedAfter>=publishedBefore; # Date comparison is not supported yet
        - IF videoCaption THEN type=='video';
        - IF videoCategoryId THEN type=='video';
        - IF videoDefinition THEN type=='video';
        - IF videoDimension THEN type=='video';
        - IF videoDuration THEN type=='video';
        - IF videoEmbeddable THEN type=='video';
        - IF videoLicense THEN type=='video';
        - IF videoSyndicated THEN type=='video';
        - IF videoType THEN type=='video';
      responses:

#        (...)