Docs Italia beta

Documenti pubblici, digitali.

5.2. Raccomandazioni su progettazione e naming

In assenza di specifiche regole per l’API Naming (es. HL7, INSPIRE, ..) DOVREBBERO essere adottate le seguenti regole.

5.2.1. [RAC_REST_NAME_001] Uso corretto dei metodi HTTP

I metodi HTTP DEVONO essere utilizzati rispettando la semantica indicata in RFC 7231#section-4.3.

5.2.2. [RAC_REST_NAME_002] Usare parole separate da trattino «-» per i path (kebab-case)

Nella definizione dei path si DEVE utilizzare il separatore «-» (kebab-case).

Esempio: /​tax-code​/{tax_code_id}

Il path DOVREBBE essere semplice, intuitivo e coerente.

5.2.3. [RAC_REST_NAME_003] Preferire Hyphenated-Pascal-Case per gli header HTTP

DOVREBBE preferirsi Hyphenated-Pascal-Case per gli header HTTP.

Esempio:

Accept-Encoding
Apply-To-Redirect-Ref
Disposition-Notification-Options
Message-ID

5.2.4. [RAC_REST_NAME_004] Le collezioni di risorse possono usare nomi al plurale

Si consiglia di differenziare il nome delle collezioni e delle risorse. Questo permette di separare a livello di URI, endpoint che sono in larga parte funzionalmente differenti.

Esempio 1: ricerca di documenti per data in una collezione

Request:

GET /​documenti​?data=2018-05-01 HTTP/1.1
Host: api.example
Accept: application/json

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "items": [ ".." ],
  "limit": 10,
  "next_cursor": 21314123
}

Esempio 2: recupera un singolo documento

Request:

GET /​documento​/21314123 HTTP/1.1
Host: api.example
Accept: application/json

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 21314123,
  "title": "Atto di nascita ..."
}

5.2.5. [RAC_REST_NAME_005] Utilizzare Query String standardizzate

Esempio 1: La paginazione DEVE essere implementata tramite i parametri:

cursor, limit, offset, sort

Esempio 2: La ricerca, il filtering e l’embedding dei parametri DEVE essere implementata tramite i parametri:

q, fields, embed

5.2.7. [RAC_REST_NAME_007] Usare URI assoluti nei risultati

Le response DOVREBBERO restituire URI assoluti, al fine di indicare chiaramente al client l’indirizzo delle risorse di destinazione e non obbligare i client a fare «inferenza» dal contesto.

5.2.8. [RAC_REST_NAME_008] Usare lo schema Problem JSON per le risposte di errore

In caso di errori si DEVONO ritornare:

  • un payload di tipo Problem definito in RFC 7807
  • il media type application/problem+json
  • uno status code esplicativo
  • l’oggetto, possibilmente esteso

Quando si restituisce un errore è importante non esporre dati interni delle applicazioni. Per prevenire il rischio di user-enumeration, i messaggi di errore di autenticazione non devono fornire informazioni sull’esistenza o meno dell’utenza.

Dopo aver validato il contenuto delle richieste si DEVE ritornare:

5.2.9. [RAC_REST_NAME_009] Ottimizzare l’uso della banda e migliorare la responsività

Si DOVREBBERO utilizzare:

  • tecniche di compressione;
  • paginazione;
  • un filtro sugli attributi necessari;
  • le specifiche di optimistic locking (HTTP header ETag , if-(none-)match) RFC 7232.

È possibile ridurre l’uso della banda e velocizzare le richieste filtrando i campi delle risorse restituite.

Esempio 1: Non filtrato

Request:

GET /resources/123 HTTP/1.1
Host: api.example

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{

"id": "cddd5e44-dae0-11e5-8c01-63ed66ab2da5",
"name": "Mario Rossi",
"address": "via del Corso, Roma, Lazio, Italia",
"birthday": "1984-09-13",
"partner": {
        "id": "1fb43648-dae1-11e5-aa01-1fbc3abb1cd0",
        "name": "Maria Rossi",
        "address": "via del Corso, Roma, Lazio, Italia",
        "birthday": "1988-04-07"
        }
}

Esempio 2: Filtrato

Request:

GET /resources/123?fields=(name,partner(name)) HTTP/1.1
Host: api.example

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"name": "Mario Rossi",
"partner": {
        "name": "Maria Rossi"
        }
}

Si DOVREBBE effettuare la Resource Expansion per ritornare risorse correlate tra loro, in modo da ridurre il numero di richieste.

In tal caso va usato:

  • il​ parametro embed utilizzando lo stesso formato dei campi per il filtering;
  • l’attributo _embedded contenente le entry espanse.

Esempio 3: Resource Expansion, utile a ritornare i dati di una persona associati ad un codice fiscale.

Request:

GET /tax_code/MRORSS12T05E472W?embed=(person) HTTP/1.1
Accept: application/json

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "tax_code":"MRORSS12T05E472W",
  "_embedded": {
         "person":{
               "given_name":"Mario",
               "family_name":"Rossi",
               "id":"1234-ABCD-7890"
     }
  }
}

5.2.10. [RAC_REST_NAME_010] Il caching http deve essere disabilitato

Il caching DOVREBBE essere disabilitato tramite HTTP header Cache-Control per evitare che delle richieste vengano inopportunamente messe in cache. Il mancato rispetto di questa raccomandazione può portare all’esposizione accidentale di dati personali.

Le API che supportano il caching DEVONO documentare le varie limitazioni e modalità di utilizzo tramite gli header definiti in RFC 7234:

Eventuali conflitti nella creazione di risorse DEVONO essere gestiti tramite gli header:

che contengono un identificatore opaco che il server è in grado di associare univocamente alla versione della risorsa erogata. Si veda RFC 7232#section-2.3 per ulteriori informazioni su come implementare questi header.

5.2.11. [RAC_REST_NAME_011] Esporre lo stato del servizio

L’API DEVE esporre lo stato del servizio al path `/status` e ritornare un oggetto con media-type application/problem+json (RFC 7807). Se il servizio funziona correttamente, l’API ritorna HTTP status 200 OK.

Segue un esempio di specifica del path in formato OpenAPI 3.

ESEMPIO: Esposizione stato del servizio

   openapi: 3.0.2
   
   ...
   
   paths:
   
   ...
   
   /status:
   
   get:
   
   summary: Ritorna lo stato dell'applicazione.
   
   tags:
   
   - public
   
   description: \|
   
   Ritorna lo stato dell'applicazione in formato problem+json
   
   responses:
   
   '200':
   
   content:
   
   application/problem+json:
   
   schema:
   
   $ref: '#/components/schemas/Problem'
   
   description: \|
   
   Il servizio funziona correttamente.
   
   default:
   
   content:
   
   application/problem+json:
   
   schema:
   
   $ref: '#/components/schemas/Problem'
   
   description: \|
   
   Il server ha riscontrato un problema.