autorest

AutoRest Extensions for OpenAPI 2.0

Introduction

The following documents describes AutoRest specific vendor extensions for OpenAPI 2.0 schema. Code generation impact and support may vary per language. Some of the extensions are applicable to ARM APIs only, some are only metadatas and would not trigger code generator update.

Generic Extensions

Microsoft Azure Extensions (available in most generators only when using --azure-arm)

Metadata extensions

Those extensions are defined as additional description of the RestAPI, and do not trigger at the moment any changes in code generation.

Generic Extensions

x-ms-code-generation-settings

x-ms-code-generation-settings extension on info element enables passing code generation settings via the OpenAPI definition.

Parent element: Info Object

Schema:

Field Name Type Description
.* string or bool Required. Field name should be a valid autorest.exe parameter. Value should be a valid string value or boolean for flag parameters

Example:

"info": {
   "x-ms-code-generation-settings": {
      "header": "MIT",
      "internalConstructors": true,
      "useDateTimeOffset": true
   }
}

x-ms-skip-url-encoding

By default, path parameters will be URL-encoded automatically. This is a good default choice for user-provided values. This is not a good choice when the parameter is provided from a source where the value is known to be URL-encoded. The URL encoding is NOT an idempotent operation. For example, the percent character “%” is URL-encoded as “%25”. If the parameter is URL-encoded again, “%25” becomes “%2525”. Mark parameters where the source is KNOWN to be URL-encoded to prevent the automatic encoding behavior.

Parent element: Parameter Object

Schema: true|false

Example:

"parameters": [
  {
    "name": "databaseName",
    "in": "path",
    "type": "string",
    "required": true,
    "x-ms-skip-url-encoding": true
  }
]

x-ms-enum

Enum definitions in OpenAPI indicate that only a particular set of values may be used for a property or parameter. When the property is represented on the wire as a string, it would be a natural choice to represent the property type in C# and Java as an enum. However, not all enumeration values should necessarily be represented as strongly typed enums - there are additional considerations, such as how often expected values might change, since adding a new value to a strongly typed enum is a breaking change requiring an updated API version. Additionally, there is some metadata that is required to create a useful enum, such as a descriptive name, which is not represented in vanilla OpenAPI. For this reason, enums are not automatically turned into strongly typed enum types - instead they are rendered in the documentation comments for the property or parameter to indicate allowed values. To indicate that an enum will rarely change and that C#/Java enum semantics are desired, use the x-ms-enum extension. Note that depending on the code generation language the behavior of this extension may differ.

In C# and Java, an enum type is generated and is declared as the type of the related request/response object. The enum is serialized as the string expected by the REST API.

Parent element: Parameter Object, Schema Object, Items Object, or Header Object

Schema:

Field Name Type Description
name string Optional. Specifies the name for the Enum.
modelAsString boolean Default: true When set to true the enum will be modeled as a string. No validation will happen. When set to false, it will be modeled as an enum if that language supports enums. Validation will happen, irrespective of support of enums in that language.
values [{ value: any, description?: string, name?: string }] Default: undefined When set, this will override the values specified with enum, while also enabling further customization. We recommend still specifying enum as a fallback for consumers that don’t understand x-ms-enum. Each item in x-ms-enum corresponds to an enum item. Property value is mandatory and corresponds to the value one would also have specified using enum. Properties description and name are optional. name allows overriding the name of the enum value that would usually be derived from the value.

Example:

accountType:
  type: string
  enum:
    - Standard_LRS
    - Standard_ZRS
    - Standard_GRS
    - Standard_RAGRS
    - Premium_LRS
  x-ms-enum:
    name: AccountType
    modelAsString: false
    values:
      - value: Standard_LRS
        description: Locally redundant storage.
        name: StandardLocalRedundancy
      - value: Standard_ZRS
        description: Zone-redundant storage.
      - value: Standard_GRS
        name: StandardGeoRedundancy
      - value: Standard_RAGRS
      - value: Premium_LRS

Single value enum

Will be treated as an extensible enum(Same as with multi value enum)

x-ms-parameter-grouping

By default operation parameters are generated in the client as method arguments. This behavior can sometimes be undesirable when the number of parameters is high. x-ms-parameter-grouping extension is used to group multiple primitive parameters into a composite type to improve the API.

Parent element: Parameter Object

Schema:

Field Name Type Description
name string When set, specifies the name for the composite type.
postfix string Alternative to name parameter. If specified the name of the composite type will be generated as follows {MethodGroup}{Method}{Postfix}.

If none of the parameters are set the name of the composite type is generated as follows {MethodGroup}{Method}Parameters.

Example:

"/some/{pathParam1}/{pathParam2}": {
  "operationId": "Update",
  "post": {
    "parameters": [
    {
        "name": "headerParam",
        "in": "header",
        "type": "string",
        "required": false,
        "x-ms-parameter-grouping": {
          "name": "custom-parameter-group"
        }
    },
    {
        "name": "pathParam1",
        "in": "path",
        "type": "string",
        "required": true,
        "x-ms-parameter-grouping": {
          "name": "custom-parameter-group"
        }
    },
    {
        "name": "pathParam2",
        "in": "path",
        "type": "string",
        "required": true,
        "x-ms-parameter-grouping": {
          "name": "custom-parameter-group"
        }
    }]
  }
}

Above OpenAPI definition will produce a type CustomParameterGroup with 3 properties (if applicable in the generator language).

x-ms-parameter-location

By default Autorest processes global parameters as properties on the client. For example subscriptionId and apiVersion which are defined in the global parameters section end up being properties of the client. It would be natural to define resourceGroupName once in the global parameters section and then reference it everywhere, rather than repeating the same definition inline everywhere. One may not want resourceGroupName as a property on the client, just because it is defined in the global parameters section. This extension helps you achieve that. You can add this extension with value “method” "x-ms-parameter-location": "method" and resourceGroupName will not be a client property.

Note:

Example:

{
  "swagger": "2.0",
  "host": "management.azure.com",
  "info": {
    "title": "AwesomeClient",
    "version": "2015-05-01"
  },
  "paths": {
    "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}": {
      "put": {
        "operationId": "StorageAccounts_Create",
        . . .
        "parameters": [
          {
            "$ref": "#/parameters/ResourceGroupName"   <<<<<<<<<<<<<<<<<<<<
          },
          {
            "name": "accountName",
            "in": "path",
            "required": true,
            "type": "string",
            "description": "The name of the storage account within the specified resource group. Storage account names must be between 3 and 24 characters in length and use numbers and lower-case letters only.  "
          },
          {
            "name": "parameters",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/StorageAccountCreateParameters"
            },
            "description": "The parameters to provide for the created account."
          },
          {
            "$ref": "#/parameters/ApiVersionParameter"
          },
          {
            "$ref": "#/parameters/SubscriptionIdParameter"
          }
        ]
        . . .
      }
    }
  },
  . . .
  "parameters": {
    "SubscriptionIdParameter": {
      "name": "subscriptionId",
      "in": "path",
      "required": true,
      "type": "string",
      "description": "Gets subscription credentials which uniquely identify Microsoft Azure subscription. The subscription ID forms part of the URI for every service call."
    },
    "ApiVersionParameter": {
      "name": "api-version",
      "in": "query",
      "required": true,
      "type": "string",
      "description": "Client Api Version."
    },
    "ResourceGroupName": {
      "description": "The name of the resource group within the user’s subscription.",
      "in": "path",
      "name": "resourceGroupName",
      "required": true,
      "type": "string",
      "x-ms-parameter-location": "method" <<<<<<<<<<<<<<<<<<<<<<<<<<<
    }
  }
}
public static StorageAccount Create(this IStorageAccountsOperations operations, string resourceGroupName, string accountName, StorageAccountCreateParameters parameters);
public partial class StorageManagementClient : ServiceClient<StorageManagementClient>, IStorageManagementClient, IAzureClient
{
    public string SubscriptionId { get; set; } //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    public string ApiVersion { get; private set; }  //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    public StorageManagementClient(Uri baseUri, ServiceClientCredentials credentials, params DelegatingHandler[] handlers) : this(handlers)
    {
        if (baseUri == null)
        {
            throw new ArgumentNullException("baseUri");
        }
        if (credentials == null)
        {
            throw new ArgumentNullException("credentials");
        }
        this.Credentials = credentials;
        if (this.Credentials != null)
        {
            this.Credentials.InitializeServiceClient(this);
        }
    }

    private void Initialize()
    {
        this.StorageAccounts = new StorageAccountsOperations(this);
        this.Usage = new UsageOperations(this);
        this.BaseUri = new Uri("https://management.azure.com");
        this.ApiVersion = "2016-01-01";
        . . .
    }
}

x-ms-paths

OpenAPI 2.0 has a built-in limitation on paths. Only one operation can be mapped to a path and http method. There are some APIs, however, where multiple distinct operations are mapped to the same path and same http method. For example GET /mypath/query-drive?op=file and GET /mypath/query-drive?op=folder may return two different model types (stream in the first example and JSON model representing Folder in the second). Since OpenAPI does not treat query parameters as part of the path the above 2 operations may not co-exist in the standard “paths” element.

To overcome this limitation an “x-ms-paths” extension was introduced parallel to “paths”. URLs under “x-ms-paths” are allowed to have query parameters for disambiguation, however they are not actually used.

Parent element: Swagger Object

Schema: The x-ms-paths extension has the same schema as Paths Object with exception that Path Item Object can have query parameters.

Example:

paths:
   "/pets":
        get:
            ...
x-ms-paths:
   "/pets?color={color}":
        get:
            parameters:
              - name: color
                in: query
                # Declaring this parameter is still necessary!
                # The `?color={color}` part of the path is
                # completely ignored and only serves the purpose
                # of disambiguation and documentation.
            ...

As in the example above, there should be one “overload” of the operation in the paths section. While technically this is not necessary (one could have put both /pets and /pets?color={color} into x-ms-paths), it makes sense to resort to x-ms-paths as little as possible in order to provide other OpenAPI tools with as much information as possible. We recommend putting the most generic overload into the paths section.

x-ms-client-name

In some situations, data passed by name, such as query parameters, entity headers, or elements of a JSON document body, are not suitable for use in client-side code. For example, a header like ‘x-ms-version’ would turn out like xMsVersion, or x_ms_version, or XMsVersion, depending on the preferences of a particular code generator. It may be better to allow a code generator to use ‘version’ as the name of the parameter in client code.

By using the ‘x-ms-client-name’ extension, a name can be defined for use specifically in code generation, separately from the name on the wire. It can be used for query parameters and header parameters, as well as properties of schemas.

Parameter Example:

  "parameters": {
    "ApiVersionParameter": {
      "name": "x-ms-version",
      "x-ms-client-name": "version",
      "in": "header",
      "required": false,
      "type": "string",
      "x-ms-global": true,
      "enum": [
        "2015-04-05",
        "2014-02-14",
        "2013-08-15",
        "2012-02-12",
        "2011-08-18",
        "2009-09-19",
        "2009-07-17",
        "2009-04-14"
      ],
      "default": "2015-04-05",
      "description": "Specifies the version of the operation to use for this request."
    }

Property Example:

{
  "definitions": {
    "Product": {
      "x-ms-external" : true,
      "properties": {
        "product_id": {
          "type": "string"
		  "x-ms-client-name": "SKU"
        }
     }
  }
}

x-ms-external

To allow generated clients to share models via shared libraries an x-ms-external extension was introduced. When a Schema Object contains this extensions it’s definition will be excluded from generated library. Note that in strongly typed languages the code will not compile unless the assembly containing the type is referenced with the project/library.

Parent element: Schema Object

Schema: true|false

Example:

{
  "definitions": {
    "Product": {
      "x-ms-external" : true,
      "properties": {
        "product_id": {
          "type": "string"
        }
     }
  }
}

x-ms-discriminator-value

Swagger 2.0 specification requires that when used, the value of discriminator field MUST match the name of the schema or any schema that inherits it. To overcome this limitation x-ms-discriminator-value extension was introduced.

Schema: string - the expected value of the discriminator field on the wire.

Parent element: Schema Object

Example:

"definitions": {
  "SqlDefinition": {
      "x-ms-discriminator-value": "USql",
      "allOf": [
        {
          "$ref": "#/definitions/SqlProperties"
        }
      ]
   }
}

x-ms-client-flatten

This extension allows to flatten deeply nested payloads into a more user friendly object. For example a payload that looks like this on the wire:

{
  template: {
    name: "some name",
    properties: {
      prop1: "value1",
      prop2: "value2",
      url: {
        value: "http://myurl",
      },
    },
  },
}

can be transformed into the following client model:

public class Template
{
    public string Name {get;set;}
    public string Prop1 {get;set;}
    public string Prop2 {get;set;}
    public string UrlValue {get;set;}
}

by using the following OpenAPI definition:

"definitions": {
  "template": {
    "properties": {
      "name": {
        "type": "string"
      },
      "properties": {
        "x-ms-client-flatten": true,
        "$ref": "#/definitions/templateProperties"
      }
    }
  }
}

It’s also possible to flatten body parameters so that the method will look like this:

client.DeployTemplate("some name", "value1", "value2", "http://myurl");

by using the following OpenAPI definition:

"post": {
  "operationId": "DeployTemplate",
  "parameters": [
  {
     "name": "body",
     "in": "body",
     "x-ms-client-flatten": true,
     "schema": {
       "$ref": "#/definitions/template"
     }
    }
  ]
}

Parent element: Parameter Objects or Property on the Schema Definition. In both cases the type of the parameter or property should be a complex schema with properties.

Schema: true|false

Example:

"definitions": {
  "template": {
    "properties": {
      "name": {
        "type": "string"
      },
      "properties": {
        "x-ms-client-flatten": true,
        "$ref": "#/definitions/templateProperties"
	    }
    }
  }
}

and

"post": {
  "operationId": "DeployTemplate",
  "parameters": [
  {
     "name": "body",
     "in": "body",
     "x-ms-client-flatten": true,
     "schema": {
       "$ref": "#/definitions/template"
     }
    }
  ]
}

x-ms-parameterized-host

When used, replaces the standard OpenAPI “host” attribute with a host that contains variables to be replaced as part of method execution or client construction, very similar to how path parameters work.

Parent element: Swagger Object

Schema:

Field Name Type Description
hostTemplate string Required. Specifies the parameterized template for the host.
useSchemePrefix boolean Optional, Default: true. Specifies whether to prepend the default scheme a.k.a protocol to the base uri of client.
positionInOperation string Optional, Default: first. Specifies whether the list of parameters will appear in the beginning or in the end, in the method signature for every operation. The order within the parameters provided in the below mentioned array will be preserved. Either the array of parameters will be prepended or appended, based on the value provided over here. Valid values are “first”, “last”. Every method/operation in any programming language has parameters categorized into two buckets “required” and “optional”. It is natural for optional parameters to appear in the end in a method signature. This aspect will be preserved, while prepending(first) or appending(last) hostTemplate parameters .
parameters Array of Parameter Objects The list of parameters that are used within the hostTemplate. This can include both reference parameters as well as explicit parameters. Note that “in” is required and must be set to “path”. The reference parameters will be treated as global parameters and will end up as property of the client.

Example:

"x-ms-parameterized-host": {
    "hostTemplate": "{accountName}.{adlaJobDnsSuffix}",
    "positionInOperation": "last",
    "parameters": [
      {
        "name": "accountName",
        "description": "The Azure Data Lake Analytics account to execute job operations on.",
        "required": true,
        "type": "string",
        "in": "path",
        "x-ms-skip-url-encoding": true
      },
      {
        "$ref": "#/parameters/adlaJobDnsSuffixInPath"
      }
    ]
  }
...
"adlaJobDnsSuffixInPath": {
      "name": "adlaJobDnsSuffix",
      "in": "path",
      "required": true,
      "type": "string",
      "default": "azuredatalakeanalytics.net",
      "x-ms-skip-url-encoding": true,
      "description": "Gets the DNS suffix used as the base for all Azure Data Lake Analytics Job service requests."
    }
"x-ms-parameterized-host": {
    "hostTemplate": "{accountName}.mystaticsuffix.com",
    "useSchemePrefix": false,
    "positionInOperation": "first",
    "parameters": [
      {
        "name": "accountName",
        "description": "The Azure Data Lake Analytics account to execute job operations on.",
        "required": true,
        "type": "string",
        "in": "path",
        "x-ms-skip-url-encoding": true
      }
    ]
  }

x-ms-mutability

This extension offers insight to Autorest on how to generate code (mutability of the property of the model classes being generated). It doesn’t alter the modeling of the actual payload that is sent on the wire.

It is an array of strings with three possible values. The array cannot have repeatable values. Valid values are: “create”, “read”, “update”.

Field Name Description
create Indicates that the value of the property can be set while creating/initializing/constructing the object
read Indicates that the value of the property can be read
update Indicates that value of the property can be updated anytime(even after the object is created)

Rules:

Examples:

"definitions": {
  "Resource": {
    "description": "The Resource Model definition.",
    "properties": {
      "id": {
        "readOnly": true,
        "type": "string",
        "description": "Resource Id",
        "x-ms-mutability": ["read"]
      },
      "name": {
        "type": "string",
        "description": "Resource name"
      },
      "type": {
        "type": "string",
        "description": "Resource type",
        "x-ms-mutability": ["read"]
      },
      "location": {
        "type": "string",
        "description": "Resource location",
        "x-ms-mutability": ["create", "read"]
      },
      "tags": {
        "type": "object",
        "additionalProperties": {
          "type": "string"
        },
        "description": "Resource tags",
        "x-ms-mutability": ["create", "read", "update"]
      }
    },
    "required": [
      "location"
    ],
    "x-ms-azure-resource": true
  }
}
"definitions": {
  "ResourceCollection": {
    "description": "Collection of Resource objects. Resource is defined in the above example.",
    "properties": {
      "value": {
        "type": "array",
        "description": "Array of Resource objects.",
        "x-ms-mutability": ["create", "read", "update"], //This means that the array is mutable
        "items": {
          "type": object,
          "x-ms-mutability": ["create", "read"] // X - Applying mutability on the itemType of the array or valueType of the dictionary is not allowed.
          "schema": {
            "$ref": "#/definitions/Resource" // The mutability of the properties of the Resource object is governed by the mutability defined in it's model definition.
          }
        }
      }
    }
  }
}

x-ms-examples

Describes the format for specifying examples for request and response of an operation in an OpenAPI definition. It is a dictionary of different variations of the examples for a given operation.

More information about this extension can be found here.

Microsoft Azure Extensions (available in most generators only when using --azure-arm)

x-ms-odata

When present the x-ms-odata extensions indicates the operation includes one or more OData query parameters. These parameters include $filter, $top, $orderby, $skip, and $expand. In some languages the generated method will expose these parameters as strongly types OData type.

Schema: ref to the definition that describes object used in filter.

Parent element: Operation Object

Example:

"paths": {
  "/subscriptions/resource": {
    "get": {
      "x-ms-odata": "#/definitions/Product"
    }
  }
}

x-ms-error-response

Indicates whether the response status code should be treated as an error response or not.

Parent element: Response Object

Schema: true|false

Example:

. . .
  "responses": {
    "200": {
      "description": "",
      "schema": {
        "$ref": "#/definitions/Pet"
      }
    },
    "202": {
      "description": "something something dark side"
    },
    "404": {
      "description": "Not found",
      "schema": {
        "$ref": "#/definitions/NotFoundErrorBase"
      },
      "x-ms-error-response": true
    },
    "400": {
      "description": "Bad request",
      "schema": {
        "type": "string"
      },
      "x-ms-error-response": true
    },
    "501": {
      "description": "Some unexpected error",
      "schema": {
        "type": "integer"
      },
      "x-ms-error-response": true
    },
    "default": {
      "description": "default stuff"
    }
  }
. . .

x-ms-text

Swagger spec doesn’t allow dev to model this XML structure: <title language="text">the title</title> This is well known issue: https://github.com/OAI/OpenAPI-Specification/issues/630

This extension is defined to help for this scenario.

Note: The extension is not tight to this particular scenario (you could model any text node that way), but we recommend to follow as much as possible the Swagger specification, and to use it only in case of attributes/text.

Parent element: XML Object

Schema: true|false

Example:

. . .
    "properties":{
        "language": {
          "xml": {
            "attribute": true,
            "name": "language"
          },
          "type": "string",
          "description": "Returned value should be 'english'"
        },
        "content": {
          "xml": {
            "x-ms-text": true
          },
          "description": "Returned value should be 'I am text'",
          "type": "string"
        }
      },
. . .

x-ms-client-default

Set the default value for a property or a parameter on the client. With this extension, you can set a default value for a property or parameter that is independent of how the property / parameter’s schema is handling a default.

x-ms-client-default vs default:

Parent element: Parameter Objects or Property on the Schema Definition.

Schema: string, integer, long, float, double, boolean - the default value for the property / parameter

Parameter Example:

. . .
    "parameters": [
      {
        "name": "parameterWithClientDefault",
        "in": "query",
        "type": "string",
        "enum": [
          "value1",
          "value2"
        ],
        "x-ms-enum": {
          "name": "ParameterWithClientDefaultEnum",
          "modelAsString": false
        },
        "required": true,
        "x-ms-client-default": "value1"
      }
    ],
. . .

Property Example:

. . .
    "properties": {
      "propertyWithClientDefault": {
          "type": "string",
          "enum": [
              "value1",
              "value2"
          ],
          "x-ms-enum": {
              "name": "PropertyWithClientDefaultEnum",
              "modelAsString": true
          },
          "x-ms-client-default": "value1"
      }
    }
. . .

x-ms-pageable

The REST API guidelines define a common pattern for paging through lists of data. The operation response is modeled in OpenAPI as a list of items (a “page”) and a link to the next page, effectively resembling a singly linked list. Tag the operation as x-ms-pageable and the generated code will include methods for navigating between pages.

Note: The request to the nextLink URL will be a GET request unless operationName is specified. If operationName is specified, the request will use the HTTP method for that operation.

Schema:

Field Name Type Description
itemName string Optional (default: value). Specifies the name of the property that provides the collection of pageable items.
nextLinkName string Required. Specifies the name of the property that provides the next link (common: nextLink). If the model does not have a next link property then specify null. This is useful for services that return an object that has an array referenced by itemName. The object is then flattened in a way that the array is directly returned, no paging is used. This provides a better client side API to the end user.
operationName string Optional (default: <operationName>Next). Specifies the name (operationId) of the operation for retrieving the next page.

Parent element: Operation Object

Example 1: Canonical

Basic use of x-ms-pageable:

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple API
produces:
  - application/json
paths:
  /getIntegers:
    get:
      operationId: list
      description: "Gets those integers."
      x-ms-pageable:                            # EXTENSION
        nextLinkName: nextLink                  # property name for next page URL
      responses:
        200:
          description: OK
          schema:
            $ref: '#/definitions/PagedIntegerCollection'
definitions:
  PagedIntegerCollection:
    description: "Page of integers."
    type: object
    properties:
      value:                                    # the current page
        type: array
        items:
          type: integer
      nextLink:                                 # next page URL (referred to by "nextLinkName")
        type: string

Generated signatures:

IPage<int?>       List(ISimpleAPIClient operations);
Task<IPage<int?>> ListAsync(ISimpleAPIClient operations, CancellationToken cancellationToken);
IPage<int?>       ListNext(ISimpleAPIClient operations, string nextPageLink);
Task<IPage<int?>> ListNextAsync(ISimpleAPIClient operations, string nextPageLink, CancellationToken cancellationToken);

Example 2: Customized

Customizing code generation:

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple API
produces:
  - application/json
paths:
  /getIntegers:
    get:
      operationId: list
      description: "Gets those integers."
      x-ms-pageable:                            # EXTENSION
        nextLinkName: nextIntegersUrl           # property name for next page URL
        value: payload                          # property name for current page (overrides "value")
        operationName: listMore                 # method name for retrieving next page (overrides "listNext")
      responses:
        200:
          description: OK
          schema:
            $ref: '#/definitions/PagedIntegerCollection'
definitions:
  PagedIntegerCollection:
    description: "Page of integers."
    type: object
    properties:
      payload:                                  # the current page (referred to by "value")
        type: array
        items:
          type: integer
      nextIntegersUrl:                          # next page URL (referred to by "nextLinkName")
        type: string

Generated signatures:

IPage<int?>       List(ISimpleAPIClient operations);
Task<IPage<int?>> ListAsync(ISimpleAPIClient operations, CancellationToken cancellationToken);
IPage<int?>       ListMore(ISimpleAPIClient operations, string nextPageLink);
Task<IPage<int?>> ListMoreAsync(ISimpleAPIClient operations, string nextPageLink, CancellationToken cancellationToken);

Example 3: Single page result

Providing a better user experience for single page response models:

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple API
produces:
  - application/json
paths:
  /getIntegers:
    get:
      operationId: list
      description: "Gets those integers."
      x-ms-pageable:
        nextLinkName: null                      # there are no further pages
        value: payload                          # property name for the "page" (overrides "value")
      responses:
        200:
          description: OK
          schema:
            $ref: '#/definitions/PagedIntegerCollection'
definitions:
  PagedIntegerCollection:
    description: "Page of integers."
    type: object
    properties:
      payload:                                  # the only "page" (referred to by "value")
        type: array
        items:
          type: integer

Generated signatures:

IEnumerable<int?>       List(ISimpleAPIClient operations);
Task<IEnumerable<int?>> ListAsync(ISimpleAPIClient operations, CancellationToken cancellationToken);

x-ms-long-running-operation

Some requests like creating/deleting a resource cannot be carried out immediately. In such a situation, the server sends a 201 (Created) or 202 (Accepted) and provides a link to monitor the status of the request. When such an operation is marked with extension "x-ms-long-running-operation": true, in OpenAPI, the generated code will know how to fetch the link to monitor the status. It will keep on polling at regular intervals till the request reaches one of the terminal states: Succeeded, Failed, or Canceled.

x-ms-long-running-operation-options

When x-ms-long-running-operation-options is specified, there should also be a x-ms-long-running-operation: true specified.

See Azure RPC Spec for asynchronous operation notes.

You probably don’t need to use this option if you follow ARM guidelines. This option is designed for cases where the server do NOT follow ARM, and we need to guide the runtime through a peculiar flow.

Schema: Field Name | Type | Description —|:—:|— final-state-via | string - one of azure-async-operation or location or original-uri or operation-location | final-state-via SHOULD BE one of

The polling mechanism in itself remains unchanged, the only impact of this option could be to do an additional final GET, or skip a final GET.

Parent element: Operation Object

Example:

"paths": {
  "/products/{name}": {
    "put": {
      "operationId": "products_create",
      "x-ms-long-running-operation": true,
      "x-ms-long-running-operation-options" : {
          "final-state-via" : "location"
      },
      "description": "A pageable list of Products."
    }
  }
}

x-ms-azure-resource

Resource types as defined by the Resource Manager API are tagged by using a x-ms-azure-resource extension.

Parent element: Schema Object

Schema: true|false

Example:

"Resource": {
  "x-ms-azure-resource": true,
  "properties": {
    "id": {
      "type": "string",
      "readOnly": true,
      "description": "Resource Id"
    }
  }
}

x-ms-request-id

When set, allows to overwrite the x-ms-request-id response header (default is x-ms-request-id).

Parent element: Operation Object

Schema: string - the name of the request id header to use when setting Response.RequestId property.

Example:

"paths": {
  "/products/{name}": {
    "get": {
      "operationId": "products_create",
      "x-ms-request-id": "request-id"
    }
  }
}

x-ms-client-request-id

When set, specifies the header parameter to be used instead of x-ms-client-request-id (default is x-ms-client-request-id).

Parent element: Header Parameter Object

Schema: string - the name of the client request id header to use when setting sending request.

Example:

"paths": {
  "/products/{name}": {
    "get": {
      "operationId": "products_create",
      "parameters": [{
        "name": "x-ms-client-request-id",
        "in": "header",
        "type": "string",
        "required": false,
        "x-ms-client-request-id": true
      }]
    }
  }
}

x-ms-arm-id-details

Can only be set on "type": "string" fields with "format": "arm-id".

When set, specifies the set of resource types which can be referenced by this arm-id. If this extension isn’t provided for a particular arm-id, the field can refer to any valid ARM ID.

Parent element: Parameter Object, Schema Object, or Items Object

Schema

Field Name Type Description
allowedResources [AllowedResource] Required An array of allowed ARM resources. Each element represents a particular type of ARM resource which can be referred to by this arm-id.

AllowedResource schema:

Field Name Type Description
scopes [string] An array of scopes. See Allowed Scopes. If not specified, the default scope is ["ResourceGroup"].
type string Required The type of resource that is being referred to. For example Microsoft.Network/virtualNetworks or Microsoft.Network/virtualNetworks/subnets. See Example Types for more examples.

Allowed Scopes

The following values are allowed for scopes. These values were derived from the scope field in ARM templates. | Scope | URL prefix | Meaning | | —————– | ——————————————————————————- | ————————————————————————————————————————————————————- | | Tenant | / | The resource is deployed into a tenant | | Subscription | /subscriptions/{subscriptionId}/ | The resource is deployed into a subscription | | ResourceGroup | /subscriptions/{subscriptionId}/resourceGroups/{group} | The resource is deployed into a resource group | | ManagementGroup | /providers/Microsoft.Management/managementGroups/{managementGroupName}/ | The resource is deployed into a management group | | Extension | {parentScope}/providers/{extensionNamespace}/{extensionType}/{extensionName}/ | The resource is an extension resource and may be deployed as a subresource of another resource. parentScope may be a resource in any of the above scopes. | | * | Any of the above | The resource may be deployed into any of the above scopes. This is identical to ["Tenant", "Subscription", "ResourceGroup", "ManagementGroup", "Extension"] |

Example Types

Below is a table showing an example entry for various different kinds of resource types

Resource kind Example
Resource in a tenant {"scopes": ["Tenant"], "type": "Microsoft.Capacity/reservationOrders"}
Resource in a subscription {"scopes": ["Subscription"], "type": "Microsoft.Resources/resourceGroups"}
Resource in a resource group {"scopes": ["ResourceGroup"], "type": "Microsoft.Network/virtualNetworks"}
Resource in a management group {"scopes": ["ManagementGroup"], "type": "Microsoft.Blueprint/blueprints"}
Extension resource {"scopes": ["Extension"], "type": "Microsoft.Authorization/locks"}
Any resource in resource group {"scopes": ["ResourceGroup"], "type": "*"}
Any compute resource in resource group {"scopes": ["ResourceGroup"], "type": "Microsoft.Compute/*"}

Sub-resources are specified in the same manner as their parent resource but with additional paths on the end. For example to refer to a subnet: Microsoft.Network/virtualNetworks/subnets.

Note that we do not currently support limiting references to an extension resource by the kind of resource it is on. For example you can refer to any resource lock (Microsoft.Authorization/locks) but not to a resource lock but only when it’s on a CosmosDB.

Examples

Example: An arm-id field that can refer to any ARM resource ID.

"MyExampleType": {
  "properties": {
    "id": {
      "type": "string",
      "format": "arm-id"
    }
  }
}

Example: An arm-id field that must refer to a virtual network

"MyExampleType": {
  "properties": {
    "vnetId": {
      "type": "string",
      "format": "arm-id",
      "x-ms-arm-id-details": {
        "allowedResources": [
          {
            "type": "Microsoft.Network/virtualNetworks"
          }
        ]
      }
    }
  }
}

Example: An arm-id field in a parameter.

"parameters": [
  {
    "name": "scope",
    "in": "path",
    "required": true,
    "type": "string",
    "format": "arm-id",
    "x-ms-skip-url-encoding": true
  },
  ...
]

Example: An arm-id field that can refer to any ARM resource ID.

"MyExampleType": {
  "properties": {
    "id": {
      "type": "string",
      "format": "arm-id"
    }
  }
}

Example: An array of arm-id’s that refer to a subnet

"MyExampleType": {
  "properties": {
    "vnets": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "arm-id",
        "x-ms-arm-id-details": {
          "allowedResources": [
            {
              "type": "Microsoft.Network/virtualNetworks/subnets"
            }
          ]
        }
      }
    }
  }
}

x-nullable

Set "x-nullable": true on a schema to indicate that a null is a legal value. By default, a null value should be disallowed when forming a request and rejected during payload deserialization.

For arrays, sending/receiving a null array entry is not supported and should result in an error.

Example: An operation that returns a scalar value or null.

"responses": {
  "200": {
    "description": "The assigned integer, or null if unassigned.",
    "schema": {
      "type": "integer",
      "x-nullable": true
    }
  }
}

Example: An operation that returns an object or null.

"responses": {
  "200": {
    "description": "The active Widget or null.",
    "schema": {
      "x-nullable": true,
      "allOf": {
        "$ref": "#/definitions/Widget"
      }
    }
  }
}

Example: A dictionary where a key’s value can be null.

{
  "name": "arrayBody",
  "in": "body",
  "schema": {
    "description": "Credential key/value pairs.  Set the credential key's value to null to remove the credential.",
    "type": "object",
    "credentials": {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "x-nullable": true
      }
    }
  }
}

Example: An object with a nullable property.

"Widget": {
  "type": "object",
  "properties": {
    "size": {
      "description": "widget size",
      "type": "integer"
    },
    "shape": {
      "description": "optional widget shape",
      "type": "string",
      "x-nullable": true
    }
  }
}

x-ms-header-collection-prefix

Handle collections of arbitrary headers by distinguishing them with a specified prefix. Has different behavior if it refers to a request header or a response header:

Additionally, applying this extension to a schema forces the schema to become a dictionary.

Schema: string. Name of the prefix you want to append / filter by. A common value for storage libraries is x-ms-meta-.

Request Example:

"parameters": [
  {
    "name": "x-ms-meta",
    "in": "header",
    "type": "string",
    "x-ms-parameter-location": "method",
    "x-ms-header-collection-prefix": "x-ms-meta-"
  }
]

This request parameter will be forced to be a dictionary schema, and all keys in this dictionary will be prefixed with x-ms-meta-. So, if you input a header with name key and value value through this parameter,

GET /path HTTP/1.1
x-ms-meta-key: value

is what reaches the service.

Response Example:

"responses": {
  "200": {
    "description": "Success",
    "headers": {
      "x-ms-meta": {
        "type": "string",
        "x-ms-client-name": "Metadata",
        "x-ms-header-collection-prefix": "x-ms-meta-"
      }
    }
  }
}

This response header parameter will be forced to be a dictionary schema. Only entries with prefix x-ms-meta- will be returned to users, and this prefix will be stripped before be returned to users. So if the response from the service is

headers:
  - rejected-key: value
  - x-ms-meta-key: value

What is returned to users is just key: value.

Metadata Extensions

x-ms-secret

This extension is used to annotate the secret property. The value type is boolean and the allowed value is either true or false. Secrets should never expose on a GET. If a secret does need to be returned after the fact, a POST api can be used to allow for granular RBAC.

Rule

Schema: true|false

Example:

"SecretAuthInfo": {
      "type": "object",
      "description": "The authentication info when authType is secret",
      "properties": {
        "name": {
          "description": "Username or account name for secret auth.",
          "type": "string"
        },
        "secret": {
          "description": "Password or account key for secret auth.",
          "type": "string",
          "x-ms-secret": true
        }
    }
}

x-ms-identifiers

(InProgress) This extension is used to indicate the identifying properties of objects in the array, e.g., id, name, uid.

Rule

Schema: array

Example:

"myArrayProperty": {​
  "type":"array",
  "items": {
    "$ref":"#/definitions/Example"​
  },
  "x-ms-identifiers": ["propertyName"]​
}

x-ms-azure-rbac-permissions-required

(InProgress) Specify permission exceptions for autogenerated public Azure REST API reference documentation.

The doc processor has an opt-in option to autogenerate the required permissions by parsing the API. However, there will be situations where the autogeneration of the required permissions is not accurate. This extension enables you to specify permission exceptions for individual APIs.

Permissions example #1

Here is a Virtual Machines - Get permissions example that does not require the x-ms-azure-rbac-permissions-required extension:

GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}?api-version=2021-11-01

Autogenerated permissions from doc processor:

Microsoft.Compute/virtualMachines/read

Permissions example #2

Here is an Assignments - Create Or Update permissions example that does require the x-ms-azure-rbac-permissions-required extension:

PUT https://management.azure.com/{resourceScope}/providers/Microsoft.Blueprint/blueprintAssignments/{assignmentName}?api-version=2018-11-01-preview

Autogenerated permissions from doc processor:

Microsoft.Blueprint/blueprintAssignments/write

Actual permissions required to call API:

Microsoft.Blueprint/blueprintAssignments/write and Microsoft.ManagedIdentity/userAssignedIdentities/assign/action

Schema:

Field Name Type Description
actions string List of the required action permissions for this API.
dataActions string List of the required data action permissions for this API.
rolesWithThesePermissions [string] An array of roles that have the required permissions for this API.
moreInfoLink string Link formatted as markdown with more information about the permissions for this API.

For a list roles, see Azure built-in roles.

"xmsPermissions": {
  "type": "object",
  "properties": {
    "actions": {
      "type": "string"
    },
    "dataActions": {
      "type": "string"
    },
    "rolesWithThesePermissions": [
      "type": "string"
    ],
    "moreInfoLink": {
      "type": "string"
    }
  }
}

Example:

"x-ms-azure-rbac-permissions-required": {
  "actions": "Microsoft.Blueprint/blueprintAssignments/write and Microsoft.ManagedIdentity/userAssignedIdentities/assign/action",
  "dataActions": "",
  "rolesWithThesePermissions": [
    "Blueprint Operator"
  ],
  "moreInfoLink": "[Learn more](https://docs.microsoft.com/azure/governance/blueprints/how-to/configure-for-blueprint-operator)"
}

Example:

"x-ms-azure-rbac-permissions-required": {
  "actions": "",
  "dataActions": "Microsoft.Storage/storageAccounts/queueServices/queues/messages/process/action or (Microsoft.Storage/storageAccounts/queueServices/queues/messages/delete and Microsoft.Storage/storageAccounts/queueServices/queues/messages/read)",
  "rolesWithThesePermissions": [
    "Storage Queue Data Message Processor",
    "Storage Queue Data Contributor"
  ],
  "moreInfoLink": "[Authorize access to blobs and queues using Azure Active Directory](https://docs.microsoft.com/azure/storage/blobs/authorize-access-azure-active-directory)"
}