Javascript, HTML, CSS e... !
0 commenti

doGet() e parametri in querystring

Creare un Web Service o una RESTful API con Google Apps Script

Tra le modalità con le quali può essere resa disponibile, ovvero interrogabile, dall'esterno una funzione in Google Apps Script è presente quella relativa alla distribuzione come API eseguibile, come mostrato nell'articolo 'Interrogare una funzione in Google Apps Script da Remoto con le Execution API'.
Nel caso specifico la procedura segue una serie di passaggi che coinvolgono la Google Console per la generazione di credenziali di autenticazione e successiva implementazione di librerie ed impostazioni dedicate al fine di potersi interfacciare da remoto con l'API personalizzata.

Esiste tuttavia un modo più semplice e veloce per creare una propria API (o un web service), sempre interrogabile da remoto, basato sulla distribuzione dello script come applicazione web anziché come API eseguibile.

Prima di entrare nel cuore della praticità riporto alcuni requisiti chiave da best practice, da tenere in considerazione, che un'API pragmatica progettata per le applicazioni web dovrebbe avere (la lista seguente, sicuramente non esaustiva, non rappresenta uno standard bensì vuole essere solo una modalità di approccio).
Una API:

- Dovrebbe usare gli standard web dove ha senso che siano applicati;
- Dovrebbe essere scritta in modo chiaro affinché sia facilmente manutenibile dallo sviluppatore;
- Dovrebbe essere esplorabile tramite la barra degli indirizzi del browser;
- Dovrebbe essere semplice, intuitiva ed efficiente per agevolarne l'utilizzo.

Un esempio di creazione di un'API, o servizio web, potrebbe essere quello di rendere disponibile all'esterno la lista dei prodotti venduti in un ecommerce, mettendo a disposizione le relative informazioni di nome, descrizione, prezzo, categoria, quantità in magazzino, ecc..., con la finalità di permettere a servizi esterni di poter gestire tali dati all'interno delle loro applicazioni.

L'esempio riportato di seguito si basa su uno script, presente su GitHub, chiamato gas-rest-api che in pratica, dopo essere rilasciato come applicazione web e pertanto interrogabile tramite un link pubblico, in base ai parametri passati legge da uno Spreadsheet le righe dei prodotti richiesti e fornisce una risposta in JSON sul sistema che ha effettuato la chiamata.

La scelta di ottenere una risposta in JSON anziché in altri formati di interscambio dati, come ad esempio l'XML, è dovuta (parlando sempre di best practice) alla praticità di utilizzo del JSON che ad oggi è affermato come standard in molti progetti, basta osservare la sua tendenza nel tempo rispetto all'XML, Fig. 1:



google trends - json api in confronto con le xml api

Fig. 1 - Confronto tra le JSON API e le XML API in Google Trends


Per visualizzare i dati aggiornati alla data corrente potete fare riferimento a Google Trends per la chiave di ricerca JSON API vs XML API.

Lo script può essere di tipo standalone, che recupera lo Spreadsheet desiderato tramite il suo id con il metodo SpreadsheetApp.openById(id), come nel caso dell'esempio originale oppure essere integrato nello Spreadsheet stesso (si parla quindi di bound script) come nella versione proposta di seguito dove le istanze dello Spreadsheet e del relativo foglio di calcolo vengono recuperate con gli specifici metodi di script associati, tra i quali ad esempio SpreadsheetApp.getActiveSpreadsheet().

La lista dei prodotti sui quali lo script agirà è la seguente, Fig. 2:



lista esemplificativa di prodotti all'interno di uno spreadsheet

Fig. 2 - Lista esemplificativa di prodotti all'interno di uno Spreadsheet


Il codice Apps Script da inserire all'interno dell'editor associato allo Spreadsheet (dal menu 'Strumenti' del Foglio di Calcolo selezionare la voce 'Editor di script...') è il seguente:

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var rng = ss.getDataRange();
var data = rng.getValues();
var headings = data[0];

/*
Recupera le informazioni dell'ID (SKU) di prodotto specificato
Esempio: [1.0, Camicia per uomo, Camicia elastica di fibra di bambù, 20.39, 0.21, http://esempio.it/01.jpg, Abbigliamento, 5.0, EUR]
*/
function productQuery(prodId) {
  for (var i = 1; i < data.length; i++) {
    if (prodId == data[i][0]) {
      return data[i];
    }
  }
}

/* Recupera le informazioni dell'ID (SKU) di prodotto specificato e le converte in un oggetto formando coppie chiave:valore con i rispettivi nomi delle colonne presenti nell'header dello Spreadsheet */
function formatProduct(rowData) {
  var product = {}
  for (var i = 0; i < headings.length; i++) {
    product[headings[i].toString()] = rowData[i];
  }
  return product;
}

function doGet(request) {
  // Verifica se in querystring sono presenti parametri i action e prodid
  if (request.parameter.action !== undefined) {
    if (request.parameter.prodid !== undefined) {
      prodIds = request.parameters.prodid;
      
      // Inizializzazione dell'oggetto che sarà restituito in formato JSON
      response = {
        products : []
      }
      
      // Gestisce ciascun prodotto specificato in querystring e popola l'oggetto da restituire in JSON
      for (var i = 0; i < prodIds.length; i++) {   
        sheetData = productQuery(prodIds[i]);
        product = formatProduct(sheetData);
        response.products.push(product);
      }
      
      if (response.products.length > 0) {
        return ContentService.createTextOutput(JSON.stringify(response));
      } else {
        return ContentService.createTextOutput('Attenzione! Non è stato specificato alcun parametro prodid.');
      }      
    } else {
      return ContentService.createTextOutput('Attenzione! Non è stato specificato un parametro prodid valido.');
    } 
  } else {
    return ContentService.createTextOutput('Attenzione! Non è stato specificato un parametro action valido.');
  }
}

Sempre all'interno dell'editor di script è necessario prima abilitare le Google Sheets API come mostrato a titolo esemplificativo nell'articolo 'Abilitare l'uso delle API dei Servizi Avanzati nei progetti in Google Apps Script', successivamente servirà avviare una funzione (sempre dall'editor di script), ad esempio doGet(), per far comparire la finestra di richiesta autorizzazioni e poter fornire allo script gli opportuni permessi, come descritto nell'articolo 'Flusso per l'Autorizzazione dei Google Services nei progetti in Apps Script'.

Sarà possibile a questo punto rendere pubblico il servizio web dal menu 'Pubblica -> Distribuisci come applicazione web...'.
Si aprirà una finestra dove andrà definito come eseguire l'applicazione (scgliere 'Io', ovvero l'utente che ha creato lo script) e chi può accedere all'applicazione (scegliere 'Chiunque, inclusi utenti anonimi'), Fig. 3:



impostazioni per la distribuzione dello script come applicazione web

Fig. 3 - Impostazioni per la distribuzione dello script come Applicazione Web


Una volta confermato verrà fornito il link pubblico, Fig. 4, che fungerà da base per la chiamata all'API:



finestra con il link pubblico dell'applicazione web in apps script

Fig. 4 - Finestra con il link pubblico dell'Applicazione Web in Apps Script


Per poter fornire una risposta dovrà essere indicato allo script il tipo di azione che vogliamo effettuare e cosa vogliamo recuperare. Per farlo, condiderando che gli URL degli script in Apps Script, per loro natura, non possono essere costruiti a livelli di sottocartelle, la gestione delle informazioni dovrà essere effettuata tramite parametri in querystring.
Nel caso specifico i parametri previsti sono action e prodid:
Come action, essendo un codice a scopo illustrativo, basta semplicemente valorizzare il parametro tuttavia per coerenza con la funzione illustrata, nel caso dell'esempio in questione, il suo valore opportuno è get (ma potrebbe essere anche post, put, delete, patch).
Come prodid è necessario semplicemente valorizzare il parametro con l'id (lo sku) del prodotto; è inoltre possibile ripetere tale parametro per effettuare una richiesta multipla di prodotti.
Un esempio di richiesta delle informazioni relative ai prodotti con SKU uguale a 1 e SKU uguale a 6 è la seguente (al posto di '[SCRIPT_URL]' dovrà essere utilizzato l'URL dell'applicazione web precedentemente pubblicata):

[SCRIPT_URL]?action=get&prodid=1&prodid=6

Per ricreare la situazione reale della chiamata di cui sopra, utilizzando Postman per verificare l'effettivo fuzionamento dell'API creata, servirà selezionare GET come metodo di chiamata ed inserire l'URL dell'applicazione web nella barra degli indirizzi (Fig. 5 al punto 1).

Nella sezione 'Params' inserire come chiave e valore i seguenti parametri (nota: se i parametri si trovano già nella querystring dell'URL dell'applicazione all'interno della barra degli indirizzi di Postman appariranno automaticamente precompilati, Fig. 5 al punto 2):
action get
prodid 1
prodid 6

Essendo lo script pubblico e non soggetto ad autenticazione da parte dell'utente che lo esegue non sono rischieste ulteriori informazioni da inserire, basterà pertanto cliccare su 'Send' per poter vedere nella parte dedicata alla risposta delle chiamate in Postman, Fig. 5 al punto 3, il risultato relativo ai 2 prodotti richiesti strutturato ordinatamente nel formato JSON:



chiamata in get con parametri ad uno script in apps script tramite postman

Fig. 5 - Chiamata in GET con parametri ad uno script in Apps Script tramite Postman


Sulla base di questo script è possibile creare ulteriori API, come ad esempio per la richiesta di tutti i prodotti di una determinata categoria o dei prodotti all'interno di una determinata fascia di prezzo e quant'altro possa essere di aiuto per fornire un servizio web completo e facile da usare da altri servizi esterni.

Tags

Michele Pisani

Michele Pisani

Sviluppatore Javascript ed esperto in Digital Analytics

L'esperienza nel settore Digital Analytics unita ad anni di sviluppo in Javascript ha trovato la massima espressione in Google Apps Script che mi ha permesso, con estrema facilità e poche righe di codice, di realizzare potenti applicazioni interattive e processi automatizzati integrati con i prodotti della G Suite.

Come contattarmi
scrivi un commento

0 Commenti

Non ci sono commenti

Nessuno ha ancora commentato questo articolo, fallo tu per primo!

scrivi un commento

Scrivi un commento

Il tuo indirizzo email non sarà pubblicato.I campi contrassegnati da un * sono obbligatori
Puoi utilizzare i seguenti tag nei commenti:
[bold]testo[/bold] se vuoi evidenziare un testo con il grassetto[code]function helloworld() { }[/code] se vuoi pubblicare una porzione di codice[url]http://www.appsscript.it[/url] se devi riferirti ad un indirizzo web