From bb270c6dc3d1998b7eef7c81261f72c5597de26a Mon Sep 17 00:00:00 2001 From: Alexander Green Date: Fri, 22 Apr 2022 11:22:47 +0200 Subject: [PATCH 1/6] Rule 05, 54, 04, 48 Statement, Rationale, Runtime implications --- The Design Rules v1.0.md | 51 ++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/The Design Rules v1.0.md b/The Design Rules v1.0.md index b8b5981..2d8579d 100644 --- a/The Design Rules v1.0.md +++ b/The Design Rules v1.0.md @@ -5,8 +5,9 @@ The REST architectural style is centered around the concept of a [resource](#dfn-resource). A resource is the key abstraction of information, where every piece of information is named by assigning a globally unique [URI](#dfn-uri) (Uniform Resource Identifier). Resources describe *things*, which can vary between physical objects (e.g. a building or a person) and more abstract concepts (e.g. a permit or an event).
-

API-05: Use nouns to name resources

-

Because resources describe things (and thus not actions), resources are referred to using nouns (instead of verbs) that are relevant from the perspective of the user of the API.

+

API-05: Use nouns to name resources

+

Statement:

+

Resources are referred to using nouns (instead of verbs) that are relevant from the perspective of the user of the API.

A few correct examples of nouns as part of a URI:

    @@ -19,14 +20,23 @@ The REST architectural style is centered around the concept of a [resource](#dfn
  • Registreren
+

Rationale:

+

Resources describe objects not actions. +

+

Runtime implications:

+

None +

+
A resource describing a single thing is called a [singular resource](#dfn-singular-resource). Resources can also be grouped into collections, which are resources in their own right and can typically be paged, sorted and filtered. Most often all collection members have the same type, but this is not necessarily the case. A resource describing multiple things is called a [collection resource](#dfn-collection-resource). Collection resources typically contain references to the underlying singular resources.

API-54: Use plural nouns to name collection resources

-

Because a collection resource represents multiple things, the path segment describing the name of the collection resource must be written in the plural form.

-
+

Statement:

+

The path segment describing the name of the collection resource must be written in the plural form. +

+

Example collection resources, describing a list of things:

https://api.example.org/v1/gebouwen
https://api.example.org/v1/vergunningen
@@ -40,18 +50,45 @@ A resource describing a single thing is called a [singular resource](#dfn-singul

Example singular resource describing the profile of the currently authenticated user:

https://api.example.org/v1/gebruikersprofiel
+

Rationale:

+

A collection resource represents multiple things. +

+

Runtime implications:

+

None +

API-04: Define interfaces in Dutch unless there is an official English glossary available

-

Since the exact meaning of concepts is often lost in translation, resources and the underlying attributes should be defined in the Dutch language unless there is an official English glossary available. Publishing an API for an international audience might also be a reason to define interfaces in English.

+

Statement:

+

+Resources and the underlying attributes should be defined in the Dutch language unless there is an official English glossary available. Publishing an API for an international audience might also be a reason to define interfaces in English.

Note that glossaries exist that define useful sets of attributes which should preferably be reused. Examples can be found at schema.org.

+

+

Rationale:

+

+The exact meaning of concepts is often lost in translation. +

+

Runtime implications:

+

+None +

API-48: Leave off trailing slashes from URIs

-

According to the URI specification [[rfc3986]], URIs may contain a trailing slash. However, for REST APIs this is considered as a bad practice since a URI including or excluding a trailing slash might be interpreted as different resources (which is strictly speaking the correct interpretation).

-

To avoid confusion and ambiguity, a URI must never contain a trailing slash. When requesting a resource including a trailing slash, this must result in a 404 (not found) error response and not a redirect. This enforces API consumers to use the correct URI.

+

Statement:

+

+A URI must never contain a trailing slash. When requesting a resource including a trailing slash, this must result in a 404 (not found) error response and not a redirect. This enforces API consumers to use the correct URI. +

+

Rationale:

+

+According to the URI specification [[rfc3986]], URIs may contain a trailing slash. However, for REST APIs this is considered as a bad practice since this can lead to ambiguity in interpretation. +

+

Runtime implications:

+

+A URI including or excluding a trailing slash might be interpreted as different resources (which is strictly speaking the correct interpretation). +

URI without a trailing slash (correct):

https://api.example.org/v1/gebouwen
From ffe3e6d17a8214ce7c5e298ec8f598dc37c5df44 Mon Sep 17 00:00:00 2001 From: Alexander Green Date: Fri, 22 Apr 2022 17:04:20 +0200 Subject: [PATCH 2/6] Update The Design Rules v1.0.md --- The Design Rules v1.0.md | 206 ++++++++++++++++++++++----------------- 1 file changed, 116 insertions(+), 90 deletions(-) diff --git a/The Design Rules v1.0.md b/The Design Rules v1.0.md index 2d8579d..ecc5955 100644 --- a/The Design Rules v1.0.md +++ b/The Design Rules v1.0.md @@ -5,107 +5,133 @@ The REST architectural style is centered around the concept of a [resource](#dfn-resource). A resource is the key abstraction of information, where every piece of information is named by assigning a globally unique [URI](#dfn-uri) (Uniform Resource Identifier). Resources describe *things*, which can vary between physical objects (e.g. a building or a person) and more abstract concepts (e.g. a permit or an event).
-

API-05: Use nouns to name resources

-

Statement:

-

Resources are referred to using nouns (instead of verbs) that are relevant from the perspective of the user of the API.

-
-

A few correct examples of nouns as part of a URI:

-
    -
  • Gebouw
  • -
  • Vergunning
  • -
-

This is different than RPC-style APIs, where verbs are often used to perform certain actions:

-
    -
  • Opvragen
  • -
  • Registreren
  • -
-
-

Rationale:

-

Resources describe objects not actions. -

-

Runtime implications:

-

None -

- +

API-05: Use nouns to name resources

+
+
Statement
+
+ Resources are referred to using nouns (instead of verbs) that are relevant from the perspective of the user of the API. +
+ A few correct examples of nouns as part of a URI: +
    +
  • Gebouw
  • +
  • Vergunning
  • +
+

This is different than RPC-style APIs, where verbs are often used to perform certain actions:

+
    +
  • Opvragen
  • +
  • Registreren
  • +
+
+
+
Rationale
+
+ Resources describe objects not actions. +
+
Implications
+
+ Adherance to this rule needs to be manually verified. +
+
A resource describing a single thing is called a [singular resource](#dfn-singular-resource). Resources can also be grouped into collections, which are resources in their own right and can typically be paged, sorted and filtered. Most often all collection members have the same type, but this is not necessarily the case. A resource describing multiple things is called a [collection resource](#dfn-collection-resource). Collection resources typically contain references to the underlying singular resources.
-

API-54: Use plural nouns to name collection resources

-

Statement:

-

The path segment describing the name of the collection resource must be written in the plural form. -

-
-

Example collection resources, describing a list of things:

-
https://api.example.org/v1/gebouwen
https://api.example.org/v1/vergunningen
-
-

Singular resources contained within a collection resource are generally named by appending a path segment for the identification of each individual resource.

-
-

Example singular resource, contained within a collection resource:

-
https://api.example.org/v1/gebouwen/3b9710c4-6614-467a-ab82-36822cf48db1
https://api.example.org/v1/vergunningen/d285e05c-6b01-45c3-92d8-5e19a946b66f
-
-

Singular resources that stand on their own, i.e. which are not contained within a collection resource, must be named with a path segment that is written in the singular form.

-
-

Example singular resource describing the profile of the currently authenticated user:

-
https://api.example.org/v1/gebruikersprofiel
-
-

Rationale:

-

A collection resource represents multiple things. -

-

Runtime implications:

-

None -

+

API-54: Use plural nouns to name collection resources

+
+
Statement
+
+ The path segment describing the name of the collection resource must be written in the plural form. +
+

Example collection resources, describing a list of things:

+
https://api.example.org/v1/gebouwen
https://api.example.org/v1/vergunningen
+
+

Singular resources contained within a collection resource are generally named by appending a path segment for the identification of each individual resource.

+
+

Example singular resource, contained within a collection resource:

+
https://api.example.org/v1/gebouwen/3b9710c4-6614-467a-ab82-36822cf48db1
https://api.example.org/v1/vergunningen/d285e05c-6b01-45c3-92d8-5e19a946b66f
+
+

Singular resources that stand on their own, i.e. which are not contained within a collection resource, must be named with a path segment that is written in the singular form.

+
+

Example singular resource describing the profile of the currently authenticated user:

+
https://api.example.org/v1/gebruikersprofiel
+
+
+
Rationale
+
+ A collection resource represents multiple things. +
+
Implications
+
+ Adherance to this rule needs to be manually verified. +
+
-
-

API-04: Define interfaces in Dutch unless there is an official English glossary available

-

Statement:

-

-Resources and the underlying attributes should be defined in the Dutch language unless there is an official English glossary available. Publishing an API for an international audience might also be a reason to define interfaces in English.

-

Note that glossaries exist that define useful sets of attributes which should preferably be reused. Examples can be found at schema.org.

-

-

Rationale:

-

-The exact meaning of concepts is often lost in translation. -

-

Runtime implications:

-

-None -

+

API-04: Define interfaces in Dutch unless there is an official English glossary available

+
+
Statement
+
+ Resources and the underlying attributes should be defined in the Dutch language unless there is an official English glossary available. Publishing an API for an international audience might also be a reason to define interfaces in English.

+

Note that glossaries exist that define useful sets of attributes which should preferably be reused. Examples can be found at schema.org. +

+
Rationale
+
+ The exact meaning of concepts is often lost in translation. +
+
Implications
+
+ Adherance to this rule needs to be manually verified. +
+
-
-

API-48: Leave off trailing slashes from URIs

-

Statement:

-

-A URI must never contain a trailing slash. When requesting a resource including a trailing slash, this must result in a 404 (not found) error response and not a redirect. This enforces API consumers to use the correct URI. -

-

Rationale:

-

-According to the URI specification [[rfc3986]], URIs may contain a trailing slash. However, for REST APIs this is considered as a bad practice since this can lead to ambiguity in interpretation. -

-

Runtime implications:

-

-A URI including or excluding a trailing slash might be interpreted as different resources (which is strictly speaking the correct interpretation). -

-
-

URI without a trailing slash (correct):

-
https://api.example.org/v1/gebouwen
-

URI with a trailing slash (incorrect):

-
https://api.example.org/v1/gebouwen/
-
+

API-48: Leave off trailing slashes from URIs

+
+
Statement
+
+ A URI must never contain a trailing slash. When requesting a resource including a trailing slash, this must result in a 404 (not found) error response and not a redirect. This enforces API consumers to use the correct URI. +
+

URI without a trailing slash (correct):

+
https://api.example.org/v1/gebouwen
+

URI with a trailing slash (incorrect):

+
https://api.example.org/v1/gebouwen/
+
+
+
Rationale
+
+ To avoid confusion and ambiguity, a URI must never contain a trailing slash. When requesting a resource including a trailing slash, this must result in a `404` (not found) error response and not a redirect. This enforces API consumers to use the correct URI. +
+
Implications
+
+ This rule is included in the automatic tests on developer.overheid.nl. The source code can be found here. +
+
-
-

API-53: Hide irrelevant implementation details

-

An API should not expose implementation details of the underlying application. The primary motivation behind this design rule is that an API design must focus on usability for the client, regardless of the implementation details under the hood. The API, application and infrastructure need to be able to evolve independently to ease the task of maintaining backwards compatibility for APIs during an agile development process.

-

A few examples of implementation details:

-
    -
  • The API design should not necessarily be a 1-on-1 mapping of the underlying domain- or persistence model
  • -
  • The API should not expose information about the technical components being used, such as development platforms/frameworks or database systems
  • -
  • The API should offer client-friendly attribute names and values, while persisted data may contain abbreviated terms or serializations which might be cumbersome for consumption
  • -
+

API-53: Hide irrelevant implementation details

+
+
Statement
+
+ An API should not expose implementation details of the underlying application, development platforms/frameworks or database systems/persistence models. +
+
Rationale
+
+
    +
  • The primary motivation behind this design rule is that an API design must focus on usability for the client, regardless of the implementation details under the hood.
  • +
  • The API, application and infrastructure need to be able to evolve independently to ease the task of maintaining backwards compatibility for APIs during an agile development process.
  • +
  • The API design of Convenience,- and Process API types (as described in Aanbeveling 2 of the NL API Strategie) should not be a 1-on-1 mapping of the underlying domain- or persistence model.
  • +
  • The API design of a System API type (as described in Aanbeveling 2 of the NL API Strategie) may be a mapping of the underlying domain- or persistence model.
  • +
+
+
Implications
+
+
    +
  • The API should not expose information about the technical components being used, such as development platforms/frameworks or database systems.
  • +
  • The API should offer client-friendly attribute names and values, while persisted data may contain abbreviated terms or serializations which might be cumbersome for consumption.
  • +
+
+
## HTTP methods From 836787255d7c56d29fac1d6c015ab5d52db6ab39 Mon Sep 17 00:00:00 2001 From: Alexander Green Date: Tue, 26 Apr 2022 16:52:49 +0200 Subject: [PATCH 3/6] Update The Design Rules v1.0.md --- The Design Rules v1.0.md | 291 ++++++++++++++++++++++----------------- 1 file changed, 165 insertions(+), 126 deletions(-) diff --git a/The Design Rules v1.0.md b/The Design Rules v1.0.md index ecc5955..a0f5b73 100644 --- a/The Design Rules v1.0.md +++ b/The Design Rules v1.0.md @@ -104,7 +104,7 @@ A resource describing a single thing is called a [singular resource](#dfn-singul
Implications
- This rule is included in the automatic tests on developer.overheid.nl. The source code can be found here. + This rule is included in the automatic tests on developer.overheid.nl. The source code can be found here.
@@ -139,133 +139,159 @@ A resource describing a single thing is called a [singular resource](#dfn-singul Although the REST architectural style does not impose a specific protocol, REST APIs are typically implemented using HTTP [[rfc7231]].
-

API-03: Only apply standard HTTP methods

-

The HTTP specification [[rfc7231]] and the later introduced PATCH method specification [[rfc5789]] offer a set of standard methods, where every method is designed with explicit semantics. Adhering to the HTTP specification is crucial, since HTTP clients and middleware applications rely on standardized characteristics. Therefore, resources must be retrieved or manipulated using standard HTTP methods.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodOperationDescription
GETReadRetrieve a resource representation for the given URI. Data is only retrieved and never modified.
POSTCreateCreate a subresource as part of a collection resource. This operation is not relevant for singular resources. This method can also be used for exceptional cases.
PUTCreate/updateCreate a resource with the given URI or replace (full update) a resource when the resource already exists.
PATCHUpdatePartially updates an existing resource. The request only contains the resource modifications instead of the full resource representation.
DELETEDeleteRemove a resource with the given URI.
-

The following table shows some examples of the use of standard HTTP methods:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - +

API-03: Only apply standard HTTP methods

+
+
Statement
+
+ Resources must be retrieved or manipulated using standard HTTP methods. +
+
Rationale
+
+ The HTTP specification [[rfc7231]] and the later introduced PATCH method specification [[rfc5789]] offer a set of standard methods, where every method is designed with explicit semantics. Adhering to the HTTP specification is crucial, since HTTP clients and middleware applications rely on standardized characteristics. +
RequestDescription
GET /rijksmonumentenRetrieves a list of national monuments.
GET /rijksmonumenten/12Retrieves an individual national monument.
POST /rijksmonumentenCreates a new national monument.
PUT /rijksmonumenten/12Modifies national monument #12 completely.
PATCH /rijksmonumenten/12Modifies national monument #12 partially.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodOperationDescription
GETReadRetrieve a resource representation for the given URI. Data is only retrieved and never modified.
POSTCreateCreate a subresource as part of a collection resource. This operation is not relevant for singular resources. This method can also be used for exceptional cases.
PUTCreate/updateCreate a resource with the given URI or replace (full update) a resource when the resource already exists.
PATCHUpdatePartially updates an existing resource. The request only contains the resource modifications instead of the full resource representation.
DELETEDeleteRemove a resource with the given URI.
+ +
Implications
+
+ Adherance to this rule needs to be manually verified. +
+ +
The following table shows some examples of the use of standard HTTP methods: + + - - + + - -
DELETE /rijksmonumenten/12Deletes national monument #12. + RequestDescription
-

HTTP also defines other methods, e.g. HEAD, OPTIONS and TRACE. For the purpose of this design rule, these operations are left out of scope.

+ + + + GET /rijksmonumenten + Retrieves a list of national monuments. + + + GET /rijksmonumenten/12 + Retrieves an individual national monument. + + + POST /rijksmonumenten + Creates a new national monument. + + + PUT /rijksmonumenten/12 + Modifies national monument #12 completely. + + + PATCH /rijksmonumenten/12 + Modifies national monument #12 partially. + + + DELETE /rijksmonumenten/12 + Deletes national monument #12. + + + +
+

HTTP also defines other methods, e.g. HEAD, OPTIONS and TRACE. For the purpose of this design rule, these operations are left out of scope.

-

API-01: Adhere to HTTP safety and idempotency semantics for operations

-

The HTTP protocol [[rfc7231]] specifies whether an HTTP method should be considered safe and/or idempotent. These characteristics are important for clients and middleware applications, because they should be taken into account when implementing caching and fault tolerance strategies.

-

Request methods are considered safe if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. A request method is considered idempotent if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.

-

The following table describes which HTTP methods must behave as safe and/or idempotent:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodSafeIdempotent
GETYesYes
HEADYesYes
OPTIONSYesYes
POSTNoNo
PUTNoYes
PATCHNoNo
DELETENoYes
+

API-01: Adhere to HTTP safety and idempotency semantics for operations

+
+
Statement
+
+ The following table describes which HTTP methods must behave as safe and/or idempotent:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodSafeIdempotent
GETYesYes
HEADYesYes
OPTIONSYesYes
POSTNoNo
PUTNoYes
PATCHNoNo
DELETENoYes
+
+
Rationale
+
+ The HTTP protocol [[rfc7231]] specifies whether an HTTP method should be considered safe and/or idempotent. These characteristics are important for clients and middleware applications, because they should be taken into account when implementing caching and fault tolerance strategies. +
+
Implications
+
+ Request methods are considered safe if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. A request method is considered idempotent if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. +
+
## Statelessness @@ -285,9 +311,22 @@ Stateless communication offers many advantages, including: * *Reliability* is improved because it eases the task of recovering from partial failures since the server doesn't have to maintain, update or communicate session state. One failing request does not influence other requests (depending on the nature of the failure of course).
-

API-02: Do not maintain session state on the server

-

In the context of REST APIs, the server must not maintain or require any notion of the functionality of the client application and the corresponding end user interactions. To achieve full decoupling between client and server, and to benefit from the advantages mentioned above, no session state must reside on the server. Session state must therefore reside entirely on the client.

-

The client of a REST API could be a variety of applications such as a browser application, a mobile or desktop application and even another server serving as a backend component for another client. REST APIs should therefore be completely client-agnostic.

+

API-02: Do not maintain session state on the server

+
+
Statement
+
+ In the context of REST APIs, the server must not maintain or require any notion of the functionality of the client application and the corresponding end user interactions. +
+
Rationale
+
+ To achieve full decoupling between client and server, and to benefit from the advantages mentioned above, no session state must reside on the server. Session state must therefore reside entirely on the client. +
+
Implications
+
+ Adherance to this rule needs to be manually verified. +
+
+

The client of a REST API could be a variety of applications such as a browser application, a mobile or desktop application and even another server serving as a backend component for another client. REST APIs should therefore be completely client-agnostic.

## Relationships From ddd49c6b54e01575104f9de82534319444b272cf Mon Sep 17 00:00:00 2001 From: Martin van der Plas Date: Wed, 25 Jan 2023 17:30:10 +0100 Subject: [PATCH 4/6] Alle Rules bijgewerkt in nieuwe format --- Summary v1.0.md | 40 +- ... Rules v1.0.md => The Design Rules v1.1.md | 348 +++++++++++++++--- index.html | 2 +- js/config.js | 17 +- 4 files changed, 325 insertions(+), 82 deletions(-) rename The Design Rules v1.0.md => The Design Rules v1.1.md (60%) diff --git a/Summary v1.0.md b/Summary v1.0.md index d9d918c..0feb074 100644 --- a/Summary v1.0.md +++ b/Summary v1.0.md @@ -6,22 +6,24 @@ Design rules have unique and permanent numbers. In the event of design rules bei ### Normative Design Rules -* API-01: Adhere to HTTP safety and idempotency semantics for operations -* API-02: Do not maintain session state on the server -* API-03: Only apply standard HTTP methods -* API-04: Define interfaces in Dutch unless there is an official English glossary available -* API-05: Use nouns to name resources -* API-06: Use nested URIs for child resources -* API-10: Model resource operations as a sub-resource or dedicated resource -* API-16: Use OpenAPI Specification for documentation -* API-17: Publish documentation in Dutch unless there is existing documentation in English -* API-18: Include a deprecation schedule when publishing API changes -* API-19: Schedule a fixed transition period for a new major API version -* API-20: Include the major version number in the URI -* API-48: Leave off trailing slashes from URIs -* API-51: Publish OAS document at a standard location in JSON-format -* API-53: Hide irrelevant implementation details -* API-54: Use plural nouns to name collection resources -* API-55: Publish a changelog for API changes between versions -* API-56: Adhere to the Semantic Versioning model when releasing API changes -* API-57: Return the full version number in a response header +Design rules can be technical rules, which should be tested automatically and functional rules which should be considerd when designing and building the api. + +* API-01: Adhere to HTTP safety and idempotency semantics for operations - *Functional rule* +* API-02: Do not maintain session state on the server - *Functional rule* +* API-03: Only apply standard HTTP methods - *Technical rule* +* API-04: Define interfaces in Dutch unless there is an official English glossary available - *Functional rule* +* API-05: Use nouns to name resources - *Functional rule* +* API-06: Use nested URIs for child resources - *Functional rule* +* API-10: Model resource operations as a sub-resource or dedicated resource - *Functional rule* +* API-16: Use OpenAPI Specification for documentation - *Technical rule* +* API-17: Publish documentation in Dutch unless there is existing documentation in English - *Functional rule* +* API-18: Include a deprecation schedule when publishing API changes - *Functional rule* +* API-19: Schedule a fixed transition period for a new major API version - *Functional rule* +* API-20: Include the major version number in the URI - *Technical rule* +* API-48: Leave off trailing slashes from URIs - *Technical rule* +* API-51: Publish OAS document at a standard location in JSON-format - *Technical rule* +* API-53: Hide irrelevant implementation details - *Functional rule* +* API-54: Use plural nouns to name collection resources - *Functional rule* +* API-55: Publish a changelog for API changes between versions - *Functional rule* +* API-56: Adhere to the Semantic Versioning model when releasing API changes - *Technical rule* +* API-57: Return the full version number in a response header - *Technical rule* diff --git a/The Design Rules v1.0.md b/The Design Rules v1.1.md similarity index 60% rename from The Design Rules v1.0.md rename to The Design Rules v1.1.md index a0f5b73..55d9541 100644 --- a/The Design Rules v1.0.md +++ b/The Design Rules v1.1.md @@ -31,15 +31,24 @@ The REST architectural style is centered around the concept of a [resource](#dfn
Adherance to this rule needs to be manually verified.
- +
Rule types
+
+ This is a functional design rule and hence can't be tested automatically. +
+
+ A resource describing a single thing is called a [singular resource](#dfn-singular-resource). Resources can also be grouped into collections, which are resources in their own right and can typically be paged, sorted and filtered. Most often all collection members have the same type, but this is not necessarily the case. A resource describing multiple things is called a [collection resource](#dfn-collection-resource). Collection resources typically contain references to the underlying singular resources.

API-54: Use plural nouns to name collection resources

Statement
+
+ A collection resource represents multiple things. +
+
Rationale
The path segment describing the name of the collection resource must be written in the plural form.
@@ -57,14 +66,14 @@ A resource describing a single thing is called a [singular resource](#dfn-singul
https://api.example.org/v1/gebruikersprofiel
-
Rationale
-
- A collection resource represents multiple things. -
Implications
Adherance to this rule needs to be manually verified.
+
Rule types
+
+ This is a functional design rule and hence can't be tested automatically. +
@@ -72,17 +81,21 @@ A resource describing a single thing is called a [singular resource](#dfn-singul
Statement
- Resources and the underlying attributes should be defined in the Dutch language unless there is an official English glossary available. Publishing an API for an international audience might also be a reason to define interfaces in English.

-

Note that glossaries exist that define useful sets of attributes which should preferably be reused. Examples can be found at schema.org. + Resources and the underlying attributes should be defined in the Dutch language unless there is an official English glossary available.

Rationale
- The exact meaning of concepts is often lost in translation. + The exact meaning of concepts is often lost in translation. Publishing an API for an international audience might also be a reason to define interfaces in English. + Note that glossaries exist that define useful sets of attributes which should preferably be reused. Examples can be found at schema.org.
Implications
Adherance to this rule needs to be manually verified.
+
Rule types
+
+ This is a functional design rule and hence can't be tested automatically. +
@@ -91,6 +104,10 @@ A resource describing a single thing is called a [singular resource](#dfn-singul
Statement
A URI must never contain a trailing slash. When requesting a resource including a trailing slash, this must result in a 404 (not found) error response and not a redirect. This enforces API consumers to use the correct URI. +
+
Rationale
+
+ To avoid confusion and ambiguity, a URI must never contain a trailing slash. When requesting a resource including a trailing slash, this must result in a `404` (not found) error response and not a redirect. This enforces API consumers to use the correct URI.

URI without a trailing slash (correct):

https://api.example.org/v1/gebouwen
@@ -98,14 +115,14 @@ A resource describing a single thing is called a [singular resource](#dfn-singul
https://api.example.org/v1/gebouwen/
-
Rationale
-
- To avoid confusion and ambiguity, a URI must never contain a trailing slash. When requesting a resource including a trailing slash, this must result in a `404` (not found) error response and not a redirect. This enforces API consumers to use the correct URI. -
Implications
This rule is included in the automatic tests on developer.overheid.nl. The source code can be found here.
+
Rule types
+
+ This is a technical design rule and hence should be tested automatically. +
@@ -131,9 +148,14 @@ A resource describing a single thing is called a [singular resource](#dfn-singul
  • The API should offer client-friendly attribute names and values, while persisted data may contain abbreviated terms or serializations which might be cumbersome for consumption.
  • +
    Rule types
    +
    + This is a functional design rule and hence can't be tested automatically. +
    + ## HTTP methods Although the REST architectural style does not impose a specific protocol, REST APIs are typically implemented using HTTP [[rfc7231]]. @@ -187,7 +209,11 @@ Although the REST architectural style does not impose a specific protocol, REST
    Implications
    - Adherance to this rule needs to be manually verified. + This rule is included in the automatic tests on developer.overheid.nl. The source code can be found here. +
    +
    Rule types
    +
    + This is a technical design rule and hence should be tested automatically.
    The following table shows some examples of the use of standard HTTP methods: @@ -290,10 +316,15 @@ Although the REST architectural style does not impose a specific protocol, REST
    Implications
    Request methods are considered safe if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. A request method is considered idempotent if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. +
    +
    Rule types
    +
    + This is a functional design rule and hence can't be tested automatically.
    + ## Statelessness One of the key constraints of the REST architectural style is stateless communication between client and server. It means that every request from client to server must contain all of the information necessary to understand the request. The server cannot take advantage of any stored session context on the server as it didn’t memorize previous requests. Session state must therefore reside entirely on the client. @@ -325,18 +356,31 @@ Stateless communication offers many advantages, including:
    Adherance to this rule needs to be manually verified.
    +
    Rule types
    +
    + This is a functional design rule and hence can't be tested automatically. +

    The client of a REST API could be a variety of applications such as a browser application, a mobile or desktop application and even another server serving as a backend component for another client. REST APIs should therefore be completely client-agnostic.

    + ## Relationships Resources are often interconnected by relationships. Relationships can be modelled in different ways depending on the cardinality, semantics and more importantly, the use cases and access patterns the REST API needs to support.

    API-06: Use nested URIs for child resources

    -

    When having a child resource which can only exist in the context of a parent resource, the URI should be nested. In that case, the child resource does not necessarily have a top-level collection resource. The best way to explain this design rule is by example.

    -
    +
    +
    Statement
    +
    + When having a child resource which can only exist in the context of a parent resource, the URI should be nested. +
    +
    Rationale
    +
    + In this use case, the child resource does not necessarily have a top-level collection resource. The best way to explain this design rule is by example. +
    +

    When modelling resources for a news platform including the ability for users to write comments, it might be a good strategy to model the collection resources hierarchically:

    https://api.example.org/v1/articles/123/comments

    The platform might also offer a photo section, where the same commenting functionality is offered. In the same way as for articles, the corresponding sub-collection resource might be published at:

    @@ -349,6 +393,14 @@ Resources are often interconnected by relationships. Relationships can be modell
    https://api.example.org/v1/comments/123
    https://api.example.org/v1/comments/456

    Although this approach might seem counterintuitive from a technical perspective (we simply could have modelled a single /comments resource with optional filters for article and photo) and might introduce partially redundant functionality, it makes perfect sense from the perspective of the consumer, which increases developer experience.

    +
    Implications
    +
    + Adherance to this rule needs to be manually verified. +
    +
    Rule types
    +
    + This is a functional design rule and hence can't be tested automatically. +
    ## Operations @@ -356,13 +408,33 @@ Resources are often interconnected by relationships. Relationships can be modell

    API-10: Model resource operations as a sub-resource or dedicated resource

    -

    There are resource operations which might not seem to fit well in the CRUD interaction model. For example, approving of a submission or notifying a customer. Depending on the type of the operation, there are three possible approaches:

    -
      -
    1. Re-model the resource to incorporate extra fields supporting the particular operation. For example, an approval operation can be modelled in a boolean attribute goedgekeurd that can be modified by issuing a PATCH request against the resource. Drawback of this approach is that the resource does not contain any metadata about the operation (when and by whom was the approval given? Was the submission declined in an earlier stage?). Furthermore, this requires a fine-grained authorization model, since approval might require a specific role.
    2. -
    3. Treat the operation as a sub-resource. For example, model a sub-collection resource /inzendingen/12/beoordelingen and add an approval or declination by issuing a POST request. To be able to retrieve the review history (and to consistently adhere to the REST principles), also support the GET method for this resource. The /inzendingen/12 resource might still provide a goedgekeurd boolean attribute (same as approach 1) which gets automatically updated on the background after adding a review. This attribute should however be read-only.
    4. -
    5. In exceptional cases, the approaches above still don't offer an appropriate solution. An example of such an operation is a global search across multiple resources. In this case, the creation of a dedicated resource, possibly nested under an existing resource, is the most obvious solution. Use the imperative mood of a verb, maybe even prefix it with a underscore to distinguish these resources from regular resources. For example: /search or /_search. Depending on the operation characteristics, GET and/or POST method may be supported for such a resource.
    6. -
    -

    In this design rule, approach 2 and 3 are preferred.

    +
    +
    Statement
    +
    + Model resource operations as a sub-resource or dedicated resource. +
    +
    Rationale
    +
    + There are resource operations which might not seem to fit well in the CRUD interaction model. For example, approving of a submission or notifying a customer. Depending on the type of the operation, there are three possible approaches: +
      +
    1. Re-model the resource to incorporate extra fields supporting the particular operation. For example, an approval operation can be modelled in a boolean attribute goedgekeurd that can be modified by issuing a PATCH request against the resource. Drawback of this approach is that the resource does not contain any metadata about the operation (when and by whom was the approval given? Was the submission declined in an earlier stage?). Furthermore, this requires a fine-grained authorization model, since approval might require a specific role.
    2. +
    3. Treat the operation as a sub-resource. For example, model a sub-collection resource /inzendingen/12/beoordelingen and add an approval or declination by issuing a POST request. To be able to retrieve the review history (and to consistently adhere to the REST principles), also support the GET method for this resource. The /inzendingen/12 resource might still provide a goedgekeurd boolean attribute (same as approach 1) which gets automatically updated on the background after adding a review. This attribute should however be read-only.
    4. +
    5. In exceptional cases, the approaches above still don't offer an appropriate solution. An example of such an operation is a global search across multiple resources. In this case, the creation of a dedicated resource, possibly nested under an existing resource, is the most obvious solution. Use the imperative mood of a verb, maybe even prefix it with a underscore to distinguish these resources from regular resources. For example: /search or /_search. Depending on the operation characteristics, GET and/or POST method may be supported for such a resource.
    6. +
    +
    +
    Implications
    +
    + In this design rule, approach 2 and 3 are preferred. + Adherance to this rule needs to be manually verified. +
    +
    Rule types
    +
    + This is a functional design rule and hence can't be tested automatically. +
    +
    + +

    +

    ## Documentation @@ -371,67 +443,225 @@ An API is as good as the accompanying documentation. The documentation has to be

    API-16: Use OpenAPI Specification for documentation

    -

    The OpenAPI Specification (OAS) [[OPENAPIS]] defines a standard, language-agnostic interface to RESTful APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic.

    -

    API documentation must be provided in the form of an OpenAPI definition document which conforms to the OpenAPI Specification (from v3 onwards). As a result, a variety of tools can be used to render the documentation (e.g. Swagger UI or ReDoc) or automate tasks such as testing or code generation. The OAS document should provide clear descriptions and examples.

    +
    +
    Statement
    +
    + API documentation must be provided in the form of an OpenAPI definition document which conforms to the OpenAPI Specification (from v3 onwards). +
    +
    Rationale
    +
    + The OpenAPI Specification (OAS) [[OPENAPIS]] defines a standard, language-agnostic interface to RESTful APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. + API documentation must be provided in the form of an OpenAPI definition document which conforms to the OpenAPI Specification (from v3 onwards). As a result, a variety of tools can be used to render the documentation (e.g. Swagger UI or ReDoc) or automate tasks such as testing or code generation. The OAS document should provide clear descriptions and examples. +
    +
    Implications
    +
    + This rule is included in the automatic tests on developer.overheid.nl. The source code can be found here. +
    +
    Rule types
    +
    + This is a technical design rule and hence should be tested automatically. +
    +

    API-17: Publish documentation in Dutch unless there is existing documentation in English

    -

    In line with design rule API-04, the OAS document (e.g. descriptions and examples) should be written in Dutch. If relevant, you may refer to existing documentation written in English.

    +
    +
    Statement
    +
    + You should write the OAS document in Dutch. +
    +
    Rationale
    +
    + In line with design rule API-04, the OAS document (e.g. descriptions and examples) should be written in Dutch. If relevant, you may refer to existing documentation written in English. +
    +
    Implications
    +
    + Adherance to this rule needs to be manually verified. +
    +
    Rule types
    +
    + This is a functional design rule and hence can't be tested automatically. +
    +

    API-51: Publish OAS document at a standard location in JSON-format

    -

    To make the OAS document easy to find and to facilitate self-discovering clients, there should be one standard location where the OAS document is available for download. Clients (such as Swagger UI or ReDoc) must be able to retrieve the document without having to authenticate. Furthermore, the CORS policy for this URI must allow external domains to read the documentation from a browser environment.

    -

    The standard location for the OAS document is a URI called openapi.json or openapi.yaml within the base path of the API. This can be convenient, because OAS document updates can easily become part of the CI/CD process.

    -

    At least the JSON format must be supported. When having multiple (major) versions of an API, every API should provide its own OAS document(s).

    -
    -

    An API having base path https://api.example.org/v1/ must publish the OAS document at:

    -
    https://api.example.org/v1/openapi.json
    -

    Optionally, the same OAS document may be provided in YAML format:

    -
    https://api.example.org/v1/openapi.yaml
    -
    +
    +
    Statement
    +
    + To make the OAS document easy to find and to facilitate self-discovering clients, there should be one standard location where the OAS document is available for download. +
    +
    Rationale
    +
    +

    Clients (such as Swagger UI or ReDoc) must be able to retrieve the document without having to authenticate. Furthermore, the CORS policy for this URI must allow external domains to read the documentation from a browser environment.

    +

    The standard location for the OAS document is a URI called openapi.json or openapi.yaml within the base path of the API. This can be convenient, because OAS document updates can easily become part of the CI/CD process.

    +

    At least the JSON format must be supported. When having multiple (major) versions of an API, every API should provide its own OAS document(s).

    +
    +

    An API having base path https://api.example.org/v1/ must publish the OAS document at:

    +
    https://api.example.org/v1/openapi.json
    +

    Optionally, the same OAS document may be provided in YAML format:

    +
    https://api.example.org/v1/openapi.yaml
    +
    +
    +
    Implications
    +
    + This rule is included in the automatic tests on developer.overheid.nl. The source code can be found here. +
    +
    Rule types
    +
    + This is a technical design rule and hence should be tested automatically. +
    +
    ## Versioning Changes in APIs are inevitable. APIs should therefore always be versioned, facilitating the transition between changes. -
    -

    API-56: Adhere to the Semantic Versioning model when releasing API changes

    -

    Version numbering must follow the Semantic Versioning [[SemVer]] model to prevent breaking changes when releasing new API versions. Versions are formatted using the major.minor.patch template. When releasing a new version which contains backwards-incompatible changes, a new major version must be released. Minor and patch releases may only contain backwards compatible changes (e.g. the addition of an endpoint or an optional attribute).

    + +
    +

    API-18: Include a deprecation schedule when deprecating features or versions

    +
    +
    Statement
    +
    + Implement well documented and timely communicated deprecation schedules. +
    +
    Rationale
    +
    + Managing change is important. In general, well documented and timely communicated deprecation schedules are the most important for API users. When deprecating features or versions, a deprecation schedule must be published. This document should be published on a public web page. Furthermore, active clients should be informed by e-mail once the schedule has been updated or when versions have reached end-of-life. +
    +
    Implications
    +
    + Adherance to this rule needs to be manually verified. +
    +
    Rule types
    +
    + This is a functional design rule and hence can't be tested automatically. +
    +
    -
    -

    API-20: Include the major version number in the URI

    -

    The URI of an API (base path) must include the major version number, prefixed by the letter v. This allows the exploration of multiple versions of an API in the browser. The minor and patch version numbers are not part of the URI and may not have any impact on existing client implementations.

    -
    -

    An example of a base path for an API with current version 1.0.2:

    -
    https://api.example.org/v1/
    -
    +
    +

    API-19: Schedule a fixed transition period for a new major API version

    +
    +
    Statement
    +
    + Old versions must remain available for a limited and fixed deprecation period. +
    +
    Rationale
    +
    + When releasing a new major API version, the old version must remain available for a limited and fixed deprecation period. Offering a deprecation period allows clients to carefully plan and execute the migration from the old to the new API version, as long as they do this prior to the end of the deprecation period. A maximum of 2 major API versions may be published concurrently. +
    +
    Implications
    +
    + Adherance to this rule needs to be manually verified. +
    +
    Rule types
    +
    + This is a functional design rule and hence can't be tested automatically. +
    +
    -
    -

    API-57: Return the full version number in a response header

    -

    Since the URI only contains the major version, it's useful to provide the full version number in the response headers for every API call. This information could then be used for logging, debugging or auditing purposes. In cases where an intermediate networking component returns an error response (e.g. a reverse proxy enforcing access policies), the version number may be omitted.

    -

    The version number must be returned in an HTTP response header named API-Version (case-insensitive) and should not be prefixed.

    -
    -

    An example of an API version response header:

    -
    API-Version: 1.0.2
    -
    +
    +

    API-20: Include the major version number in the URI

    +
    +
    Statement
    +
    + The URI of an API must include the major version number. +
    +
    Rationale
    +
    + The URI of an API (base path) must include the major version number, prefixed by the letter v. This allows the exploration of multiple versions of an API in the browser. The minor and patch version numbers are not part of the URI and may not have any impact on existing client implementations. +
    +

    An example of a base path for an API with current version 1.0.2:

    +
    https://api.example.org/v1/
    +
    +
    +
    Implications
    +
    + This rule is included in the automatic tests on developer.overheid.nl. The source code can be found here. +
    +
    Rule types
    +
    + This is a technical design rule and hence should be tested automatically. +
    +

    API-55: Publish a changelog for API changes between versions

    -

    When releasing new (major, minor or patch) versions, all API changes must be documented properly in a publicly available changelog.

    +
    +
    Statement
    +
    + Publish a changelog. +
    +
    Rationale
    +
    +

    When releasing new (major, minor or patch) versions, all API changes must be documented properly in a publicly available changelog.

    +
    +
    Implications
    +
    + Adherance to this rule needs to be manually verified. +
    +
    Rule types
    +
    + This is a functional design rule and hence can't be tested automatically. +
    +
    +
    -
    -

    API-18: Include a deprecation schedule when deprecating features or versions

    -

    Managing change is important. In general, well documented and timely communicated deprecation schedules are the most important for API users. When deprecating features or versions, a deprecation schedule must be published. This document should be published on a public web page. Furthermore, active clients should be informed by e-mail once the schedule has been updated or when versions have reached end-of-life.

    +
    +

    API-56: Adhere to the Semantic Versioning model when releasing API changes

    +
    +
    Statement
    +
    + Implement Semantic Versioning. +
    +
    Rationale
    +
    + Version numbering must follow the Semantic Versioning [[SemVer]] model to prevent breaking changes when releasing new API versions. Versions are formatted using the major.minor.patch template. When releasing a new version which contains backwards-incompatible changes, a new major version must be released. Minor and patch releases may only contain backwards compatible changes (e.g. the addition of an endpoint or an optional attribute). +
    +
    Implications
    +
    + This rule is included in the automatic tests on developer.overheid.nl. The source code can be found here. +
    +
    Rule types
    +
    + This is a technical design rule and hence should be tested automatically. +
    +
    -
    -

    API-19: Schedule a fixed transition period for a new major API version

    -

    When releasing a new major API version, the old version must remain available for a limited and fixed deprecation period. Offering a deprecation period allows clients to carefully plan and execute the migration from the old to the new API version, as long as they do this prior to the end of the deprecation period. A maximum of 2 major API versions may be published concurrently.

    +
    +

    API-57: Return the full version number in a response header

    +
    +
    Statement
    +
    + Return the API-Version header. +
    +
    Rationale
    +
    +

    Since the URI only contains the major version, it's useful to provide the full version number in the response headers for every API call. This information could then be used for logging, debugging or auditing purposes. In cases where an intermediate networking component returns an error response (e.g. a reverse proxy enforcing access policies), the version number may be omitted.

    +

    The version number must be returned in an HTTP response header named API-Version (case-insensitive) and should not be prefixed.

    +
    +

    An example of an API version response header:

    +
    API-Version: 1.0.2
    +
    +
    +
    Implications
    +
    + This rule is included in the automatic tests on developer.overheid.nl. The source code can be found here. +
    +
    Rule types
    +
    + This is a technical design rule and hence should be tested automatically. +
    +
    + + + diff --git a/index.html b/index.html index 5009f7b..10c5201 100644 --- a/index.html +++ b/index.html @@ -40,7 +40,7 @@
    -
    +
    diff --git a/js/config.js b/js/config.js index cc75ba4..786722c 100644 --- a/js/config.js +++ b/js/config.js @@ -9,16 +9,17 @@ //------------------------------------------------------------------------------------- //-- Log . . . : 20180615 - FT - Initiele versie //-- . . . . . : 20181106 - JvG - verplaatst naar root KP-APIs +//-- . . . . . : 20220125 - MvdP - Nieuwe versie / opzet in lijn met de modulaire opbouw //------------------------------------------------------------------------------------- var respecConfig = { - specStatus: "DEF", + specStatus: "WV", specType: "ST", pubDomain: "api", shortName: "adr", - publishDate: "2020-07-09", - publishVersion: "1.0", + publishDate: "2022-01-25", + publishVersion: "1.1", // previousPublishVersion: "(none)", // postProcess: [repair], @@ -35,6 +36,16 @@ var respecConfig = name: "Jan van Gelder", company: "Geonovum", companyURL: "https://www.geonovum.nl", + }, + { + name: "Alexnder Green", + company: "Logius", + companyURL: "https://www.logius.nl", + }, + { + name: "Martin van der Plas", + company: "Logius", + companyURL: "https://www.logius.nl", } ], authors: From 5cb9128a3e4f8ed27920ce148bedab1a24ca9423 Mon Sep 17 00:00:00 2001 From: Martin van der Plas Date: Wed, 25 Jan 2023 17:34:46 +0100 Subject: [PATCH 5/6] typo --- js/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/config.js b/js/config.js index 786722c..b3d7dee 100644 --- a/js/config.js +++ b/js/config.js @@ -38,7 +38,7 @@ var respecConfig = companyURL: "https://www.geonovum.nl", }, { - name: "Alexnder Green", + name: "Alexander Green", company: "Logius", companyURL: "https://www.logius.nl", }, From bb3a446081bb634ee95a4140d05c2063cf057ad5 Mon Sep 17 00:00:00 2001 From: Alexander Green Date: Tue, 31 Jan 2023 21:56:38 +0100 Subject: [PATCH 6/6] Removed version numbers from file names --- Abstract v1.0.md => Abstract.md | 0 The Design Rules v1.1.md => DesignRules.md | 0 Glossary v1.0.md => Glossary.md | 0 Introduction v1.0.md => Introduction.md | 0 Summary v1.0.md => Summary.md | 0 index.html | 10 +++++----- 6 files changed, 5 insertions(+), 5 deletions(-) rename Abstract v1.0.md => Abstract.md (100%) rename The Design Rules v1.1.md => DesignRules.md (100%) rename Glossary v1.0.md => Glossary.md (100%) rename Introduction v1.0.md => Introduction.md (100%) rename Summary v1.0.md => Summary.md (100%) diff --git a/Abstract v1.0.md b/Abstract.md similarity index 100% rename from Abstract v1.0.md rename to Abstract.md diff --git a/The Design Rules v1.1.md b/DesignRules.md similarity index 100% rename from The Design Rules v1.1.md rename to DesignRules.md diff --git a/Glossary v1.0.md b/Glossary.md similarity index 100% rename from Glossary v1.0.md rename to Glossary.md diff --git a/Introduction v1.0.md b/Introduction.md similarity index 100% rename from Introduction v1.0.md rename to Introduction.md diff --git a/Summary v1.0.md b/Summary.md similarity index 100% rename from Summary v1.0.md rename to Summary.md diff --git a/index.html b/index.html index 10c5201..8f05049 100644 --- a/index.html +++ b/index.html @@ -33,15 +33,15 @@ -
    +
    -
    -
    -
    -
    +
    +
    +
    +
    \ No newline at end of file