From aa621fd49f72456082a0edbedd6bcb3c814d0a87 Mon Sep 17 00:00:00 2001 From: Ludovic Robert <30499179+bigludo7@users.noreply.github.com> Date: Thu, 17 Oct 2024 21:03:39 +0200 Subject: [PATCH] Update API-design-guidelines.md Add part for: - https://github.com/camaraproject/Commonalities/issues/304 - https://github.com/camaraproject/Commonalities/issues/299 - partial https://github.com/camaraproject/Commonalities/issues/295 --- documentation/API-design-guidelines.md | 63 ++++++++++++++++++++------ 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/documentation/API-design-guidelines.md b/documentation/API-design-guidelines.md index 98156931..797d59f8 100644 --- a/documentation/API-design-guidelines.md +++ b/documentation/API-design-guidelines.md @@ -13,7 +13,7 @@ This document captures guidelines for the API design in CAMARA project. These gu - [2.2 API First](#22-api-first) - [2.3 Interface standardization. Standardization fora.](#23-interface-standardization-standardization-fora) - [2.4 Information Representation Standard](#24-information-representation-standard) - - [2.5 Reduce telco-specific terminology in API definitions](#25-reduce-telco-specific-terminology-in-api-definitions) + - [2.5 Reduce telco-specific terminology in API definitions](#25-reduce-telco-specific-terminology-in-api-definitions) - [3. API Definition](#3-api-definition) - [3.1 API REST](#31-api-rest) - [POST or GET for transferring sensitive or complex data](#post-or-get-for-transferring-sensitive-or-complex-data) @@ -66,16 +66,21 @@ This document captures guidelines for the API design in CAMARA project. These gu - [Examples](#examples) - [APIs which deal with explicit subscriptions](#apis-which-deal-with-explicit-subscriptions) - [API-level scopes (sometimes referred to as wildcard scopes in CAMARA)](#api-level-scopes-sometimes-referred-to-as-wildcard-scopes-in-camara) + - [11.7 API access restriction (Based on token \& client Id)](#117-api-access-restriction-based-on-token--client-id) - [12. Subscription, Notification \& Event](#12-subscription-notification--event) - [12.1 Subscription](#121-subscription) - [Instance-based (implicit) subscription](#instance-based-implicit-subscription) - [Instance-based (implicit) subscription example](#instance-based-implicit-subscription-example) - [Resource-based (explicit) subscription](#resource-based-explicit-subscription) + - [Operations](#operations) + - [Rules for subscriptions data minimization](#rules-for-subscriptions-data-minimization) + - [Subscriptions data model](#subscriptions-data-model) - [Error definition for resource-based (explicit) subscription](#error-definition-for-resource-based-explicit-subscription) - [Termination for resource-based (explicit) subscription](#termination-for-resource-based-explicit-subscription) - [Resource-based (explicit) example](#resource-based-explicit-example) - [12.2 Event notification](#122-event-notification) - [Event notification definition](#event-notification-definition) + - [subscription-ends event](#subscription-ends-event) - [Error definition for event notification](#error-definition-for-event-notification) - [Correlation Management](#correlation-management) - [Security Considerations](#security-considerations) @@ -551,23 +556,23 @@ API versions use a numbering scheme in the format: `x.y.z` ### 5.1 API version (OAS info object) -The API version is defined in the `version` field (in the `info` object) of the OAS definition file of an API.  +The API version is defined in the `version` field (in the `info` object) of the OAS definition file of an API. ```yaml info: title: Number Verification description: text describing the API - version: 2.2.0   + version: 2.2.0 #... ``` -In line with Semantic Versioning 2.0.0, the API with MAJOR.MINOR.PATCH version number, increments as follows: +In line with Semantic Versioning 2.0.0, the API with MAJOR.MINOR.PATCH version number, increments as follows: -1. The MAJOR version when an incompatible / breaking API change is introduced -2. The MINOR version when functionality is added that is backwards compatible -3. The PATCH version when backward compatible bugs are fixed +1. The MAJOR version when an incompatible / breaking API change is introduced +2. The MINOR version when functionality is added that is backwards compatible +3. The PATCH version when backward compatible bugs are fixed -For more details on MAJOR, MINOR and PATCH versions, and how to evolve API versions, please see [API versioning](https://wiki.camaraproject.org/x/a4BaAQ) in the CAMARA wiki.  +For more details on MAJOR, MINOR and PATCH versions, and how to evolve API versions, please see [API versioning](https://wiki.camaraproject.org/x/a4BaAQ) in the CAMARA wiki. It is recommended to avoid breaking backward compatibility unless strictly necessary: new versions should be backwards compatible with previous versions. More information on how to avoid breaking changes can be found below. @@ -579,7 +584,7 @@ The API version in the `url` field only includes the "x" (MAJOR version) number ```yaml servers: -    url: {apiRoot}/qod/v2 + url: {apiRoot}/qod/v2 ``` --- @@ -590,7 +595,7 @@ IMPORTANT: CAMARA public APIs with x=0 (`v0.x.y`) MUST use both the MAJOR and th ```yaml servers: -    url: {apiRoot}/number-verification/v0.3 + url: {apiRoot}/number-verification/v0.3 ``` This allows for both test and commercial usage of initial API versions as they are evolving rapidly, e.g. `/qod/v0.10alpha1`, `/qod/v0.10rc1`, or `/qod/v0.10`. However, it should be acknowledged that any initial API version may change. @@ -604,7 +609,7 @@ Overall, an API can have any of the following versions: * work-in-progress (`wip`) API versions used during the development of an API before the first pre-release or in between pre-releases. Such API versions cannot be released and are not usable by API consumers. * alpha (`x.y.z-alpha.m`) API versions (with extensions) for CAMARA internal API rapid development purposes * release-candidate (`x.y.z-rc.n`) API versions (with extensions) for CAMARA internal API release bug fixing purposes -* public (`x.y.z`) API versions for usage in commercial contexts. These API versions only have API version number x.y.z (semver 2.0), no extension. Public APIs can have one of two maturity states (used in release management):  +* public (`x.y.z`) API versions for usage in commercial contexts. These API versions only have API version number x.y.z (semver 2.0), no extension. Public APIs can have one of two maturity states (used in release management): * initial - indicating that the API is still not fully stable (x=0) * stable - indicate that the API has reached a certain level of maturity (x>0) @@ -614,7 +619,7 @@ The following table gives the values of the API version (Info object) and the AP |-------------------|:-------------:|:--------------------------------:|:-------------------------------:|:---------------------------:| | work-in-progress | wip | vwip | vwip | No | | alpha | x.y.z-alpha.m | v0.yalpham | vxalpham | Yes (internal pre-release) | -| release-candidate |  x.y.z-rc.n | v0.yrcn | vxrcn | Yes (internal pre-release) | +| release-candidate | x.y.z-rc.n | v0.yrcn | vxrcn | Yes (internal pre-release) | | public | x.y.z | v0.y | vx | Yes | Precedence examples: @@ -666,7 +671,7 @@ Compatibility management: To ensure this compatibility, the following guidelines must be applied. **As API provider**: -- Never change an endpoint name; instead, add a new one and mark the original one for deprecation in a MINOR change and remove it in a later MAJOR change (see semver FAQ entry: https://semver.org/#how-should-i-handle-deprecating-functionality) +- Never change an endpoint name; instead, add a new one and mark the original one for deprecation in a MINOR change and remove it in a later MAJOR change (see semver FAQ entry: https://semver.org/#how-should-i-handle-deprecating-functionality) - If possible, do the same for attributes - New fields should always be added as optional. - Postel's Law: “Be conservative in what you do, be liberal in what you accept from others”. When you have input fields that need to be removed, mark them as unused, so they can be ignored. @@ -1568,6 +1573,22 @@ The decision on the API-level scopes was made within the [Identity and Consent M The scopes will always be those defined in the API Specs YAML files. Thus, a scope would only provide access to all endpoints and resources of an API if it is explicitly defined in the API Spec YAML file and agreed in the corresponding API subproject. +### 11.7 API access restriction (Based on token & client Id) + +In some CAMARA API we have functions to create resource (via POST) and then later query them via id and/or list (with GET) or delete them (via DELETE). For example we have sessions, payments, subscriptions, etc.. + +For the GET and DELETE operations we must restrict the resource(s) targeted based on the request. Basically we consider 2 filters: +* API client (aka ClientId) +* access token + +| Operation | 3-legged access token is used | 2-legged access token is used | +|-----------|--------------------------------|-------------------------------| +| GET/{id} | -The resource queried must have been created for the end user associated with the access token.
- The resource queried must must have been created by the same API client given in the access token. | - The resource queried must must have been created by the same API client given in the access token. | +| GET/| -Return all resource(s) created by the API consumer that are associated with both the end user identified by the token and the same API client given in the access token.| Return all resource(s) created by the same API client given in the access token.| +| DELETE/{id} | -The resource to be deleted must have been created for the end user associated with the access token.
- The resource to be deleted must must have been created by the same API client given in the access token | - The resource to be deleted must must have been created by the same API client given in the access token. | + + + ## 12. Subscription, Notification & Event To provide event-based interaction, CAMARA API could provide capabilities for subscription & notification management. @@ -1645,6 +1666,7 @@ CAMARA subscription model leverages **[CloudEvents](https://cloudevents.io/)** a To ensure consistency across Camara subprojects, it is necessary that explicit subscriptions are handled within separate API/s. It is mandatory to append the keyword "subscriptions" at the end of the API name. For e.g. device-roaming-subscriptions.yaml +##### Operations Four operations must be defined: | operation | path | description | @@ -1672,13 +1694,22 @@ The rationale for using this alternate pattern should be explicitly provided (e.g. the notification source for each of the supported events may be completely different, in which case, separating the implementations is beneficial). +##### Rules for subscriptions data minimization + +These rules apply for subscription with device identifier +- If 3-legged access token is used, the POST and GET responses must not provide any device identifier. +- If 2-legged access token is used, the presence of a device identifier in the response is mandatory and should the same identifier type than the one provided in the request. + + + +##### Subscriptions data model The following table provides `/subscriptions` attributes | name | type | attribute description | cardinality | |----------------|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------| | protocol | string | Identifier of a delivery protocol. **Only** `HTTP` **is allowed for now**. | Mandatory | | sink | string | The address to which events shall be delivered, using the HTTP protocol. | mandatory | -| sinkCredential | object | Sink credential provides authorization information necessary to enable delivery of events to a target. In order to be updated in future this object is polymorphic. See detail below. To protect the notification endpoint providing sinkCredential is RECOMMENDED. | optional | +| sinkCredential | object | Sink credential provides authorization information necessary to enable delivery of events to a target. In order to be updated in future this object is polymorphic. See detail below. To protect the notification endpoint providing sinkCredential is RECOMMENDED.
The sinkCredential must **not** be present in `POST` and `GET` responses. | optional | | types | string | Type of event subscribed. This attribute **must** be present in the `POST` request. It is required by API project to provide an enum for this attribute. `type` must follow the format: `org.camaraproject...` with the `api-version` with letter `v` and the major version like ``org.camaraproject.device-roaming-subscriptions.v1.roaming-status`` - Note: An array of types could be passed **but as of now only one value MUST passed**. Use of multiple value will be open later at API level. | mandatory | | config | object | Implementation-specific configuration parameters needed by the subscription manager for acquiring events. In CAMARA we have predefined attributes like ``subscriptionExpireTime``, ``subscriptionMaxEvents`` or ``initialEvent``. See detail below. | mandatory | | id | string | Identifier of the event subscription - This attribute must not be present in the POST request as it is provided by API server | mandatory in server response | @@ -1715,6 +1746,10 @@ Remark: This action will trigger a subscription-ends event with terminationReaso | initialEvent | boolean | Set to true by API consumer if consumer wants to get an event as soon as the subscription is created and current situation reflects event request. Example: Consumer request Roaming event. If consumer sets initialEvent to true and device is in roaming situation, an event is triggered. Up to API project decision to keep it. | optional | +Note on combined usage of initialEvent and subscriptionMaxEvents: +Unless explicitly decided otherwise by the API WG, if an event is triggered following initialEvent set to `true`, this event will be counted towards subscriptionMaxEvents (if provided). +It is recommended to provide this clarification in all subscriptions API featuring subscriptionMaxEvents and initialEvent. + Subscription status value table: Managing subscription is a draft feature, and it is not mandatory for now. An API project could decide to use/not use it. A list of status is provided for global consistency.