6.1.1. [NONBLOCK_PUSH_REST] Not Blocking Push REST¶
Nel caso in cui il pattern venga implementato con tecnologia REST, DEVONO essere rispettate le seguenti indicazioni:
- Le specifiche delle interfacce del fruitore e dell’erogatore DEVONO dichiarare tutti i codici di stato HTTP previsti dall’interfaccia, con il relativo schema della risposta, oltre che ad eventuali header HTTP restituiti;
- Le specifiche delle interfacce del fruitore e dell’erogatore DEVONO dichiarare gli schemi delle richieste insieme ad eventuali header HTTP richiesti;
- La specifica dell’interfaccia dell’erogatore deve dichiarare tramite il formalismo specifico il formato delle callback; questa specifica deve essere rispettata dall’interfaccia esposta dal fruitore, e quindi nella rispettiva specifica;
- Al passo (1), il fruitore DEVE indicare l’endpoint della callback utilizzando l’header HTTP custom X-ReplyTo ed usando HTTP method POST ;
- Al passo (2), l’erogatore DEVE fornire insieme all’acknowledgement della richiesta nel body, il CorrelationID utilizzando l’header HTTP custom X-Correlation-ID; Il codice HTTP di stato DEVE essere HTTP status 202 Accepted a meno che non si verifichino errori;
- Al passo (3), l’erogatore DEVE utilizzare lo stesso CorrelationID fornito al passo (2) sempre utilizzando l’header HTTP custom X-Correlation-ID; Il verbo HTTP utilizzato deve essere POST;
- Al passo (4), il fruitore DEVE riconoscere tramite un messaggio di acknowledgement il ricevimento della risposta; Il codice HTTP di stato DEVE essere HTTP status 200 OK a meno che non si verifichino errori.
6.1.1.1. Regole di processamento¶
Al termine del processamento delle richieste, l’erogatore ed il fruitore DEVONO fare uso dei codici di stato HTTP rispettando la semantica. Fruitore ed erogatore:
- DEVONO verificare la validità sintattica dei dati in ingresso. In caso di dati errati DEVONO restituire HTTP status 500 Internal Server Error fornendo dettagli circa l’errore;
- In caso di dati errati DEVONO restituire HTTP status 400 Bad Request fornendo nel body di risposta dettagli circa l’errore;
- In caso di representation semanticamente non corretta DEVONO ritornare HTTP status 422 Unprocessable Entity;
- Se qualcuno degli ID nel path o nel body non esiste, DEVONO restituire HTTP status 404 Not Found, indicando nel body di risposta quale degli ID è mancante;
- Se si ipotizza che la richiesta sia malevola, PUÒ ritornare HTTP status 400 Bad Request o HTTP status 404 Not Found
- In caso di errori non dipendenti dalla richiesta, DEVONO restituire HTTP status 5XX rispettando la semantica degli stessi;
- Al momento della ricezione della richiesta, l’erogatore DEVE restituire HTTP status 202 Accepted. In caso di ricezione corretta della risposta, il fruitore DEVE restituire HTTP status 200 OK, ritornando nel body di risposta un acknowledgement dell’avvenuta ricezione. In caso di errore di ricezione della risposta da parte del fruitore, è possibile utilizzare meccanismi specifici per la ritrasmissione della risposta o della richiesta.
NB: I messaggi di errore devono essere utili al client ma NON DEVONO rivelare dettagli tecnici e/o informazioni riservate.
6.1.1.2. Esempio¶
Specifica Servizio Server
https://api.ente.example/rest/nome-api/v1/RESTCallbackServer.yaml
openapi: 3.0.1
info:
title: RESTCallbackServer
version: "1.0"
description: |-
Questo file descrive semplicemente i metodi di un'API
e non indica tutte le informazioni di metadatazione che
normalmente vanno inserite.
license:
name: Apache 2.0 License
url: http://www.apache.org/licenses/LICENSE-2.0.html
paths:
/resources/{id_resource}/M:
post:
description: M
operationId: PushMessage
parameters:
- name: X-ReplyTo
in: header
schema:
type: string
- name: id_resource
in: path
required: true
schema:
type: integer
format: int32
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MType'
responses:
202:
description: Preso carico correttamente di M
headers:
X-Correlation-ID:
required: true
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/ACKMessage'
400:
description: Richiesta non valida
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
404:
description: Identificativo non trovato
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
default:
$ref: '#/components/responses/default'
callbacks:
completionCallback:
'{$request.header#/X-ReplyTo}':
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MResponseType'
responses:
200:
description: Risposta correttamente ricevuta
content:
application/json:
schema:
$ref: '#/components/schemas/ACKMessage'
default:
$ref: '#/components/responses/default'
components:
responses:
default:
description: |-
Errore inatteso. Non ritornare informazioni
sulla logica interna e/o non pertinenti all'interfaccia.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
schemas:
MType:
type: object
properties:
a:
$ref: '#/components/schemas/AComplexType'
b:
type: string
ACKMessage:
type: object
properties:
outcome:
type: string
MResponseType:
type: object
properties:
c:
type: string
AComplexType:
type: object
properties:
a1s:
type: array
items:
type: integer
format: int32
a2:
type: string
ErrorMessage:
type: object
properties:
detail:
description: |
A human readable explanation specific to this occurrence of the
problem.
type: string
instance:
description: |
An absolute URI that identifies the specific occurrence of the problem.
It may or may not yield further information if dereferenced.
format: uri
type: string
status:
description: |
The HTTP status code generated by the origin server for this occurrence
of the problem.
exclusiveMaximum: true
format: int32
maximum: 600
minimum: 100
type: integer
title:
description: |
A short, summary of the problem type. Written in english and readable
for engineers (usually not suited for non technical stakeholders and
not localized); example: Service Unavailable
type: string
type:
default: about:blank
description: |
An absolute URI that identifies the problem type. When dereferenced,
it SHOULD provide human-readable documentation for the problem type
(e.g., using HTML).
format: uri
type: string
Specifica Servizio Client
https://api.client.example/rest/nome-api/v1/RESTCallbackClient.yaml
openapi: 3.0.1
info:
title: RESTCallbackClient
version: "1.0"
description: |-
Questo file descrive semplicemente i metodi di un'API
e non indica tutte le informazioni di metadatazione che
normalmente vanno inserite.
license:
name: Apache 2.0 License
url: http://www.apache.org/licenses/LICENSE-2.0.html
paths:
/MResponse:
post:
description: M
operationId: PushResponseMessage
parameters:
- name: X-Correlation-ID
in: header
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MResponseType'
responses:
200:
description: Risposta correttamente ricevuta
content:
application/json:
schema:
$ref: '#/components/schemas/ACKMessage'
400:
description: Richiesta non valida
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
404:
description: Identificativo non trovato
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
default:
description: |-
Errore inatteso. Non ritornare informazioni
sulla logica interna e/o non pertinenti all'interfaccia.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
components:
schemas:
ACKMessage:
type: object
properties:
outcome:
type: string
MResponseType:
type: object
properties:
c:
type: string
ErrorMessage:
type: object
properties:
detail:
description: |
A human readable explanation specific to this occurrence of the
problem.
type: string
instance:
description: |
An absolute URI that identifies the specific occurrence of the problem.
It may or may not yield further information if dereferenced.
format: uri
type: string
status:
description: |
The HTTP status code generated by the origin server for this occurrence
of the problem.
exclusiveMaximum: true
format: int32
maximum: 600
minimum: 100
type: integer
title:
description: |
A short, summary of the problem type. Written in english and readable
for engineers (usually not suited for non technical stakeholders and
not localized); example: Service Unavailable
type: string
type:
default: about:blank
description: |
An absolute URI that identifies the problem type. When dereferenced,
it SHOULD provide human-readable documentation for the problem type
(e.g., using HTML).
format: uri
type: string
Di seguito il fruitore effettua una richiesta al metodo M; l’erogatore conferma la presa in carico della richiesta ritornando HTTP status 202 Accepted.
Endpoint: https://api.ente.example/rest/nome-api/v1/resources/1234/M
- Request
POST /rest/nome-api/v1/resources/1234/M HTTP/1.1
Host: api.ente.example
Content-Type: application/json
X-ReplyTo: https://api.client.example/rest/v1/nomeinterfacciaclient/Mresponse
{
"a": {
"a1": [ 1, "..", 2 ],
"a2": "RGFuJ3MgVG9vbHMgYXJlIGNvb2wh"
},
"b": "Stringa di esempio"
}
- Response
HTTP/1.1 202 Accepted
Content-Type: application/json
X-Correlation-ID: 69a445fb-6a9f-44fe-b1c3-59c0f7fb568d
{"result": "ACK"}
Quindi l’erogatore notifica al fruitore l’avvenuto processamento delle informazioni tramite una HTTP method POST all’URL concordato. Il fruitore conferma con HTTP status 200 OK l’avvenuta ricezione della notifica.
Endpoint
https://api.client.example/rest/v1/nomeinterfacciaclient/Mresponse
- Request
POST /rest/v1/nomeinterfacciaclient/Mresponse HTTP/1.1
Host: api.client.example
Content-Type: application/json
X-Correlation-ID: 69a445fb-6a9f-44fe-b1c3-59c0f7fb568d
{"c": "OK"}
- Response
HTTP/1.1 200 OK
Content-Type: application/json
{"result": "ACK"}