Skip to content

Instantly share code, notes, and snippets.

@marcodebe
Last active October 24, 2017 20:47
Show Gist options
  • Save marcodebe/d6cf62a8c2892b9bd41ef3c94ac3db78 to your computer and use it in GitHub Desktop.
Save marcodebe/d6cf62a8c2892b9bd41ef3c94ac3db78 to your computer and use it in GitHub Desktop.
Microservizi

Microservizi

Si tratta di buzzword, comunque indica un'architettura in cui i singoli servizi sono accoppiati in modo lasco, oguno può essere sviluppato con tecnologie diverse e da vendor diversi. Garantiscono maggiore flessibilità rispetto ad un'implementazione concentrata su un server monolitico.

Tipicamente sono realizzati su HTTP, se non altro per il fatto che è ubiquo.

Servizi monolitici vs microservizi

In un'architettura non SOA, un server implementa diversi servizi tutti al suo interno, vincolandoli strettamente l'uno all'altro.

Applicazioni SOA tradizionali implementano un orchestratore tra i vari servizi che a quindi possono essere sostituiti singolarmente a patto che mantengano l'interfaccia (cioè a parità di input e output).

I microservizi invece sono interamente slegati fra di loro: si possono quindi realizzare applicazioni che lato client sfruttano direttamente i singoli servizi (ad esempio one-page app via AJAX).

HTTP

È un protocollo applicativo request-response, tipicamente su TCP, per lo scambio di risorse.

La versione più recente è la 2, ma ancora molti server usano la versione 1.1.

Entrambe le versioni gestiscono più connessioni HTTP all'interno di una TCP, la versione 2 supporta anche connessioni HTTP parallele all'interno di una TCP.

Il termine della connessione viene indicato dall'header "Connection: close header".

URL: Uniform Resource Locator

scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]

scheme può essere: http, https, file, ...

Richieste HTTP

Una richiesta HTTP è formata da:

  1. una riga che indica l'azione, la risorsa sulla quale eseguirla e il protocollo separati da spazio
  2. un insieme di righe di header Chiave: valore
  3. un eventuale body (ad esempio in caso di POST)
  4. una riga vuota che indica la fine della richiesta

Una richiesta HTTP è formata da:

  1. una riga con protocollo, status code e relativa descrizione separati da spazio
  2. un insieme di righe di header Chiave: valore
  3. un body (può essere vuoto, ad esempio se c'è un redirect)

Esempio di richiesta:

GET /items/42 HTTP/1.1
Host: www.example.org

Le azioni possono essere:

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE
  • OPTIONS
  • HEAD
  • CONNECT
  • TRACE

Gli status code sono di 4 tipi: 1xx, 2xx, 3xx, 4xx e 5xx.

  • 1xx Informazioni
  • 2xx Successo
  • 3xx Redirezione
  • 4xx Errore del client
  • 5xx Errore del server

Formato dei dati

Quando si sviluppano servizi su HTTP è necessario che client e server scambino dati strutturati.

Esistono sostanzialmente due alternative: XML e JSON.

XML non è il massimo per il web; JSON invece è più adatto in quanto un dato in formato JSON è immediatamente caricabile in una struttura dati javascript e, viceversa, una struttura dati javascript è naturalmente rappresentabile da una stringa JSON. JSON è anche più leggibile da un umano, è meno verboso.

Esempio di interazione client/server con autenticazione Basic

Client                                         Server
---------------------------------------------------->
GET / HTTP/1.1

<----------------------------------------------------
	                    HTTP/1.1 401 Unauthorized
	 WWW-Authenticate: Basic realm="Zona privata"

---------------------------------------------------->
GET / HTTP/1.1
Authorization: Basic dXRlbnRlOnBhc3N3b3Jk

<----------------------------------------------------
	                              HTTP/1.1 200 OK
                                             oppure
	                       HTTP/1.1 403 Forbidden

Il server chiede l'autenticazione (401) per il realm "Zona privata", il client riceve la risposta e prova ad autenticarsi inviando una nuova richiesta per la stessa risorsa e con l'header Authorization: con il valore Basic dXRlbnRlOnBhc3N3b3Jk.

La stringa "dXRlbnRlOnBhc3N3b3Jk" è la rappresentazione base64 di utente:password, che quindi viaggiano in chiaro, sarà compito di HTTPS quello di cifrare tutta la connessione.

Per generarlo da commandline:

printf utente:password |base64

Tutto questo lavoro il browser lo esegue automaticamente presentando la dialog di input delle credenziali all'utente.

Cookie di sessione

I cookie vengono scambiati utilizzando gli header. Il server chiede al client di registrare un cookie con l'header Set-Cookie e il client passa il cookie al server con l'header Cookie.

I cookie di sessione vengono utilizzati per gestire le sessioni di un utente archiviando tutte le informazioni necessarie in un database sul server.

Il cookie è un puntatore (un semplice numero/stringa casuale) usato per recuperare la sessione sul database.

Lo svantaggio di un cookie di sessione è che tutti i microservizi dovrebbero poter accedere al database per recuperare la sessione dell'utente, violando perciò il principio di accoppiamento lasco.

Autenticazione basata su token

La sessione non esiste più, al client/utente che si autentica correttamente viene rilasciato un token (Access Token), presentando il quale l'utente può accedere alle risorse se autorizzato.

Si tratta di autorizzazione al portatore (bearer), e si usa un header di questo tipo:

Authorization: Bearer eyJhbGciOiJIUzI1NiIXVCJ9...TJVA95OrM7E20RMHrHDcEfxjoYZgeFONFh7HgQ

JWT

Nel caso di JWT (Json Web Token) il token è in formato JSON ed è composto da un header, un payload ed una firma. L'header indica il tipo di cookie e l'algoritmo di firma, il payload trasporta le informazioni dell'utente ed i suoi privilegi, infine la firma garantisce l'integrità e l'autenticità del token.

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

Il token è quindi in chiaro, sarà compito di HTTPS garantire la segretezza.

Il servizio che riceve la richiesta dal client verifica che il JWT fornito sia valido e autorizza l'accesso alla risorsa in base al contenuto del token stesso.

I token sono stateless, non è necessario archiviarli.

REST

Si tratta del modo più corretto di usare il web.

Un piccolo insieme di azioni su un insieme molto grande di sostantivi.

Si parla di operazioni CRUD su risorse: (Create, Read, Update, Delete). Inoltre All read per elencare tutte le risorse.

Operation HTTP Verb URL
All GET /notes
Read GET /notes/:id
Create POST /notes
Update PATCH/PUT /notes/:id
Delete DELETE /notes/:id

I principali framework di sviluppo web rendono facile lo sviluppo di applicazioni REST a partire dalla definizione delle entità di una database. Una componente, chiamata router, mappa path dell'URL sui corrispondenti metodi che agiscono sulle risorse/entità.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment