Integrazioni GraphQL e NodeJS con le funzioni di Cloud Code

GraphQL porta zucchero, spezie e tutto ciò che di bello c’è per gli sviluppatori di API, ma è fondamentalmente un linguaggio di query che consente di specificare ciò che si sta cercando.

E se nella vostra applicazione aveste bisogno di più business intelligence di questa?

E se vi servisse anche un po’ di logica?

E se voleste anche il modulo NPM Module?

Bene, allacciate le cinture di sicurezza perché oggi vi mostrerò qualcosa di molto potente. E da grandi poteri derivano grandi… beh… grandi risparmi di tempo, grandi possibilità, tante cose belle…

Se volete saperne di più su GraphQL, date un’occhiata a questo post: Cos’è GraphQL

Dovete essere alti così per cavalcare…

E utilizzate Parse 3.5.0 o superiore per giocare con GraphQL.
Andate su Impostazioni del server e Gestione del server Parse e assicuratevi di utilizzare una versione compatibile.

La nostra nuovissima funzione: Funzioni GraphQL + Cloud Code

Se siete già utenti di Parse/Back4app, probabilmente avete usato o almeno sentito parlare di Cloud Code.

Cloud Code è essenzialmente codice NodeJS che viene eseguito dai server delle applicazioni di Back4app invece che dai dispositivi finali.

Questo comporta alcuni vantaggi fondamentali a seconda delle esigenze, ma essenzialmente consente di:

  • Risparmiare sulla batteria del cellulare

    Quando si trasferisce il carico di elaborazione pesante dal dispositivo al cloud, l’elaborazione intensa non viene eseguita sul dispositivo, risparmiando così la batteria. L’elaborazione viene eseguita sui nostri server e il cliente riceve solo il risultato finale. Niente più cellulare bollente in tasca. Niente più “OMG questa app mi prosciuga la batteria!”.

  • Risparmiate sui piani dati

    Avete una tonnellata di oggetti da recuperare per ottenere un report. Migliaia? Milioni?
    Sono molti i dati che dovete recuperare e se non siete in WiFi, fareste meglio ad aggiornare il piano dati del cellulare.
    Sappiamo tutti che il piano dati è piuttosto costoso (nessuno paga più per gli SMS, giusto?), quindi, cosa succederebbe se avessimo un approccio più intelligente?
    E se potessimo far calcolare completamente il report sul cloud e recuperare solo l’ultimo risultato sul dispositivo? Un payload più piccolo che consumerebbe molto meno dal vostro piano dati e sarebbe anche più veloce?
    Sembra fantastico? Ecco cosa fa Cloud Code…

  • Implementazione più rapida del codice

    Una volta gli sviluppatori dovevano ripubblicare il loro software sugli App Store. All’epoca si trattava di una lotteria: se ricevevi un revisore più veloce, la tua applicazione sarebbe stata disponibile per gli utenti il giorno stesso. Con un revisore più lento o esigente, l’applicazione poteva impiegare settimane per essere pubblicata. Se veniva pubblicata.
    Perché rischiare?
    Consegnate agli App Store solo la parte frontend dell’applicazione e lasciate che la maggior parte della logica sia chiamata codice Cloud.
    Avete bisogno di apportare una piccola modifica alla logica? O un’enorme modifica? Nessun problema.
    Cambiate il codice cloud, distribuitelo di nuovo e sarete come nuovi. Nessuna revisione da parte di qualcuno da qualche altra parte e disponibilità immediata per i vostri clienti.

Ma ancora… che dire di GraphQL?

GraphQL consente di effettuare query. Si possono fare query molto intelligenti, ma solo query.

Quando il nostro CEO, Davi, stava discutendo su come renderlo più intelligente, l’integrazione con Cloud Code Functions sembrava essere solo una logica: avete il meglio di entrambi i mondi! La potenza e l’intelligenza di Cloud Code Functions e la facilità e la manutenibilità di GraphQL.

Attraverso la nostra nuova funzionalità è possibile estendere i tipi di GraphQL per eseguire le Cloud Code Functions e recuperarne i risultati.

Potete applicare qualsiasi logica aziendale che possiate immaginare alle vostre Cloud Code Functions, includervi i moduli NPM e interrogare il tutto con GraphQL.

Basta parlare. Mettiamo le mani in pasta…

Le classi e gli oggetti che utilizzeremo

Per questo post, ho creato due classi distinte: Employee e Pet, che conterranno i dipendenti di Back4app e i loro rispettivi animali domestici.

Un dipendente ha le seguenti proprietà:

  • nome (stringa)
  • età (Numero)
  • email (Stringa)
  • posizione (Stringa)
  • hasThisPet (puntatore alla classe Pet)

screen-shot-2019-08-07-at-13-18-26

Un Animale domestico ha le seguenti proprietà:

  • nome (Stringa)
  • specie (Stringa)

screen-shot-2019-08-07-at-13-18-37

E alcune funzioni del codice Cloud

Per le funzioni del codice Cloud, scriverò un file chiamato main.js e includerò il seguente codice.

Contiene cinque funzioni del codice Cloud completamente commentate che serviranno:

  • checkGraphQLSupport
    recuperare se l’applicazione ha il supporto a GraphQL
  • recuperareFirstEmployeeByName
    recuperare tutti i dettagli del primo dipendente trovato nel database con un determinato nome
  • recuperareTuttiImpiegati
    recupera tutti i dettagli di tutti i dipendenti
  • recuperareOnwerOfPetByName
    recupera i dettagli di un dipendente che ha un animale domestico con un determinato nome
  • recuperareDipendentePerNomeConAnimale
    recuperare tutti i dettagli di un dipendente e del suo animale domestico
Parse.Cloud.define("checkGraphQLSupport", async req => {
  /*
    Questa funzione restituisce se l'app supporta GraphQL. 
    Il parseGraphQLServer è vero se l'App lo supporta, altrimenti è falso.
  */
  if (parseGraphQLServer){
    restituisce "Questa App ha il supporto per GraphQL";
  } else {
    return "Questa applicazione non ha il supporto GraphQL. Forse la versione di Parse è sbagliata?";
  }
});

Parse.Cloud.define("retrieveFirstEmployeeByName", async req => {
  /*
    Questa funzione recupera il primo dipendente trovato con un determinato nome.
    Vengono recuperate tutte le proprietà del dipendente.
    Viene restituito un solo dipendente, se ce ne sono più di uno nel database.
    Se non ci sono dipendenti, viene recuperato null.
  */
  const query = new Parse.Query("Employees"); 
  query.equalTo("name", req.params.name);
  const result = await query.first();
  restituire il risultato;
});

Parse.Cloud.define("retrieveAllEmployees", async req => {
  /*
    Questa funzione recupera tutti i dipendenti.
    Vengono recuperate tutte le proprietà della classe Employee, ma solo di quella classe.
    Non vengono recuperati i dettagli di puntatori o relazioni, ma solo l'ID oggetto.
    Viene restituito un array di dipendenti. Vuoto se non ci sono dipendenti.
  */
  const query = new Parse.Query("Employees"); 
  const results = await query.find();
  restituisce i risultati;
});

Parse.Cloud.define("retrieveOnwerOfPetByName", async req => {
  /*
    Questa funzione recupera le informazioni sul dipendente relative a un animale domestico,
    in base al nome dell'animale domestico.
    Vengono recuperate tutte le proprietà della classe Employee.
    Non vengono recuperati i dettagli dell'Animale domestico.
    Viene restituito un array di animali domestici. Vuoto se non viene trovato alcun Animale domestico.
  */

  // Per prima cosa facciamo una query per recuperare le informazioni sull'animale domestico
  const petQuery = new Parse.Query("Pet"); 
  petQuery.equalTo("name", req.params.name);
  
  // Poi facciamo una query per recuperare i dettagli del suo dipendente in base alla proprietà hasThisPet
  let employeeQuery = new Parse.Query("Employees"); 
  employeeQuery.matchesQuery("hasThisPet", petQuery);
  const results = await employeeQuery.find();

  restituire i risultati;
  
});

Parse.Cloud.define("retrieveEmployeeByNameWithPet", async req => {
  /*
    Questa funzione recupera le informazioni sul dipendente e sul relativo animale domestico,
    in base al nome del dipendente.
    Vengono recuperate tutte le proprietà della classe Employee e della classe Pet.
    Viene restituito un array di dipendenti, che include una proprietà hasThisPet completamente popolata
    con le informazioni sull'animale domestico.
    Se non viene trovato alcun dipendente, viene restituito un array vuoto.
  */
  const query = new Parse.Query("Employees"); 
  query.equalTo("name", req.params.name);
  query.include("hasThisPet")
  const results = await query.find();
  restituisce i risultati;
});

Lo carichiamo nel nostro Cloud Code Functions, nella cartella Cloud.

Un piccolo passo in più

Le Cloud Code Functions che abbiamo appena pubblicato possono essere utilizzate, ma per farle funzionare con GraphQL, dobbiamo creare un file chiamato schema.graphql ed esporre queste funzioni.

La sintassi è molto semplice, ma richiede attenzione:

extend type Query {
 GraphQLMethodName (parameterName: parameterType): ReturnType! @resolve(to:"CloudCodeFunctionName")
}

Per il codice qui sopra, la sintassi rappresenta:

  • GraphQLMethodName
    Questo è il nome che verrà chiamato nella query GraphQL. Non deve necessariamente corrispondere al nome della funzione del codice Cloud, ma si dovrebbe scegliere qualcosa che renda facile capire cosa fa il metodo.
  • nome parametro
    Il nome del parametro che verrà consumato nella Request quando si trova all’interno della Cloud Code Function. Non è necessario passarlo se non si usano parametri nella funzione Cloud Code.
  • parametroTipo
    Il tipo di parametro che si sta passando. È possibile saperne di più sugli schemi e vedere tutte le possibilità. Non è necessario passarlo se non si utilizzano parametri nella funzione Cloud Code.
  • Tipo di ritorno
    È il tipo di ritorno del metodo.
  • Nome della funzione CloudCode
    Deve corrispondere al nome della Cloud Code Function indicato nel file main.js, in quanto il codice verrà chiamato in base al nome della funzione.

Quindi, per il nostro file main.js appena creato, il nostro schema.graphql sarebbe:

extend type Query {
  checkGraphQLSupport: String! @resolve(to: "checkGraphQLSupport")
  retrieveThisEmployeeByName (name:String): EmployeesClass! @resolve(to: "retrieveFirstEmployeeByName")
  dammiTuttiImpiegati: [EmployeesClass!]! @resolve(to: "retrieveAllEmployees")
  whichEmployeeIsOnwerOfThisPet (name:String): [EmployeesClass!]! @resolve(to: "retrieveOnwerOfPetByName")
  gatherEmployeeAndPetByEmployeeName (name:String): [EmployeesClass!] @resolve(to: "retrieveEmployeeByNameWithPet")
}

Non è così difficile, vero?

Notate che ho usato nomi molto estesi che non corrispondono al nome delle Cloud Code Functions, in modo che sappiate che potete rinominarle quando le esponete.

Ora tornate alla sezione Cloud Code Functions della vostra applicazione e caricate anche questo file. Assicurarsi che sia anche nella cartella Cloud. Se necessario, è possibile trascinarlo lì.
Se esiste già un file con quel nome e non è possibile caricarne uno nuovo, è possibile fare clic con il pulsante destro del mouse ed eliminarlo prima di caricarlo.

Distribuite tutto e siamo pronti a partire:

screen-shot-2019-08-07-at-14-52-49

Ora è il momento della magia…

Andare alla console GraphQL. Iniziate a digitare “query” e utilizzate la funzione di completamento automatico (CTRL + barra spaziatrice su Windows, OPTION + barra spaziatrice su Mac) e vedrete la magia:

screen-shot-2019-08-07-at-15-11-36

Tutti i nostri metodi sono presenti e possiamo interrogare ciascuno di essi. Proviamo uno per uno:

  • checkGraphQLSupport

    (si risolve nella nostra funzione del codice Cloud checkGraphQLSupport)
    screen-shot-2019-08-07-at-15-14-49

  • retrieveThisEmployeeByName (name:String)

    (si risolve nella nostra funzione Cloud Code retrieveFirstEmployeeByName)
    screen-shot-2019-08-07-at-15-19-18

  • dammiTuttiImpiegati

    (risolve la nostra funzione Cloud Code retrieveAllEmployees)
    screen-shot-2019-08-07-at-15-21-06
    Nell’esempio precedente, si noti che le proprietà name ed age sono state recuperate correttamente, ma hasThisPet ha valori nulli per il nome e la specie dell’animale domestico.
    Ciò è dovuto al fatto che nella funzione Cloud Code non sono state incluse (con il metodo include()) le informazioni sull’animale domestico.
    Il completamento automatico mostra le possibilità, ma nella funzione Cloud Code non sono stati forniti i dati per soddisfare tali informazioni.
    Vedere l’esempio gatherEmployeeAndPetByEmployeeNameresolves di seguito per vedere come includere le informazioni.

  • qualeDipendenteE'AmministratoreDiQuestoPet

    (si risolve con la nostra funzione del codice Cloud retrieveOnwerOfPetByName)
    screen-shot-2019-08-07-at-15-26-12

  • gatherEmployeeAndPetByEmployeeName 

    (si risolve con la nostra funzione del codice Cloud recuperareEmployeeByNameWithPet)
    screen-shot-2019-08-07-at-15-28-54

Le vostre fantastiche definizioni sono state aggiornate

Ecco come portare la logica aziendale in GraphQL.

Ti amo 3000!

Conclusione

GraphQL è un linguaggio di query e un runtime multipiattaforma potente e facile da usare, ma in fin dei conti è solo un linguaggio di query.
Con questa nuova integrazione con Cloud Code Functions, vi abbiamo portato il meglio di entrambi i mondi, liberando la potenza di Cloud Code (compresi i moduli NPM, baby!).

Ora sta a voi e alla vostra creatività! Fateci sapere come vi piace e come lo utilizzate nei vostri progetti nei commenti qui sotto!

Che cos’è il codice cloud?

Il codice cloud è fondamentalmente Node.JS. Viene eseguito dai server di Back4app anziché dai dispositivi finali. Offre diversi vantaggi a seconda delle esigenze. Permette di risparmiare sulla batteria, di distribuire il codice più velocemente e di risparmiare dati in base alle proprie esigenze.

In che modo Cloud Code aiuta a risparmiare sulla batteria del cellulare?

Aiuta a risparmiare batteria perché riduce il carico sui dispositivi. Il carico di elaborazione che era gestito costantemente dal dispositivo verrà trasferito al codice cloud e il dispositivo sarà più inattivo del solito. Quindi, alla fine, contribuirà a risparmiare batteria.

In che modo Cloud Code aiuta a salvare i dati?

Il codice cloud recupererà automaticamente tutti i dati che stavi elaborando tramite Wi-Fi o dati mobili. Continuerà a recuperare i dati e a calcolare report completi sul cloud.
Recupererà solo l’ultimo risultato sul dispositivo, il che si tradurrà in un carico utile inferiore e un minore utilizzo di dati.


Leave a reply

Your email address will not be published.