Foto di Darshak Pandya da Pexels

Come costruire un API Gateway con Express

 

Hai bisogno di sapere come costruire un API Gateway con Express, ma non sai come fare? Nessun problema.

Chiariamo il concetto di API gateway e poi vediamo come realizzarne uno, oppure quali tra gli strumenti già esistenti è possibile (e consigliato usare).

 

 

Cos’è un API gateway

 

Funzionamento dell'API gateway con due o più microservizi
Funzionamento dell’API gateway con due o più microservizi

 

Un API gateway è un componente che accetta tutte le request API dai client e quindi le instrada al microservizio appropriato attraverso il routing, la composizione e il protocollo appropriato. In altre parole, è un servizio che permette di gestire più richieste a servizi diversi, occupandosi di prendere in carico le chiamate e “smistarle” al microservizio giusto, determinando il percorso migliore. Può occuparsi anche della traduzione tra protocolli Web e protocolli non compatibili con l’applicazione del client (come AMQP o WebSocket).

 

Inoltre, l’API gateway è un vero e proprio pattern: è consigliato se si desidera progettare e creare applicazioni basate su microservizi complessi o di grandi dimensioni con più applicazioni client che devono accedere ad una serie di servizi. Lo scopo è simile a quello del pattern cosiddetto facade: in questo caso però, costituisce un proxy inverso all’interno di un sistema e utilizza un modello di comunicazione sincrono.

 

Un API gateway fornisce un singolo endpoint o URL che le applicazioni client possono utilizzare e mappa internamente le richieste ai microservizi appropriati; questo fornisce quindi un livello di astrazione maggiore, nascondendo alcuni dettagli di implementazione (ad esempio, il modo in cui la richiesta verrà gestita), oltre a funzionalità aggiuntive come piani di sottoscrizione (chi può interrogare una serie di servizi e fino a quando) o trasformazioni dell’input e dell’output, o ancora gestione dei logs e degli errori.

 

In questo articolo, il nostro API gateway fungerà semplicemente da gateway tra i client e i nostri servizi.

 

 

Step-by-step

 

Creazione del progetto Express Gateway

Per creare un progetto con Express Gateway, è necessario installare Node.js ed Express Gateway; una volta fatto, è possibile usare questo comando per creare un progetto che ci permetta di scrivere la nostra applicazione:

 

$ eg gateway create

 

Verrà generato un progetto con i seguenti file:

 

File generati dal comando precedente
File generati dal comando precedente

 

Chiaramente, dovremo avere a disposizione uno (o più) servizi con il quale il nostro gateway dovrà interagire. All’interno di questo articolo, andremo ad utilizzare questo repository, che offre un servizio di memorizzazione delle attività di una TODO list, ma nulla esclude che il nostro gateway possa in futuro aggiungere altri servizi e fornire un unico punto di accesso!


Configurazione del gateway

Per creare dei servizi manutenibili, esiste il file gateway.config.yml, che permette di definire un elenco di API che il gateway deve andare ad interrogare quando riceve una richiesta da un client.

 

Quando creiamo un progetto ex-novo, il file ha il seguente aspetto:

 

Andiamo a modificare le seguenti voci: per prima cosa, definiamo nella riga 6 all’interno della proprietà apiEndpoints una nuova API che il nostro gateway andrà ad esporre, ossia tasksApi: a partire dall’indirizzo localhost (il nostro gateway si trova in locale, al momento), mapperà tutti i path sotto /tasks* (vedere la definizione all’interno del file di routing del singolo microservizio), sfruttando il servizio che andiamo a definire subito dopo, all’interno di serviceEndpoints:

 

apiEndpoints:
  tasksApi:
    host: localhost
    paths: '/tasks*'
serviceEndpoints:
  tasksService:
    url: 'http://localhost:8081/api'

 

Anche i servizi sono esposti su localhost, ma sulla porta 8081: nel caso del gateway, andremo ad utilizzare la porta 8080, definendo questa regola all’inizio del file:

 

http:
  port: 8080

 

L’oggetto pipelines ci permette di definire in che modo il gateway deve cablare gli endpoint dell’API e il servizio: in questo caso, ne creiamo una ad hoc chiamata tasks che utilizza l’API endpoint definito in precedenza e stabilisce a quale servizio deve fare riferimento quando riceve una request:

 

pipelines:
  - name: tasks
    apiEndpoints:
      - tasksApi
    policies:
      - proxy:
          - action:
              serviceEndpoint: tasksService
              changeOrigin: true

 

 

Testiamo su Postman

Per assicurarci che la nostra API funzioni correttamente, possiamo testarla con Postman (o qualunque altro strumento).

 

Quello che avremmo fatto in precedenza, utilizzando il microservizio, sarebbe stato di effettuare una chiamata come quella riportata in figura, dove interroghiamo direttamente il servizio attraverso la sua porta:

 

Chiamata al microservizio
Chiamata al microservizio

 

Invece, adesso disponiamo di un gateway che ci permette di reindirizzare correttamente le request, utilizzando un’unica porta (la 8080):

 

Chiamata al microservizio attraverso il gateway
Chiamata al microservizio attraverso il gateway

 

Abbiamo raggiunto il nostro obiettivo configurando un solo microservizio: se ne volessimo aggiungere altri 10? Sarebbe sufficiente modificare il file seguendo gli step visti in precedenza per ogni nuovo microservizio, ed il gioco è fatto!

 

Definire un customer API

 

Express Gateway offre anche la possibilità di definire dei customer, ossia degli utenti che sono autorizzati ad utilizzare l’API, e questo ci permette di mettere in sicurezza i nostri servizi.

 

Per creare un nuovo consumer, eseguiamo la seguente request sulla porta 9876 (che viene utilizzata per la gestione amministrativa):

 

Creazione di un consumer
Creazione di un consumer

 

Una volta inserite le informazioni, dobbiamo specificare che la nostra API ha bisogno di una chiave di autenticazione, e lo facciamo in questo modo: inseriamo all’interno dell’attributo policies la proprietà key-auth, che ci permette di definire che l’API sarà esposta tramite una chiave di autenticazione con un header personalizzato (opzionale) che definiamo come CUSTOM-HEADER:

 

pipelines:
  - name: tasks
    apiEndpoints:
      - tasksApi
    policies:
      - key-auth:
          - action:
              apiKeyHeader: CUSTOM-HEADER
              disableHeadersScheme: true
      - proxy:
          - action:
              serviceEndpoint: tasksService
              changeOrigin: true

 

A questo punto, creiamo delle credenziali da assegnare all’utente creato poco fa con il seguente comando:

 

Creazione credenziali nel formato key-auth
Creazione credenziali nel formato key-auth

 

Se proviamo ad eseguire nuovamente una request lasciando le impostazioni così com’erano, questo è quello che otteniamo:

 

 

Unauthorized
La response è (giustamente) unauthorized

 

 

Per far sì che funzioni, andiamo ad aggiungere un header alla nostra request, dove il nome sarà quello configurato in precedenza, e il valore sarà dato dalla keyId:keySecret, ossia le due chiavi che abbiamo ottenuto durante il processo di creazione:

 

Aggiunta dell'header alla request
Aggiunta dell’header alla request

 

 

 

 

 

Alternative

 

Se ti è sembrato tutto (troppo) complicato, prova a dare un’occhiata a queste alternative:

  • Amazon API Gateway: https://aws.amazon.com/it/api-gateway/pricing/
  • Gravitee.io: https://docs.gravitee.io/apim/1.x/apim_installguide_gateway_configuration.html

 

Risorse utili

  • Documentazione ufficiale: https://www.express-gateway.io/docs
  • Tutorial ufficiali: https://www.express-gateway.io/getting-started/#installation

 

Condividi la tua opinione