Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: x-ms-examples #648

Closed
amarzavery opened this issue Oct 31, 2016 · 12 comments
Closed

Proposal: x-ms-examples #648

amarzavery opened this issue Oct 31, 2016 · 12 comments

Comments

@amarzavery
Copy link
Contributor

amarzavery commented Oct 31, 2016

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"
      }
    }
  }
}
@amarzavery
Copy link
Contributor Author

@veronicagg, @johanste - please review. Does this cover all the aspects w.r.t adding a sample for an operation ?

@brjohnstmsft
Copy link
Member

Just to add a data point here -- take a look at the examples in the Search Management Spec. While there is no way yet to see how these will render in reference documentation, I found it was at least possible to include all the examples from our current REST API documentation in the spec. The convention I chose was to use the model type example for what I expect to render as the "request" example in the docs, and the example in the responses section for the "response" example. This covered all the cases, at least for our (admittedly simple) spec.

What I like about the standard example element (besides the fact that it's already standard) is that it is simple and easy to use. My concern with this proposal as it stands is that it looks very complex, but then again maybe it is addressing scenarios that just don't matter for our spec.

@amarzavery
Copy link
Contributor Author

amarzavery commented Oct 31, 2016

  • The example provided for response of an API in the search swagger spec is slightly incorrect. The example of a response should be associated with a mime-type, as described in the swagger specification over here.
  • Network and Compute specs have the same model for input and output (body parameter of a PUT and response of the PUT operation are the same).
  • Spec author would want to document separate samples/examples for Operations that fall into the category of "createOrUpdate". A sample for Create and a sample for update, (both for input and output).
    The association with mime-type is a bummer, as the author can only provide one example per mime-type.
  • Adding sample data to the spec, would make the specs more lengthy (some specs are already 18000 lines long).
  • Benefits of the extension are already laid out in the proposal. The biggest one is that it provides a snapshot of the request and the response for that API all in one place.

@bradygaster-zz
Copy link

@brjohnstmsft @amarzavery i also noticed that on these lines of the spec you have an external docs node, but you don't have a title for it. When docs implements support for the externalDocs nodes we're going to need descriptive text to show to the user so they know what they're linking "to." Does the swagger spec allow for not providing a title for externalDocs? If so docs will need to come up with a way of supporting title-less externalDocs resources.

@brjohnstmsft
Copy link
Member

@bradygaster The Open API spec says that only the URL is required. It looks like the description is optional.

@bradygaster-zz
Copy link

@brjohnstmsft that's valuable to know. @amarzavery since the description isn't required is SDK team planning on implying a convention to request titles/descriptions with those? If they're not there, what sort of link text would we show? I guess we'd just show the URL on-screen? Seems sub-optimal.

@brjohnstmsft
Copy link
Member

@bradygaster I'm not sure teams other than Search regularly use externalDocs. I'd be happy to add descriptions to all usages if that makes the docs experience better.

@bradygaster-zz
Copy link

@brjohnstmsft i think that'd be good - the experience would be a lot better if we had descriptions. that said, docs engineers will need to make sure we don't depend on their provision and handle the case(s) in which they're not there.

@bradygaster-zz
Copy link

@amarzavery what's the status on this proposal? Have you guys begun using the extension actively and if not, what's your ETA for doing so? We want to make sure the spec is up to your plans for use of the extension so let me know the POR.

@veronicagg
Copy link
Contributor

veronicagg commented Dec 14, 2016

@bradygaster We're going forward with the extension. We're in the process of reviewing PR https://github.com/Azure/autorest/pull/1675/files/b4eec487239126225bf3364c04d6b22805952552..169ce10a0e1d423be825d52d6b8f29ea86ed9d5f to allow this extension in our schema.
We're also starting to ask teams to provide the data in this format.

@kirthik
Copy link
Contributor

kirthik commented Feb 2, 2017

Closing since we are already using this extension. Please feel free to open a new bug for any issues on that extension.

@kirthik kirthik closed this as completed Feb 2, 2017
@nandakus1
Copy link

Hi, Is there any option to add multiple examples (.json files) with different values to one request ? From below example we need to add createStorageAccount1.json and createStorageAccount2.json to same "Create a storage account"

"Create a storage account": { "$ref": "../examples/createStorageAccount.json" },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants