Cos'è Swagger?

Swagger è un insieme di specifiche e di strumenti che mirano a semplificare e standardizzare i processi di documentazione di API per servizi web RESTful. Il cuore di Swagger consiste in un file testuale (in formato sia YAML che JSON) dove sono descritte tutte le funzionalità di un'applicazione web e i dettagli di input e output in un formato studiato per essere interpretabile correttamente sia dagli umani che dalle macchine.

I vantaggi di questa standardizzazione sono molti, come una migliore e più condivisibile esplorazione delle funzionalità di un'applicazione, oltre che alla possibilità di generare codice client/server sfruttando direttamente i vincoli definiti nello schema.

Infatti, i metadati presenti nel file forniscono informazioni sufficienti sia per generare il componente backend con le rotte http e la validazione degli input, sia la parte client che in modo automatico può adattarsi all’evoluzione delle API del backend.

La generazione della parte server è sicuramente vantaggiosa in quanto è possibile concentrarsi direttamente alla programmazione della business logic.

 

Definizione di una API

Per creare una API esistono sostanzialmente due approcci, top down e bottom-up.

 

TOP-DOWN:

In questo caso si procede con la creazione del file YAML dettagliando le funzionalità che l'applicazione dovrà avere. Per questo è possibile utilizzare l'editor Swagger che semplifica il processo di editing mostrando un'anteprima della documentazione risultante, riducendo la possibilità di commettere errori grazie ad una validazione real time e a suggerimenti sui parametri consentiti.

 

BOTTOM UP:

Nel caso si voglia documentare un'applicazione REST esistente, esistono tool di autogenerazione del file YAML a partire da annotations inserite nel codice sorgente (qui un esempio di autogenerazione nel caso si utilizzi lo standard Java REST JAX-RS ). Se non si riuscisse ad ottenere sufficiente libertà tramite l'utilizzo di annotations è possibile utilizzare l'approccio tramite l'editor.

 

L'editor fornisce alcuni esempi, dai più semplici ai più dettagliati, da cui è possibile prendere spunto per scrivere la documentazione necessaria. 

 

Analizzando il file che presenta una struttura lineare, oltre ai molti attributi di cui è immediato intuire il funzionamento, è possibile notare l’utilizzo della keyword $ref per riutilizzare i modelli definiti nella sezione definitions.

Ogni parametro di input ha invece un attributo in che specifica dove dovrà essere settato, se tra gli headers, nel body o come parametro query nell URL.

 

swagger: '2.0'
info:
  version: '1.0.0'
  title: Swagger Petstore (Simple)
  description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification
  termsOfService: http://helloreverb.com/terms/
  contact:
    name: Swagger API team
    email: foo@example.com
    url: http://swagger.io
  license:
    name: MIT
    url: http://opensource.org/licenses/MIT
host: petstore.swagger.io
basePath: /api
schemes:
  - http
consumes:
  - application/json
produces:
  - application/json
paths:
  /pets:
    get:
      description: Returns all pets from the system that the user has access to
      operationId: findPets
      produces:
        - application/json
        - application/xml
        - text/xml
        - text/html
      parameters:
        - name: tags
          in: query
          description: tags to filter by
          required: false
          type: array
          items:
            type: string
          collectionFormat: csv
        - name: limit
          in: query
          description: maximum number of results to return
          required: false
          type: integer
          format: int32
      responses:
        '200':
          description: pet response
          schema:
            type: array
            items:
              $ref: '#/definitions/pet'
        default:
          description: unexpected error
          schema:
            $ref: '#/definitions/errorModel'
    post:
      description: Creates a new pet in the store.  Duplicates are allowed
      operationId: addPet
      produces:
        - application/json
      parameters:
        - name: pet
          in: body
          description: Pet to add to the store
          required: true
          schema:
            $ref: '#/definitions/newPet'
      responses:
        '200':
          description: pet response
          schema:
            $ref: '#/definitions/successModelPetSingle'
        default:
          description: unexpected error
          schema:
            $ref: '#/definitions/errorModel'
  /pets/{id}:
    get:
      description: Returns a user based on a single ID, if the user does not have access to the pet
      operationId: findPetById
      produces:
        - application/json
        - application/xml
        - text/xml
        - text/html
      parameters:
        - name: id
          in: path
          description: ID of pet to fetch
          required: true
          type: integer
          format: int64
      responses:
        '200':
          description: pet response
          schema:
            $ref: '#/definitions/pet'
        default:
          description: unexpected error
          schema:
            $ref: '#/definitions/errorModel'
    delete:
      description: deletes a single pet based on the ID supplied
      operationId: deletePet
      parameters:
        - name: id
          in: path
          description: ID of pet to delete
          required: true
          type: integer
          format: int64
      responses:
        '204':
          description: pet deleted
        default:
          description: unexpected error
          schema:
            $ref: '#/definitions/errorModel'
definitions:
  pet:
    type: object
    required:
      - id
      - name
    properties:
      id:
        type: integer
        format: int64
      name:
        type: string
      tag:
        type: string
  newPet:
    type: object
    required:
      - name
    properties:
      id:
        type: integer
        format: int64
      name:
        type: string
      tag:
        type: string
  errorModel:
    type: object
    required:
      - code
      - message
    properties:
      code:
        type: integer
        format: int32
      message:
        type: string
  successModelPetSingle:
    properties:
      success:
        type: boolean
      code:
        type: integer
      data:
        $ref: '#/definitions/pet'

 

 

Visualizzare l'API con Swagger UI

Per poter visualizzare e navigare da browser le nostre API si utilizzerà la web application Swagger UI, che andrà opportunamente configurata per puntare al file dell’applicazione che fornisce i servizi.

 

E’ necessario quindi rendere raggiungibile il file (yaml/json), scegliendo se lasciarlo tra i contenuti statici o fare in modo che venga servito da una rotta ad hoc.

 

N.B.

Potrebbe essere necessario abilitare le chiamate CORS sulla web application che ospita il file swagger, nel caso Swagger UI non fosse sullo stesso server.

Una volta effettuato il download di Swagger UI è possibile eseguire l’applicazione dal file:

 

{$SWAGGER_UI_HOME}/dist/index.html

 

Di default punterà ad un url di esempio ma che può essere modificato a seconda delle esigenze. Inoltre è previsto un parametro url per puntare dinamicamente ad un file di documentazione:

 

{$SWAGGER_UI_HOME}/dist/index.html?url=http://mywebapp.com/swagger-file.yaml

 

Nello screenshot di esempio Swagger UI sta puntando al file swagger.yaml (va bene anche il JSON) presente sul server che ospita il fornitore di servizi.

 

Oltre a ad esplorare la documentazione, Swagger UI consente anche di interagire con le API dato che integra un client http per eseguire le varie chiamate REST. Basta infatti espandere una delle funzionalità, cliccare sul pulsante “Try it now” ed esaminare la risposta da parte del server. Per questo, risulta molto comodo e intuitivo l'editor per configurare i payload da inviare.

 

 

Conclusioni

Visto il successo nella community di sviluppatori ma anche tra i vendor, Swagger è ormai considerato lo standard de facto per la descrizione di API REST, infatti dal 1 gennaio 2016 Swagger é diventato parte integrante della Open API Initiative (OAI), una iniziativa della Linux Foundation che promuove e sostiene l’importanza di avere un linguaggio comune per le applicazioni web per favorire la sua diffusione in modo radicale, in un mondo sempre più connesso e dominato dalla diffusione dei big data.