Describes the format for specifying examples for request and response of an operation in a swagger spec. It is a dictionary of different variations of the examples for a given operation.
We looked at the current mechanism/format provided by swagger specification to provide examples.
- For a response, swagger specification says:
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.
- This will provide enough information about making a request against an endpoint/API.
- One can provide multiple examples for an operation and all of them are captured at one place.
- The sample data (provided by the service developer) in the extension will 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 forms the basis of better documentation. The doc team will leverage this in lightening up the REST API documentation.
- It will also be used to test the API/endpoint by running a live request with the help of some custom tool.
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 (examples) of the spec.
The detailed example MUST be specified in a separate json file in the example folder under the api-version folder.
For example: The location of a swagger spec for a given service in this repo looks like this:
- azure-rest-api-specs/arm-<serviceName>/2016-01-01/swagger/<serviceName>.json. So the examples for that api-version can reside at
- azure-rest-api-specs/arm-<serviceName>/2016-01-01/examples/createFooResource.json
This will keep the spec cleaner and easy to manage.
Parent element: Operation Object. It is applied on the operation in the swagger spec.
- How the extension would look in the swagger spec?
- JSON schema for the extension can be found here.
{
"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/Schema of the example provided in an individual example (json) file
- The JSON schema for the content to be provided in the example file can be found here.
"x-ms-examples": {
"example-name": { //Name of the example/scenario. It is free-form text and should succinctly describe the scenario.
"parameters": { //Provide examples for all the path, query, header, body, formData parameters as applicable.
...
},
"responses": { //Provide examples of the response headers and body per status code (as per the operation defined in the swagger spec) as applicable.
"statusCode1": {
"headers": { ... }, //Examples for location, azure-asyncoperation, retry-after response headers for long running (asynchronous) operations would be valueable
"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"
}
}
}
}