API Definitions as Developer Contracts

Mark W.

Mike Kistler

Developers are at the core of everything we do at Microsoft. Our Azure service teams are constantly working to improve the clarity and consistency of API definitions. We believe it’s important that there’s a single, accurate, and clear “source of truth” for how our API will work. For Azure, that source of truth is the Azure REST API specs GitHub repository.

Furthermore, our API definitions are a key input to a large swath of our downstream tooling and code generation. For example, we use the OpenAPI document as the basis to generate client libraries, CLIs, and REST API documentation. Due to significant investment in tooling, and some customizations, Azure continues to use the OpenAPI v2 format in our API definition files.

Because the API definitions drive numerous downstream artifacts, one of our key goals is to provide a consistent experience across all Azure services. The challenges are the pace at which services evolve and the increasing number of services. We created the Azure REST API Guidelines, along with a companion set of documents to help our service teams reach these goals. Some of the areas of clarity and consistency we focus on are:

  • Documentation of error responses: The Azure convention is to use the “default” response to describe all error conditions. Using a single “default” error significantly reduces verbosity without much loss in information. We also recommend that teams use meaningful error text rather than simply repeating what you get from HTTP. For example, documenting a particular error status code is useful, such as 409 Conflict, to describe specific conditions that cause this response.
  • Specific formats/constraints for parameters and properties: A common problem is date fields that don’t specify format: date-time, and thus aren’t defined properly in client libraries. Another common problem is string parameters that don’t clearly document restrictions on length or characters allowed.
  • More rigor on “descriptions” everywhere in the API definition: Every operation, parameter, and schema property should have a clear description. We also want descriptions on response headers, security definitions, individual values of extensible enums, and elsewhere. We use linting tools to verify that descriptions are present in these places, and strive to ensure that they’re clear and complete. These descriptions feed directly into our generated developer docs, so it’s important we get them right.
  • Security definitions should be complete and accurate: In particular, the security scheme(s) should be accurately described. For example, which OAuth2 flows and scopes are required. Also, each operation should reference at least one security scheme.

Whether you use our APIs through one of our SDKs, or directly from your own tools, we’d love to learn more about how you’re using our APIs. Tell us what works, what’s frustrating, and share your ideas on how we can improve. Let’s start a conversation. Contact us at azureapi@microsoft.com.

Thanks,

-Mark & Mike

2 comments

Leave a comment

  • Aaron

    The Azure convention is to use the “default” response to describe all error conditions.
    Can you elaborate on that a bit how it relates to HTTP status codes? I read the section in the guidelines but I am still not sure if I got it.
    My current understanding would be to preferably use a single HTTP status codes to report errors and only divert from it if necessary.

    • Mike KistlerMicrosoft employee

      Thanks for your comment!

      In Azure we use “default” to cover all the standard 4XX and 5XX HTTP status codes. Typically there is little information value to specifying these individually, since it often mimics the standard error description. For example, a 401 means “Unauthorized” and since this is an HTTP standard there is no need to repeat this in our API definitions. In addition, the _absence_ of any of these status codes cannot be taken by the user to mean that such a code will not be returned, since middleware may inject these responses without the involvement of the service.

      Make sense?