Skip to content

Proposal for URI Template support #778

@darrelmiller

Description

@darrelmiller

This is a proposal to enable OpenAPI to support many of the features of URI Templates defined by RFC 6570, without adopting the URI Template syntax.

Overview

Open API already supports some of the URI Template capabilities but it does so with a simplified path template syntax and then parameter objects that describe the parameters.

In summary, the proposal is to add the following properties to the parameter object:

  • escape (Boolean, default true)
  • separator (Char)
  • explode (Boolean, default false)

Below is a description of the URI Template features and how these new parameter properties would work.

Details

RFC 6570 defines four levels of support.

Level 1: /bar/{foo}/baz

Open API already supports Level 1 templates

Level 2: {[+|#]foo}
This level adds support for fragment parameters and unescaped parameter values.
By adding the fragment option to the in property of the we could support fragment parameters. However, as fragment parameters are not sent from client to server, I'm not sure there is any value in adding this support.

Adding an escape Boolean property to the parameter object would allow OpenAPI parameters to specify whether parameter values be escaped. This should be an optional property with a default of true.

{
  "name": "callbackurl",
  "in": "query",
  "description": "Url to be called when event occurs",
  "required": true,
  "escape" : false,
  "schema": {
    "type": "string"
  }
}

Level 3: {[+|#|.|/|;|?|&]foo,bar}

This level adds a bunch of separator characters that are prefixed in front of the parameter value. By adding an optional separator property to the parameter object we can add this capability to OpenAPI. The value the ? and & parameters are debatable because we already known which parameters are in the query string.
The ability to have a list of parameter names in a var spec is just a syntax shortcut and I don't believe adds any capability that OpenAPI doesn't already have.

{
  "name": "colour",
  "in": "path",
  "description": "Optional Colour of car",
  "required": false,
  "separator" : ";",
  "schema": {
    "type": "string"
  }
}

With a path like

/cars/{make}/{model}{colour}/{year}

an output path might be

/cars/Honda/accord;red/2010 

Level 4: {[+|#|.|/|;|?|&]foo,bar[:n|*]]}

This level adds two suffix options and the support for values that are lists and maps. The :nsuffix option that allows you to just take the first few characters off a parameter value seems unnecessary to me.
The explode operator is useful if we accept supporting maps and lists as parameter values. Should map and list be added as two native parameter types? Adding an explode Boolean property to the parameter object would be sufficient to add this support.

{
  "name": "colour",
  "in": "path",
  "description": "Optional Colour of car",
  "required": true,
  "separator" : ";",
   "explode" : true,
  "schema": {
    "type": "string"
  }
}

With this parameter and assuming the path defined in the level 3 example and a parameter value of ["red","green","blue"] then you would get:

     /cars/Honda/accord;colour=red;colour=green;colour=blue/2010 

Constraints

There are certain capabilities in URI Templates that make it difficult for tooling to do the types of things that users are used to doing with OpenAPI. In order to limit the pain, there are some constraints that might be worth adding to these new parameter object properties:

  • Escape = false cannot be used in path parameters. This prevents the introduction of additional path segments due to the presence of forward slashes in parameter values. This makes mapping of URLs to operations difficult.
  • For similar reasons, should the / separator be allowed in path parameters?
  • Explode operator can only be true for parameters of type array and object.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions