OpenAPI è uno standard per la de­scri­zio­ne delle in­ter­fac­ce di pro­gram­ma­zio­ne, ovvero le Ap­pli­ca­tion Pro­gram­ming In­ter­fa­ces (API). La specifica OpenAPI definisce un formato di de­scri­zio­ne aperto e non soggetto a licenza per i servizi API. In par­ti­co­la­re, tramite OpenAPI si possono de­scri­ve­re, svi­lup­pa­re, testare e do­cu­men­ta­re le API REST.

La specifica OpenAPI attuale deriva dal pre­ce­den­te progetto Swagger. La società di sviluppo SmartBear ha posto la specifica Swagger esistente sotto licenza aperta e ne ha affidato la ma­nu­ten­zio­ne e l’ulteriore sviluppo alla OpenAPI Ini­tia­ti­ve. Accanto a SmartBear, fanno parte della OpenAPI Ini­tia­ti­ve alcuni colossi del settore come Google, IBM e Microsoft; il progetto è sup­por­ta­to anche dalla Linux Foun­da­tion.

API IONOS per svi­lup­pa­to­ri
Gestisci i tuoi prodotti di hosting tramite la nostra potente API
  • Gestione record DNS
  • Am­mi­ni­stra­zio­ne SSL
  • Do­cu­men­ta­zio­ne API

OpenAPI in sintesi

Un punto che può creare con­fu­sio­ne è la di­stin­zio­ne tra OpenAPI e Swagger. OpenAPI è una specifica, cioè una de­scri­zio­ne astratta che non è legata a un’im­ple­men­ta­zio­ne tecnica par­ti­co­la­re. Fino alla versione 2.0, questa specifica era chiamata Swagger ed è stata ri­no­mi­na­ta in seguito specifica OpenAPI. Tuttavia, i tool forniti dalla società di sviluppo originale, SmartBear, con­ti­nua­no a esistere con il nome di Swagger.

OpenAPI permette di de­scri­ve­re una API in modo uniforme. Si parla a tal proposito di “de­fi­ni­zio­ne API”, che viene generata in un formato leggibile dalle macchine. In par­ti­co­la­re si uti­liz­za­no i due linguaggi YAML e JSON.

N.B.
Accanto alla de­fi­ni­zio­ne API, si può talvolta sentir parlare di “specifica API”. Si tratta in questo caso di una de­scri­zio­ne astratta di API, creata esclu­si­va­men­te per il lettore umano.

Tec­ni­ca­men­te, YAML e JSON dif­fe­ri­sco­no solo mar­gi­nal­men­te, per cui è possibile con­ver­ti­re au­to­ma­ti­ca­men­te una de­fi­ni­zio­ne API esistente da un lin­guag­gio all’altro. YAML, però, ha una struttura più chiara ed è più fa­cil­men­te leggibile per l’occhio umano. Di seguito un esempio dello stesso server object OpenAPI, scritto in YAML e JSON:

# YAML
servers:
- url: https://development.example.com/v1
    description: Development server
- url: https://staging.example.com/v1
    description: Staging server
- url: https://api.example.com/v1
    description: Production server
// JSON
{
    "servers": [
        {
            "url": "https://development.example.com/v1",
            "description": "Development server"
        },
        {
            "url": "https://staging.example.com/v1",
            "description": "Staging server"
        },
        {
            "url": "https://api.example.com/v1",
            "description": "Production server"
        }
    ]
}

La specifica OpenAPI definisce una serie di proprietà che possono essere uti­liz­za­te per costruire la propria API. Queste proprietà sono rag­grup­pa­te come co­sid­det­ti oggetti (in inglese “objects”). Nell’attuale versione 3.0.3, OpenAPI definisce, tra l’altro, la struttura per i seguenti oggetti:

  • Info Object: versione, nome, ecc. dell’API.
  • Contact Object: in­for­ma­zio­ni di contatto del fornitore API.
  • License Object: licenza con la quale l’API fornisce i suoi dati.
  • Server Object: nomi degli host, struttura degli URL e porte dei server con cui viene in­di­riz­za­ta l’API.
  • Com­po­nen­ts Object: com­po­nen­ti in­cap­su­la­ti che possono essere uti­liz­za­ti più volte all’interno di una de­fi­ni­zio­ne API.
  • Paths Object: percorsi relativi agli endpoint delle API che vengono uti­liz­za­ti insieme al Server Object.
  • Path Item Object: ope­ra­zio­ni, come GET, PUT, POST, DELETE, con­sen­ti­te per un de­ter­mi­na­to percorso.
  • Operation Object: specifica, ad esempio, i parametri e le risposte del server previste per un’ope­ra­zio­ne.

Quali sono i campi di ap­pli­ca­zio­ne di OpenAPI?

In generale, OpenAPI è uti­liz­za­to per de­scri­ve­re le API REST in modo uniforme. Poiché questa de­scri­zio­ne, cioè la de­fi­ni­zio­ne API, è in un formato leggibile dalle macchine, è possibile generare au­to­ma­ti­ca­men­te diversi artefatti virtuali, come ad esempio:

  • creazione di do­cu­men­ta­zio­ne API: la do­cu­men­ta­zio­ne basata su HTML viene generata au­to­ma­ti­ca­men­te dalla de­fi­ni­zio­ne API leggibile dalle macchine. Questa serve come testo di ri­fe­ri­men­to per gli svi­lup­pa­to­ri che accedono ai servizi API. Se la de­fi­ni­zio­ne API cambia, la do­cu­men­ta­zio­ne viene ri­ge­ne­ra­ta in modo che entrambe rimangano coerenti.
  • creazione di col­le­ga­men­ti in diversi linguaggi di pro­gram­ma­zio­ne: uti­liz­zan­do gli strumenti ap­pro­pria­ti, è possibile generare a partire dalla de­fi­ni­zio­ne API una libreria lato client in un lin­guag­gio di pro­gram­ma­zio­ne sup­por­ta­to. Ciò consente ai pro­gram­ma­to­ri di diversi linguaggi di accedere alle API. La libreria viene integrata in maniera classica; gli accessi ai servizi API avvengono quindi, ad esempio, tramite chiamate di funzione all’interno dell’ambiente di pro­gram­ma­zio­ne abituale.
  • creazione di casi di prova: ogni com­po­nen­te di un software deve essere sot­to­po­sto a test per garantire la propria fun­zio­na­li­tà. In par­ti­co­la­re, un com­po­nen­te software deve essere testato a ogni modifica del codice sot­to­stan­te. Dalla de­fi­ni­zio­ne API, questi test possono essere generati au­to­ma­ti­ca­men­te, in modo che la fun­zio­na­li­tà dei com­po­nen­ti software possa essere mo­ni­to­ra­ta inin­ter­rot­ta­men­te.

Per com­ple­tez­za, va ricordato che non tutte le API possono essere mappate con OpenAPI. Tuttavia, le API REST sono espli­ci­ta­men­te sup­por­ta­te.

Quali sono i vantaggi di OpenAPI?

In generale, il vantaggio di OpenAPI è quello di mantenere una coerenza tra l’im­ple­men­ta­zio­ne, la do­cu­men­ta­zio­ne e i test di una API durante lo sviluppo e la ma­nu­ten­zio­ne. Inoltre, l’uso della specifica OpenAPI permette un migliore coor­di­na­men­to dello sviluppo delle API tra back end e front end. Da entrambi i lati, i com­po­nen­ti del codice possono essere generati dalla de­fi­ni­zio­ne delle API, per­met­ten­do ai team di back end e front end di svi­lup­pa­re e testare senza doversi aspettare re­ci­pro­ca­men­te.

Oltre a questi vantaggi generali, OpenAPI è par­ti­co­lar­men­te uti­liz­za­to come base stan­dar­diz­za­ta per lo sviluppo di API REST. Questo è in­te­res­san­te perché non è banale svi­lup­pa­re un’API REST ma­nual­men­te. Tuttavia, le API REST hanno alcuni vantaggi; ad esempio, REST funziona su HTTP/S e le porte sono aperte in qualsiasi firewall.

Inoltre, l’utilizzo di OpenAPI presenta i seguenti vantaggi:

  • de­fi­ni­zio­ne delle API HTTP in­di­pen­den­te­men­te da un lin­guag­gio di pro­gram­ma­zio­ne specifico
  • ge­ne­ra­zio­ne del codice server per una API definita in OpenAPI
  • ge­ne­ra­zio­ne di librerie lato client per un’API conforme a OpenAPI in più di 40 linguaggi di pro­gram­ma­zio­ne
  • ela­bo­ra­zio­ne di una de­fi­ni­zio­ne OpenAPI con strumenti ap­pro­pria­ti
  • creazione di do­cu­men­ta­zio­ne API in­te­rat­ti­va
  • pos­si­bi­li­tà di per­met­te­re a uomini e macchine di scoprire e com­pren­de­re le capacità di un servizio senza dover guardare il codice sorgente o la do­cu­men­ta­zio­ne ag­giun­ti­va
  • pos­si­bi­li­tà di accedere ai servizi API con il minimo sforzo di im­ple­men­ta­zio­ne

Quali sono le versioni di OpenAPI e in cosa dif­fe­ri­sco­no?

Al momento della scrittura del presente articolo, la versione attuale è OpenAPI 3.0.3. Di seguito una breve pa­no­ra­mi­ca delle versioni pre­ce­den­ti:

Versione Nome Stato
1.0, agosto 2011 Specifica Swagger Non più in uso
2.0, settembre 2014 Specifica Swagger > Specifica OpenAPI Ancora sup­por­ta­ta
3.0, luglio 2017 Specifica OpenAPI Ancora sup­por­ta­ta

Di seguito vi mostriamo le novità più im­por­tan­ti quando si passa dalla versione 2.0 alla versione 3.0:

Nuovo nome dell’oggetto root

Con il rilascio della versione 3.0 è stato in­tro­dot­to l’oggetto OpenAPI, che so­sti­tui­sce l’oggetto Swagger pre­ce­den­te­men­te uti­liz­za­to:

# <= 2.0
"swagger": "2.0"
# >= 3.0
"OpenAPI": "3.0.0"

Più host/server

A partire dalla versione 3.0 di OpenAPI, una API può essere in­di­riz­za­ta da più di un server. Inoltre, è possibile definire in modo variabile parti dell’URL del server. Un esempio qui di seguito:

"servers": [
        {
            "url": "https://{username}.example.com:{port}/{basePath}",
            "description": "The production API server",
            "variables": {
                "username": {
                    "default": "demo",
                    "description": "this value is assigned by the service provider, in this example `example.com`"
                },
                "port": {
                    "enum": [
                        "8443"
                        "443"
                    ],
                    "default": "8443"
                },
                "basePath": {
                    "default": "v2"
                }
            }
        }
    ]

Nuovi com­po­nen­ti e oggetti di ri­fe­ri­men­to

I com­po­nen­ti e gli oggetti di ri­fe­ri­men­to aggiunti nella versione 3.0 di OpenAPI sono una delle prin­ci­pa­li novità. L’oggetto com­po­nen­te consente di definire più oggetti riu­ti­liz­za­bi­li all’interno della de­fi­ni­zio­ne delle API. Questi co­sid­det­ti com­po­nen­ti sono inclusi nella de­fi­ni­zio­ne API uti­liz­zan­do la speciale istru­zio­ne $ref.

Uti­liz­zan­do i com­po­nen­ti e i ri­fe­ri­men­ti, è possibile costruire una de­fi­ni­zio­ne API a partire da diverse parti riu­ti­liz­za­bi­li. Questo rende più facile la lettura e riduce le di­men­sio­ni dell’intero documento. Di seguito è riportato un esempio dalla de­fi­ni­zio­ne ufficiale API di GitHub:

  1. schema di un re­po­si­to­ry di codice GitHub, definito come oggetto com­po­nen­te;
  2. de­fi­ni­zio­ne della licenza, con ri­fe­ri­men­to a un com­po­nen­te definito ester­na­men­te.
"components": {
    "schemas": {
        // Schema del repository
        "repository": {
            "title": "Repository",
            "description": "A git repository",
            "type": "object",
            "properties": {
                "id": {
                    "description": "Unique identifier of the repository",
                    "example": 42,
                    "type": "integer"
                },
                "node_id": {
                    "type": "string",
                    "example": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5"
                },
                "name": {
                    "description": "The name of the repository.",
                    "type": "string",
                    "example": "Team Environment"
                },
                "full_name": {
                    "type": "string",
                    "example": "octocat/Hello-World"
                },
                // Definizione della licenza
                "license": {
                    "nullable": true,
                    "allOf": [
                        {
                            // Riferimento a un componente definito esternamente
                            "$ref": "#/components/schemas/license-simple"
                        }
                    ]
                },

OpenAPI in pratica: due esempi

La specifica OpenAPI e i relativi tool, in par­ti­co­la­re Swagger, sono uti­liz­za­ti su vasta scala per la creazione di varie API. Vi pre­sen­tia­mo qui due esempi:

GitHub v3 REST API

Il popolare servizio Git GitHub utilizza OpenAPI per de­scri­ve­re la sua “GitHub v3 REST API”. La de­fi­ni­zio­ne API è di­spo­ni­bi­le su GitHub come re­po­si­to­ry. Con il suo aiuto, un utente può vi­sua­liz­za­re esat­ta­men­te a quali servizi può accedere tramite l’API di GitHub e come devono essere strut­tu­ra­te esat­ta­men­te i richiami in questione. Inoltre, chiunque può uti­liz­za­re l’API per generare il relativo codice uti­liz­zan­do gli strumenti ap­pro­pria­ti.

Secondo GitHub, la de­fi­ni­zio­ne API viene uti­liz­za­ta per de­scri­ve­re, creare, eseguire e vi­sua­liz­za­re l’API REST. Al momento della scrittura del presente articolo, la de­fi­ni­zio­ne API non è completa. Mancano, ad esempio, alcuni campi di in­te­sta­zio­ne che verranno aggiunti in futuro. Va inoltre notato che è possibile eseguire alcune delle possibili ope­ra­zio­ni API tramite percorsi diversi, sebbene nelle spe­ci­fi­che possa essere elencato un solo percorso.

Per motivi di com­pa­ti­bi­li­tà, GitHub fornisce la de­fi­ni­zio­ne delle API in diversi formati. Da un lato, c’è una versione de­no­mi­na­ta “bundled”, che contiene i com­po­nen­ti in­tro­dot­ti con OpenAPI 3.0 e i relativi ri­fe­ri­men­ti. Dall’altro, viene offerta una versione chiamata de­re­fe­ren­zia­ta (“de­fe­ren­ced”), in cui i ri­fe­ri­men­ti sono tutti risolti. A causa della ri­don­dan­za che si verifica, la de­fi­ni­zio­ne API de­re­fe­ren­zia­ta è circa tre volte più grande di quella “bundled”. Molti strumenti non sup­por­ta­no ancora i ri­fe­ri­men­ti; per questi casi, la de­fi­ni­zio­ne di API de­re­fe­ren­zia­ta è la scelta opportuna.

Potete dare un’occhiata voi stessi alla de­fi­ni­zio­ne API. Si noterà che il file completo ha una di­men­sio­ne di diversi megabyte. Per un file di testo, si tratta di una quantità in­cre­di­bil­men­te grande di in­for­ma­zio­ni. GitHub non può vi­sua­liz­za­re di­ret­ta­men­te un file così grande. Tuttavia, è possibile uti­liz­za­re il seguente link per vi­sua­liz­za­re l’API REST di GitHub nel browser. Questa è la versione YAML, molto più compatta e leggibile: GitHub REST API (YAML).

Esempio di API petstore di Swag­ge­rHub

Come secondo esempio, vi il­lu­stria­mo un caso di API che può essere generato su Swag­ge­rHub. Swag­ge­rHub è una piat­ta­for­ma online per la pro­get­ta­zio­ne e lo sviluppo di API REST con OpenAPI. Qui potete re­gi­strar­vi e creare un account utente gratuito, ma anche accedere con un account di GitHub (se ne avete già uno).

Una volta ef­fet­tua­to il login in Swag­ge­rHub, è possibile creare una nuova API. C’è un’opzione per crearne una a partire da un modello esistente. Ad esempio, esiste un template API per un “petstore” virtuale, quindi per un negozio di animali. L’API del petstore creata con il template include una vasta gamma di oggetti OpenAPI. Questi includono:

  • In­for­ma­zio­ni di contatto, con­di­zio­ni di utilizzo, licenza, ecc.
  • Gli endpoint API e le ope­ra­zio­ni di ogni endpoint
  • I parametri di ingresso e di uscita con­sen­ti­ti delle ope­ra­zio­ni
  • Spe­ci­fi­che di sicurezza

Os­ser­van­do l’API del petstore, si può imparare molto su come funziona OpenAPI. Inoltre, la de­fi­ni­zio­ne di petstore è un buon esempio per com­pren­de­re come costruire un’API REST. Infine, facciamo un esempio di codice partendo dall’API del petstore. Ana­liz­zia­mo la seguente sezione del codice:

  1. Il codice definisce l’endpoint API '/pet'.
  2. Con una richiesta HTTP POST viene aggiunto un nuovo animale domestico al negozio di animali.
  3. Se invece uti­liz­za­te il verbo HTTP PUT sullo stesso endpoint, potete mo­di­fi­ca­re un animale già presente nel negozio.
  4. Per le ope­ra­zio­ni sono definite diverse risposte del server. In questo esempio, i codici di stato HTTP includono il noto codice di stato 404 “Not Found”. Questo è sti­liz­za­to in questo caso come “Pet not found” nell’esempio dell’API del petstore.
N.B.
Le righe di codice che iniziano con '$ref' e com­men­ta­te con “OpenAPI 3.0+ Component” sono ri­fe­ri­men­ti a com­po­nen­ti OpenAPI definiti sin­go­lar­men­te.
# Petstore API Template #
# API Endpoint '/pet'
/pet:
    # HTTP-POST Request
    post:
        tags:
            - pet
        summary: Add a new pet to the store
        operationId: addPet
        # HTTP-Status codes
        responses:
            '405':
                description: Invalid input
        security:
            # Permissions
            - petstore_auth:
                - 'write:pets'
                - 'read:pets'
        requestBody:
            # OpenAPI 3.0+ Component
            $ref: '#/components/requestBodies/Pet'
    # HTTP-PUT Request
    put:
        tags:
            - pet
        summary: Update an existing pet
        operationId: updatePet
        # HTTP-Status codes
        responses:
            '400':
                description: Invalid ID supplied
            '404':
                description: Pet not found
            '405':
             description: Validation exception
        security:
            # Permissions
            - petstore_auth:
                - 'write:pets'
                - 'read:pets'
        requestBody:
            # OpenAPI 3.0+ Component
            $ref: '#/components/requestBodies/Pet'
In sintesi
OpenAPI si è affermato come formato di de­scri­zio­ne aperto e non soggetto a licenza per i servizi API. Si prevede che sarà am­pia­men­te uti­liz­za­to come standard per la co­stru­zio­ne di API REST nel prossimo futuro.
Vai al menu prin­ci­pa­le