Docs Italia beta

Documenti pubblici, digitali.

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

  1. 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"
}
  1. 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

  1. 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"}
  1. Response
HTTP/1.1 200 OK
Content-Type: application/json

{"result": "ACK"}