Skip to content

Proposal: x-ms-examples #648

Closed
Closed

Description

Current mechanism and its shortcomings

We looked at the current mechanism/format provided by swagger specification to provide examples.

Field Pattern Type Description
{mime type} Any The name of the property MUST be one of the Operation produces values (either implicit or inherited). The value SHOULD be an example of what such a response would look like.

Illustration:

{
  "application/json": {
    "name": "Puma",
    "type": "Dog",
    "color": "Black",
    "gender": "Female",
    "breed": "Mixed"
  }
}

shortcomings/concerns: What if the service team wants to show different examples. Scenario: GET on NetworkInterface with $expand and without $expand will have an impact on the NetworkSecurityGroup property of the NIC. In the former it will be a full blown NSG and in the latter it will be a Subresource(object with one property ‘id’)?

  • For any model definition (body parameter is a model definition; example: StorageAccountCreateParameters), swagger specfication says:
Field Name Type Description
example Any A free-form property to include an example of an instance for this schema.

shortcomings/concerns: Well this is good. But it does not provide a holistic picture of the entire request/response. We have to do extra processing to join the dots. When a Service developer thinks about an API endpoint, he/she would think in terms of sending a request to the endpoint and receiving a response from that endpoint.

Hence, having an extension at every operation level in a spec, would give us the biggest bang for the buck.

Benefits of this extension:

  • This will provide enough information about making a request against an endpoint/API.
  • The sample data (provided by the service developer) in the extension can be used to validate the data models (as a part of the Travis CI while the PR is sent to the azure-rest-apis-specs repo).
  • It can also be used to test the API/endpoint by running a live request with the help of some custom tool.
    • The live request can be recorded and the recording can be saved in a json format per scenario. This recording can then be used (directly or after some processing) to run playback tests in the sdk
  • It forms the basis of better documentation. The doc team can leverage this in lightening up the REST API documentation.

NOTE: We would not like to pollute the swagger spec with sample data. Hence the extension will contain a reference to the sample (a json file) in an adjacent folder of the spec.

For example: The location of storage spec is:

  • azure-rest-api-specs/arm-storage/2016-01-01/swagger/storage.json. So the examples for that api-version can reside at
  • azure-rest-api-specs/arm-storage/2016-01-01/examples/createStorageAccount.json

This will keep the spec cleaner and easy to manage.

Structure of the extension

  • How the extension would look in the swagger spec?
{
  "info": { ... },
  "paths": {
   "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}": {
      "put": {
        "operationId": "StorageAccounts_CreateOrUpdate",
        "description": "Creates or updates a storage account.",
        "x-ms-examples": {
          "Create a storage account": { "$ref": "../examples/createStorageAccount.json" },
          "Update a storage account": { "$ref": "../examples/updateStorageAccount.json" }
        },
        "parameters": [ ... ],
        "responses": { ... }
      }
    }
  },
  "definitions": { ... }
}
  • Skeleton of the extension
"x-ms-examples": {
  "example-name": {
    "parameters": {
       ...
    },
    "responses": {
      "statusCode1": {
        "headers": { ... },
        "body": { ... }
      },
      "statuscode2": { ... }
    }
  }
}
  • How would the content of an example file look like ?
{
  "parameters": {
      "subscriptionId": "34adfa4f-cedf-4dc0-ba29-b6d1a69ab345",
      "resourceGroupName": "testrg123",
      "storageAccountName": "testacc6141",
      "api-version": "2016-01-01",
      "accountCreateParameters": {
        "sku": { 
          "name": 'Standard_LRS' 
        },
        "kind": 'Storage',
        "location": 'eastasia',
        "properties": { 
          "encryption": { 
            "services": { 
              "blob": { 
                "enabled": true 
              }
            },
            "keySource": 'Microsoft.Storage' 
          }
        }
      }
   },
  "responses": {
    "200": {
      "headers": {
      },
      "body": {
        "id": "/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg123/providers/Microsoft.Storage/storageAccounts/testacc6141",
        "kind": "Storage",
        "location": "eastasia",
        "name": "testacc6141",
        "properties": {
          "creationTime": "2016-04-12T19:20:33.2288820Z",
          "encryption": {
            "keySource": "Microsoft.Storage",
            "services": {
              "blob": {
                "enabled": true,
                "lastEnabledTime": "2016-04-12T19:20:33.2298823Z"
              }
            }
          },
          "primaryEndpoints": {
            "blob": "https://testacc6141.blob.core.windows.net/",
            "file": "https://testacc6141.file.core.windows.net/",
            "queue": "https://testacc6141.queue.core.windows.net/",
            "table": "https://testacc6141.table.core.windows.net/"
          },
          "primaryLocation": "eastasia",
          "provisioningState": "Succeeded",
          "statusOfPrimary": "Available"
        },
        "sku": {
          "name": "Standard_LRS",
          "tier": "Standard"
        },
        "tags": {},
        "type": "Microsoft.Storage/storageAccounts"
      }
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions