Powerd911 – Numéro #1 au Canada

Domaine de valeurs

API design principles

An important principle for API design and usage is Postel’s Law, aka The Robustness Principle (see also RFC 1122): Be liberal in what you accept, be conservative in what you send

Compatibility

MUST not break backward compatibility

Change APIs, but keep all consumers running. Consumers usually have independent release lifecycles, focus on stability, and avoid changes that do not provide additional value. APIs are contracts between service providers and service consumers that cannot be broken via unilateral decisions.

There are two techniques to change APIs without breaking them:

  • follow rules for compatible extensions
  • introduce new API versions and still support older versions

We strongly encourage using compatible API extensions and discourage versioning (see SHOULD avoid versioning and MUST use media type versioning below). The following guidelines for service providers (SHOULD prefer compatible extensions) and consumers (MUST prepare clients accept compatible API extensions) enable us (having Postel’s Law in mind) to make compatible changes without versioning.

Note: There is a difference between incompatible and breaking changes. Incompatible changes are changes that are not covered by the compatibility rules below. Breaking changes are incompatible changes deployed into operation, and thereby breaking running API consumers. Usually, incompatible changes are breaking changes when deployed into operation. However, in specific controlled situations it is possible to deploy incompatible changes in a non-breaking way, if no API consumer is using the affected API aspects (see also Deprecation guidelines).

Hint: Please note that the compatibility guarantees are for the “on the wire” format. Binary or source compatibility of code generated from an API definition is not covered by these rules. If client implementations update their generation process to a new version of the API definition, it has to be expected that code changes are necessary.

SHOULD avoid versioning

When changing your RESTful APIs, do so in a compatible way and avoid generating additional API versions. Multiple versions can significantly complicate understanding, testing, maintaining, evolving, operating and releasing our systems (supplementary reading)

If changing an API can’t be done in a compatible way, then proceed in one of these three ways:

  • create a new resource (variant) in addition to the old resource variant
  • create a new service endpoint — i.e. a new application with a new API (with a new domain name)
  • create a new API version supported in parallel with the old API by the same microservice

As we discourage versioning by all means because of the manifold disadvantages, we strongly recommend to only use the first two approaches.

MUST use media type versioning

However, when API versioning is unavoidable, you have to design your multi-version RESTful APIs using media type versioning (see MUST not use URI versioning). Media type versioning is less tightly coupled since it supports content negotiation and hence reduces complexity of release management.

Version information and media type are provided together via the HTTP Content-Type header — e.g. application/x.zalando.cart+json;version=2. For incompatible changes, a new media type version for the resource is created. To generate the new representation version, consumer and producer can do content negotiation using the HTTP Content-Type and Accept headers.

Note
This versioning only applies to the request and response content schema, not to URI or method semantics.

MUST not use URI versioning

With URI versioning a (major) version number is included in the path, e.g. /v1/customers. The consumer has to wait until the provider has been released and deployed. If the consumer also supports hypermedia links — even in their APIs — to drive workflows (HATEOAS), this quickly becomes complex. So does coordinating version upgrades — especially with hyperlinked service dependencies — when using URL versioning. To avoid this tighter coupling and complexer release management we do not use URI versioning, and go instead with media type versioning and content negotiation (see above).

Custom media type format

Custom media type format should have the following pattern:

application/x.<custom-media-type>+json;version=<version>
  • custom-media-type is a custom type name, e.g. zalando.cart

  • version is a number, e.g. 2

Example

In this example, a client wants only the new version of the response:

Accept: application/x.zalando.cart+json;version=2

A server responding to this, as well as a client sending a request with content should use the Content-Type header, declaring that one is sending the new version:

Content-Type: application/x.zalando.cart+json;version=2

Using media type versioning should:

  • Use a custom media type, e.g. application/x.zalando.cart+json

  • Include versions in request and response headers to increase visibility

  • Include Content-Type in the Vary header to enable proxy caches to differ between versions

Vary: Content-Type
Tip
Until an incompatible change is necessary, it is recommended to stay with the standard application/json media type and do not use media type versioning.

Further reading: API Versioning Has No “Right Way” provides an overview on different versioning approaches to handle breaking changes without being opinionated.

Deprecation

Sometimes it is necessary to phase out an API endpoint, an API version, or an API feature, e.g. if a field or parameter is no longer supported or a whole business functionality behind an endpoint is supposed to be shut down. As long as the API endpoints and features are still used by consumers these shut downs are breaking changes and not allowed. To progress the following deprecation rules have to be applied to make sure that the necessary consumer changes and actions are well communicated and aligned using deprecation and sunset dates.

MUST obtain approval of clients before API shut down

Before shutting down an API, version of an API, or API feature the producer must make sure, that all clients have given their consent on a sunset date. Producers should help consumers to migrate to a potential new API or API feature by providing a migration manual and clearly state the time line for replacement availability and sunset (see also SHOULD add Deprecation and Sunset header to responses). Once all clients of a sunset API feature are migrated, the producer may shut down the deprecated API feature.

MUST collect external partner consent on deprecation time span

If the API is consumed by any external partner, the API owner must define a reasonable time span that the API will be maintained after the producer has announced deprecation. All external partners must state consent with this after-deprecation-life-span, i.e. the minimum time span between official deprecation and first possible sunset, before they are allowed to use the API.

MUST reflect deprecation in API specifications

The API deprecation must be part of the API specification.

If an API endpoint (operation object), an input argument (parameter object), an in/out data object (schema object), or on a more fine grained level, a schema attribute or property should be deprecated, the producers must set deprecated: true for the affected element and add further explanation to the description section of the API specification. If a future shut down is planned, the producer must provide a sunset date and document in details what consumers should use instead and how to migrate.

MUST monitor usage of deprecated API scheduled for sunset

Owners of an API, API version, or API feature used in production that is scheduled for sunset must monitor the usage of the sunset API, API version, or API feature in order to observe migration progress and avoid uncontrolled breaking effects on ongoing consumers. See also SHOULD monitor API usage.

SHOULD add Deprecation and Sunset header to responses

During the deprecation phase, the producer should add a Deprecation: <date-time> (see draft: RFC Deprecation HTTP Header) and – if also planned – a Sunset: <date-time> (see RFC 8594) header on each response affected by a deprecated element (see MUST reflect deprecation in API specifications).

The Deprecation header can either be set to true – if a feature is retired -, or carry a deprecation time stamp, at which a replacement will become/became available and consumers must not on-board any longer (see MUST not start using deprecated APIs). The optional Sunset time stamp carries the information when consumers latest have to stop using a feature. The sunset date should always offer an eligible time interval for switching to a replacement feature.

Deprecation: Tue, 31 Dec 2024 23:59:59 GMT
Sunset: Wed, 31 Dec 2025 23:59:59 GMT

If multiple elements are deprecated the Deprecation and Sunset headers are expected to be set to the earliest time stamp to reflect the shortest interval consumers are expected to get active.

Note: adding the Deprecation and Sunset header is not sufficient to gain client consent to shut down an API or feature.

Hint: In earlier guideline versions, we used the Warning header to provide the deprecation info to clients. However, Warning header has a less specific semantics, will be obsolete with draft: RFC HTTP Caching, and our syntax was not compliant with RFC 7234 — Warning header.

SHOULD add monitoring for Deprecation and Sunset header

Clients should monitor the Deprecation and Sunset headers in HTTP responses to get information about future sunset of APIs and API features (see SHOULD add Deprecation and Sunset header to responses). We recommend that client owners build alerts on this monitoring information to ensure alignment with service owners on required migration task.

Hint: In earlier guideline versions, we used the Warning header to provide the deprecation info (see hint in SHOULD add Deprecation and Sunset header to responses).

MUST not start using deprecated APIs

Clients must not start using deprecated APIs, API versions, or API features.

Compatibility

  • MUST prepare clients accept compatible API extensions
  • SHOULD used open-ended list of values (x-extensible-enum) for enumerations
  • SHOULD prefer compatible extensions

MUST use same semantics for null and absent properties

Open API 3.x allows to mark properties as required and as nullable to specify whether properties may be absent ({}) or null ({"example":null}). If a property is defined to be not required and nullable (see 2nd row in Table below), this rule demands that both cases must be handled in the exact same manner by specification.

The following table shows all combinations and whether the examples are valid:

required nullable {} {“example”:null}

true

true

No

Yes

false

true

Yes

Yes

true

false

No

No

false

false

Yes

No

While API designers and implementers may be tempted to assign different semantics to both cases, we explicitly decide against that option, because we think that any gain in expressiveness is far outweighed by the risk of clients not understanding and implementing the subtle differences incorrectly.

As an example, an API that provides the ability for different users to coordinate on a time schedule, e.g. a meeting, may have a resource for options in which every user has to make a choice. The difference between undecided and decided against any of the options could be modeled as absent and null respectively. It would be safer to express the null case with a dedicated Null object, e.g. {} compared to {"id":"42"}.

Moreover, many major libraries have somewhere between little to no support for a null/absent pattern (see Gson, Moshi, Jackson, JSON-B). Especially strongly-typed languages suffer from this since a new composite type is required to express the third state. Nullable Option/Optional/Maybe types could be used but having nullable references of these types completely contradicts their purpose.

The only exception to this rule is JSON Merge Patch RFC 7396) which uses null to explicitly indicate property deletion while absent properties are ignored, i.e. not modified.

JSON guidelines

  • SHOULD represent enumerations as strings
  • SHOULD declare enum values using one the following five conventions for capitalizing identifiers : Upper Snake case, Snake case, Pascal case, Camel case or Uppercase format about enum value naming conventions.
Enum values (using enum or x-extensible-enum) need to consistently use one of the cases formats above. This approach allows to clearly distinguish values from properties or other elements. The convention does not apply where the actual exact values are coming from some outside source, e.g. for language codes from ISO 639-1.
Snake case

The snake case is a typographical convention in computer science consisting of writing sets of words, usually in lowercase, separated by underscores. Here are several examples of writing variable names according to the original spelling:

  • “variable name” becomes variable_name
  • “TopCamelCaseVariableName” becomes name_of_variable_upper_camel_case
  • “Variable” becomes variable
  • “variable” becomes variable (no change)
Pascal case

The first letter in the identifier and the first letter of each subsequent concatenated word are capitalized. You can use Pascal case for identifiers of three or more characters. For example: PascalCase

Camel case

The camel case is a notation consisting of writing a set of words by linking them without spaces or punctuation, where the first letter of an identifier is lowercase and the first letter of each subsequent concatenated word is capitalized. For example: backColor. This term refers to the hollows and bumps of a camel’s back represented by the alternation of lowercase and capitals 

Uppercase

All letters in the identifier are capitalized. Use this convention only for identifiers that consist of two or fewer letters. For example: System.IO System.Web.UI

Reference
  1. https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-1.1/x2dbyw72(v=vs.71)?redirectedfrom=MSDN
  2. http://gdt.oqlf.gouv.qc.ca/ficheOqlf.aspx?Id_Fiche=26543803
  3. http://gdt.oqlf.gouv.qc.ca/ficheOqlf.aspx?Id_Fiche=26543805
  4. https://fr.wikipedia.org/wiki/Snake_case

SHOULD prefer compatible extensions

API designers should apply the following rules to evolve RESTful APIs for services in a backward-compatible way:

  • Enum ranges can be reduced when used as input parameters, only if the server is able to explain the reason (return an error) why the value is no longer allowed, eg dissolution of a country;
  • Enum ranges can be extended when used for input parameters;
  • Enum range can be reduced when used as output parameters;
  • Enum ranges cannot be extended when used for output parameters — clients may not be prepared to handle it. Enums must be able to accept values of type ‘UNKNOWN’;
  • Use x-extensible-enum, if range is used for output parameters and likely to be extended with growing functionality. It defines an open list of explicit values and clients must be agnostic to new values.

MUST prepare clients accept compatible API extensions

Service clients must be prepared for compatible API extensions of service providers:

  • Be prepared that x-extensible-enum return parameter may deliver new values; either be agnostic or provide default behavior for unknown values.

SHOULD used open-ended list of values (x-extensible-enum) for enumerations

  • Enumerations are per definition closed sets of values, that are assumed to be complete and not intended for extension. This closed principle of enumerations imposes compatibility issues when an enumeration must be extended. To avoid these issues, we strongly recommend to use an open-ended list of values instead of an enumeration unless:
    • the API has full control of the enumeration values, i.e. the list of values does not depend on any external tool or interface, and
    • the list of value is complete with respect to any thinkable and unthinkable future feature.
    • Examples : List of days, months, quarters, boolean (TRUE/FALSE)

To specify an open-ended list of values use the marker x-extensible-enum as follows:

delivery_methods:
type: string
x-extensible-enum:
– PARCEL
– LETTER
– EMAIL
default: EMAIL
description: Intended about delivery methods

Note: x-extensible-enum is not JSON Schema conform but will be ignored by most tools.

SHOULD represent enumerations as strings

Strings are a reasonable target for values that are by design enumerations.

MUST not use null for boolean properties

Schema based JSON properties that are by design booleans must not be presented as nulls. A boolean is essentially a closed enumeration of two values, true and false. If the content has a meaningful null value, strongly prefer to replace the boolean with enumeration of named values or statuses – for example accepted_terms_and_conditions with true or false can be replaced with terms_and_conditions with values yes, no and unknown.

MUST maintain backwards compatibility for events

Changes to events must be based around making additive and backward compatible changes. This follows the guideline, “Must: Don’t Break Backward Compatibility” from the Compatibility guidelines.

In the context of events, compatibility issues are complicated by the fact that producers and consumers of events are highly asynchronous and can’t use content-negotiation techniques that are available to REST style clients and servers. This places a higher bar on producers to maintain compatibility as they will not be in a position to serve versioned media types on demand.

For event schema, these are considered backward compatible changes, as seen by consumers –

  • Adding new optional fields to JSON objects.
  • Changing the order of fields (field order in objects is arbitrary).
  • Changing the order of values with same type in an array.
  • Removing optional fields.
  • Removing an individual value from an enumeration.

These are considered backwards-incompatible changes, as seen by consumers –

  • Removing required fields from JSON objects.
  • Changing the default value of a field.
  • Changing the type of a field, object, enum or array.
  • Changing the order of values with different type in an array (also known as a tuple).
  • Adding a new optional field to redefine the meaning of an existing field (also known as a co-occurrence constraint).
  • Adding a value to an enumeration (note that x-extensible-enum is not available in JSON Schema)

Enums

You can use the enum keyword to specify possible values of a request parameter or a model property. For example, the sort parameter in GET /items?sort=[asc|desc] can be described as:

paths:
    /items:
      get:
        parameters:
          - in: query
            name: sort
            description: Sort order
            schema:
              type: string
              enum: [asc, desc]

In YAML, you can also specify one enum value per line:

enum:
  - asc
  - desc

All values in an enum must adhere to the specified type. If you need to specify descriptions for enum items, you can do this in the description of the parameter or property:

parameters:
  - in: query
    name: sort
    schema:
      type: string
      enum: [asc, desc]
    description: >
      Sort order:
       * `asc` - Ascending, from A to Z
       * `desc` - Descending, from Z to A

Nullable enums

A nullable enum can be defined as follows:

type: string
nullable: true  # <---
enum:
  - asc
  - desc
  - null        # <--- without quotes, i.e. null not "null"

Note that null must be explicitly included in the list of enum values. Using nullable: true alone is not enough here.

Reusable enums

In OpenAPI 3.0, both operation parameters and data models use a schema, making it easy to reuse the data types. You can define reusable enums in the global components section and reference them via $ref elsewhere.

paths:
  /products:
    get:
      parameters:
      - in: query
        name: color
        required: true
        schema:
          $ref: '#/components/schemas/Color'
      responses:
        '200':
          description: OK
components:
  schemas:
    Color:
      type: string
      enum:
        - black
        - white
        - red
        - green
        - blue

Specification Extensions

While the OpenAPI Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points.

The extensions properties are implemented as patterned fields that are always prefixed by “x-“.

Field Pattern Type Description
^x- Any Allows extensions to the OpenAPI Schema. The field name MUST begin with x-, for example, x-internal-id. The value can be null, a primitive, an array or an object. Can have any valid JSON format value.

The extensions may or may not be supported by the available tooling, but those may be extended as well to add requested support (if tools are internal or open-sourced).

RESTful API guidelines

Organization

https://developers.google.com/s/results/assistant/conversational/overview?q=enum%20frozen

This enum is not yet frozen and values maybe added later.

https://tvh-equipment.gitlab.io/api-guidelines/index.html

TVH Equipment, fabricant de nacelles élévatrices de Belgique, fait partie du groupe mateco (avec plus de 60 sites en Europe et même plus de 80 partenaires dans le monde).  .

https://opensource.zalando.com/restful-api-guidelines/#

https://github.com/zalando/restful-api-guidelines

Zalando est une entreprise de commerce électronique allemande, spécialisée dans la vente de chaussures et de vêtements, basée à Berlin. Créée en 2008 par Rocket Internet, elle est présente dans 17 pays européens  https://cobra.netapp.com/guide/#Fondée en 1992, NetApp a profité de la croissance liée à Internet dans les années 1999-2001. Elle compte à présent plus de 10 000 employés dans le monde, et conçoit des solutions dans le domaine du stockage informatique en proposant des baies disque

https://schweizerischebundesbahnen.github.io/api-principles/

https://github.com/schweizerischebundesbahnen/api-principles

Les Chemins de fer fédéraux suisses (CFF);  en allemand Schweizerische Bundesbahnen (SBB) ; en italien Ferrovie Federali Svizzere (FFS) ; en romanche Viafiers federalas svizras (VFS) ou (VFF) sont la principale compagnie ferroviaire de Suisse.

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md

The OpenAPI Initiative (OAI) was created by a consortium of forward-looking industry experts who recognize the immense value of standardizing on how APIs are described. As an open governance structure under the Linux Foundation, the OAI is focused on creating, evolving and promoting a vendor neutral description format. The OpenAPI Specification was originally based on the Swagger Specification, donated by SmartBear Software.http://www.withouthaste.com/codeNotes/rest.php#header1

 
   
   
   
   
   
   
   
   

Laisser un commentaire