vai al contenuto principale

Sperimentare con GraphQL

Usiamo GraphQL per effettuare alcune semplici query sul modello d'esempio

Adesso che hai completato il tutorial, sai come modellare e rendere disponibile un’applicazione Livebase, sei quindi pronto ad utilizzare le API esposte dalla piattaforma. Il vero scopo di Livebase è, infatti, quello di fornire un back-end completo che puoi interrogare attraverso un endpoint GraphQL.

In questa sezione imparerai a sottomettere alcune semplici query GraphQL di consultazione, utilizzando come riferimento una Cloudlet su cui è stato montato un engine derivato dal modello finale ottenuto dal tutorial (vedi la lezione precedente), con le seguenti differenze:

  • L’associazione tra Activity e Project_assignment è stata resa bidirezionale, in modo da poter abilitare il ruolo da Activity a Project_assignment;
  • Nella classe Activity sono stati aggiunti gli attributi derivati project_name e assignment_employee, che indicano rispettivamente il nome del progetto seguendo il percorso Activity.assignment.project_.name e il nome dell’impiegato a cui questo è stato assegnato (Activity.Project_assignment.employee).

In più, è stato creato un utente per ciascuno dei profili definiti:

  • AccountantUser per il profilo Accountant, che ha accesso all’applicazione Accounting;
  • AdministratorUser per il profilo Administrator, che ha accesso a tutte le applicazioni;
  • StaffManagerUser per il profilo StaffManager, che ha accesso all’applicazione Staff_management;
  • TeamManagerUser per il profilo TeamManager, che ha accesso all’applicazione Team_management. L’utente appartiene al team Accounting Giants e gli è assegnato l’employee John Teamuser;
  • UserUser per il profilo User, che ha accesso all’applicazione User_area. Gli è assegnato l’employee John User.

Tutte le utenze hanno una password pari a test.

Il modello ha la struttura riportata nell’immagine qui sotto:

Cloudlet model

Puoi scaricarlo facendo clic su questo pulsante:

SandboxEngine_workforce

Utilizzo degli endpoint GraphQL #

Per interfacciarti con le API GraphQL di una Cloudlet, devi inviare delle richieste ai relativi endpoint. Puoi farlo in diversi modi, tra cui:

  • attraverso cURL, in ambiente Linux;
  • attraverso Postman, disponibile sia per Windows che per Linux;
  • attraverso il client GraphiQL, offerto dalla piattaforma.

In tutti gli esempi sottometteremo questa semplice query denominata Test, che dato l’identificativo di un impiegato (in questo caso 11000) restituisce il relativo oggetto Employee mostrandone i campi _id e first_name.

query Test {
  Employee___get(_id: 11000) {
    _id
    first_name
  }
}

Il risultato sarà quindi nel seguente formato:

{
  "data": {
    "Employee___get": {
      "_id": "11000",
      "first_name": "Dolorita"
    }
  }
}

Comunicazione tramite cURL #

cURL (abbreviazione di “Client URL”) è un tool per riga di comando che permette il trasferimento di dati attraverso diversi protocolli di rete, tra cui HTTP. Se usi Linux come sistema operativo, noterai che cURL è già disponibile e pronto all’uso.

Apri il Terminale e incolla questo comando sulla command line:

curl -i -X POST https://sandbox.livebase.com/trial/Workforce_readonly/auth/api/graphql/Administration \
 -H "Content-type: application/json" \
 -H "Authorization: Basic $(echo AdministratorUser:test | base64)" \
 -d '{"query": "query Test {Employee___get(_id: 11000) {_id first_name}}"}'

Il Terminale stamperà la seguente risposta:

HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Thu, 06 Oct 2022 19:01:09 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 67
Connection: keep-alive
X-Trace-ID: dce107637934ca156146c8116b5ae35f94b801aa
Access-Control-Allow-Credentials: true
Accept-Ranges: bytes
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Strict-Transport-Security: max-age=31536000

{"data":{"Employee___get":{"_id":"11000","first_name":"Dolorita"}}}

Affinché la richiesta sia correttamente interpretata dall’endpoint, è importante specificare il termine POST dopo l’opzione -X, unico metodo HTTP accettato dagli endpoint GraphQL. Da notare anche le opzioni -H che specificano quali header devono comparire nella richiesta, tra cui il Content-type, che deve essere settato a application/json, e l’Authorization. La stringa dopo i due punti indica che stiamo utilizzando la basic authentication a cui passiamo lo username AdministratorUser e la password test, entrambi codificati. Esserci autenticati come AdministratorUser ci permetterà di eseguire la query sull’applicazione Administration a cui lui ha accesso.

Comunicazione tramite Postman #

Postman è una piattaforma di sviluppo di API, che tra le varie funzionalità permette di effettuare interrogazioni agli endpoint in modo sistematico e veloce.

Una volta aperto Postman, vedrai la seguente schermata:
Postman screen.

Fai clic sul tasto “+” per aprire una nuova scheda, facente riferimento a una nuova richiesta HTTP.
Plus icon.

Seleziona il metodo POST dal dropdown, quindi inserisci l’indirizzo dell’endpoint GraphQL nella casella di testo a fianco.

https://sandbox.livebase.com/trial/Workforce_readonly/auth/api/graphql/Administration

Postman endpoint textbox

Fai clic su Headers, quindi sull’entry vuota in fondo alla tabella per aggiungerne uno nuovo. Come campo Key, inserisci Authorization, mentre come campo Value dovrai inserire Basic <base64>, dove <base64> è la coppia username e password così codificata. Per ottenere questo valore, è possibile procedere come visto nel paragrafo precedente, ovvero eseguendo il seguente comando da terminale (se si opera con Linux):

echo AdministratorUser:test | base64

Oppure, esegui il seguente codice Javascript nella finestra di ispezione del tuo browser e copia e incolla il risultato ottenuto.

btoa("AdministratorUser:test")

La tua tabella degli header avrà questo aspetto:
Postman header table

Fai clic su Body e seleziona l’opzione GraphQL, quindi incolla la query nell’omonima casella di testo e fai clic sul pulsante Send.

query Test {
  Employee___get(_id: 11000) {
    _id
    first_name
  }
}

Postman body send

Otterrai il seguente risultato:

Postman query response

Comunicazione tramite GraphiQL #

La Cloudlet di test mette a disposizione un client GraphiQL che puoi accedere facendo clic su questo pulsante:

Accedi alla sandbox

Si aprirà una finestra che richiede username e password. Digita per il primo AdministratorUser e per il secondo test. A questo punto vedrai questa schermata nel tuo browser:

GraphiQL

Nel pannello di sinistra, digita la query di test e premi il pulsante, oppure digita Ctrl+Enter. Le risposte JSON del server compariranno nel pannello a fianco.

Esempi di query #

Ora che conosci i principali metodi per sottomettere le query GraphQL, sperimenta con queste.

GetActivitiesByEmployee #

query GetActivitiesByEmployee {
  Activity___getPage(options : {
    filter : {
      assignment_employee___eq : "John User"
    }
  }) {
    items {
      assignment_employee
      project_name
      date
      hours
      minutes
      description
    }
  }
}

Questa query restituisce tutte le attività a cui sta lavorando l’impiegato John User, cioé tutti gli oggetti Activity il cui campo derivato assignment_employee ha come valore John User.

Può essere inviata da un qualsiasi utente il cui profilo è autorizzato a consultare gli oggetti di Activity, nel nostro caso:

  • AdministratorUser con il profilo Administrator;
  • TeamManagerUser con il profilo Team_manager;
  • UserUser con il profilo User.

Se l’utente ha il profilo Administrator, vengono sempre restituite le attività dell’impiegato specificato.

{
  "data": {
    "Activity___getPage": {
      "items": [
        {
          "assignment_employee": "John User",
          "project_name": "Mars Rocket",
          "date": "02/01/2022",
          "hours": 0,
          "minutes": 15,
          "description": "Lorem ipsum"
        }
      ]
    }
  }
}

Se l’utente ha il profilo Team_manager, si ottiene un risultato solo se l’impiegato specificato è nel suo stesso team.

Se invece viene sottomessa da un User, darà risultato nel solo caso in cui l’impiegato specificato sia quello a cui corrisponde l’utente.

GetActivitiesByProject #

query GetActivitiesByProject {
  Activity___getPage(options : {
    filter : {
      project_name___eq : "Mars Rocket"
    }
  }) {
    items {
      assignment_employee
      project_name
      date
      hours
      minutes
      description
    }
  }
}

Questa query restituisce tutte le attività che si riferiscono al progetto Mars Rocket, cioé tutti gli oggetti Activity il cui campo derivato project_name ha come valore Mars Rocket.

Può essere inviata da un qualsiasi utente il cui profilo è autorizzato a consultare gli oggetti di Activity, nel nostro caso:

  • AdministratorUser con il profilo Administrator;
  • TeamManagerUser con il profilo Team_manager;
  • UserUser con il profilo User.

Se l’utente è un Administrator, vengono restituite le attività di tutti gli impiegati sul progetto indicato.

{
  "data": {
    "Activity___getPage": {
      "items": [
        {
          "project_name": "Mars Rocket",
          "date": "28/10/2018",
          "hours": 0,
          "minutes": 16,
          "description": "Lorem ipsum"
        },
        {
          "project_name": "Mars Rocket",
          "date": "28/10/2018",
          "hours": 2,
          "minutes": 3,
          "description": "Lorem ipsum"
        },
        {
          "project_name": "Mars Rocket",
          "date": "28/10/2018",
          "hours": 8,
          "minutes": 2,
          "description": "Lorem ipsum"
        },
        # [...]
      ]
    }
  }
}

Se l’utente è un Team_manager, vengono restituite le attività sul progetto indicato che interessano i soli impiegati nello stesso team dell’utente.

{
  "data": {
    "Activity___getPage": {
      "items": [
        {
          "assignment_employee": "Dolorita Wanell",
          "project_name": "Mars Rocket",
          "date": "28/10/2018",
          "hours": 0,
          "minutes": 16,
          "description": "Lorem ipsum"
        },
        {
          "assignment_employee": "John Teamuser",
          "project_name": "Mars Rocket",
          "date": "02/01/2022",
          "hours": 0,
          "minutes": 15,
          "description": "Lorem ipsum"
        },
        {
          "assignment_employee": "John User",
          "project_name": "Mars Rocket",
          "date": "02/01/2022",
          "hours": 0,
          "minutes": 15,
          "description": "Lorem ipsum"
        }
      ]
    }
  }
}

Se l’utente è un User, vengono restituite le attività sul progetto indicato che interessano il solo impiegato a cui è associato l’utente.

{
  "data": {
    "Activity___getPage": {
      "items": [
        {
          "assignment_employee": "John User",
          "project_name": "Mars Rocket",
          "date": "02/01/2022",
          "hours": 0,
          "minutes": 15,
          "description": "Lorem ipsum"
        }
      ]
    }
  }
}

GetAllEmployees #

query GetAllEmployees {
  Employee___getPage(options: {}) {
    items {
      _id
      full_name
      address {
        _id
        city
      }
    }
  }
}

Questa query restituisce gli impiegati presenti nella classe Employee.

Può essere inviata da un qualsiasi utente il cui profilo è autorizzato a consultare gli oggetti di Employee, nel nostro caso:

  • AdministratorUser con il profilo Administrator;
  • StaffManagerUser con il profilo Staff_manager;
  • TeamManagerUser con il profilo Team_manager;
  • UserUser con il profilo User.

Se l’utente ha il profilo Administrator o Staff_manager, vengono restituiti tutti gli impiegati.

{
  "data": {
    "Employee___getPage": {
      "items": [
        {
          "_id": "11000",
          "full_name": "Dolorita Wanell",
          "address": {
            "_id": "31005",
            "city": "Santa Fe"
          }
        },
        {
          "_id": "11001",
          "full_name": "Ursuline Benezeit",
          "address": {
            "_id": "31006",
            "city": "Daytona Beach"
          }
        },
        {
          "_id": "11002",
          "full_name": "Will Kleine",
          "address": {
            "_id": "31007",
            "city": "Rosthern"
          }
        },
        {
          "_id": "11003",
          "full_name": "Vanna Bamforth",
          "address": {
            "_id": "31008",
            "city": "Pickering"
          }
        },
        # [...]
      ]
    }
  }
}

Se l’utente ha il profilo Team_manager, vengono restituiti tutti gli impiegati che appartengono al suo stesso team.

{
  "data": {
    "Employee___getPage": {
      "items": [
        {
          "_id": "11000",
          "full_name": "Dolorita Wanell",
          "address": {
            "_id": "31005",
            "city": "Santa Fe"
          }
        },
        {
          "_id": "11003",
          "full_name": "Vanna Bamforth",
          "address": {
            "_id": "31008",
            "city": "Pickering"
          }
        },
        {
          "_id": "11019",
          "full_name": "Lorry Shillan",
          "address": {
            "_id": "31024",
            "city": "Cedar Rapids"
          }
        },
        {
          "_id": "11020",
          "full_name": "Gradeigh O'Doohaine",
          "address": {
            "_id": "31025",
            "city": "Barrie"
          }
        },
        # [...]
      ]
    }
  }
}

Se l’utente ha il profilo User, viene restituito solo l’oggetto Employee che corrisponde a sé stesso.

{
  "data": {
    "Employee___getPage": {
      "items": [
        {
          "_id": "82906",
          "full_name": "John User",
          "address": null
        }
      ]
    }
  }
}

GetEmployee #

query GetEmployee {
  Employee___get(_id: 82906) {
    first_name
    last_name
    date_of_birth
    assignments {
      items {
        start_date
        end_date
        project_ {
          name
          completed
        }
      }
    }
  }
}

Questa query restituisce l’impiegato della classe Employee con l’id specificato dal parametro _id.

La query può essere inviata da un qualsiasi utente il cui profilo è autorizzato a consultare gli oggetti di Employee, nel nostro caso:

  • AdministratorUser con il profilo Administrator;
  • StaffManagerUser con il profilo Staff_manager;
  • TeamManagerUser con il profilo Team_manager;
  • UserUser con il profilo User.

Se l’utente ha il profilo Administrator o Staff_manager, viene sempre restituito l’impiegato con id richiesto.

{
  "data": {
    "Employee___get": {
      "first_name": "John",
      "last_name": "User",
      "date_of_birth": "01/01/1970",
      "assignments": {
        "items": [
          {
            "start_date": "01/01/2020",
            "end_date": "15/01/2020",
            "project_": {
              "name": "Mars Rocket",
              "completed": false
            }
          }
        ]
      }
    }
  }
}

Se l’utente ha il profilo Team_manager, l’impiegato viene restituito solo se appartiene allo stesso team dell’utente.

Se l’utente ha il profilo User, l’impiegato viene restituito solo se è quello associato all’utente.

GetEmployeesAndActivities #

query GetEmployeesAndActivities {
  Employee___getPage(options: {}) {
    items {
      _id
      full_name
      address {
        _id
        city
      }
      assignments {
        items {
          start_date
          end_date
          is_active
          activities {
            items {
              date
              hours
              minutes
              description
            }
          }
        }
      }
    }
  }
}

Questa query restituisce tutti gli Employee e le loro Activity sui vari progetti.

La query può essere inviata da un qualsiasi utente il cui profilo è autorizzato a consultare gli oggetti di Employee e Activity, nel nostro caso:

  • AdministratorUser con il profilo Administrator;
  • TeamManagerUser con il profilo Team_manager;
  • UserUser con il profilo User.

Se l’utente è di tipo Administrator, vengono restituiti tutti gli Employee con le relative Activity.

{
  "data": {
    "Employee___getPage": {
      "items": [
        {
          "_id": "11000",
          "full_name": "Dolorita Wanell",
          "address": {
            "_id": "31005",
            "city": "Santa Fe"
          },
          "assignments": {
            "items": [
              {
                "start_date": "16/08/2017",
                "end_date": "13/02/2018",
                "is_active": false,
                "activities": {
                  "items": [
                    {
                      "date": "28/10/2018",
                      "hours": 0,
                      "minutes": 16,
                      "description": "Lorem ipsum"
                    }
                  ]
                }
              }
            ]
          }
        },
        {
          "_id": "11001",
          "full_name": "Ursuline Benezeit",
          "address": {
            "_id": "31006",
            "city": "Daytona Beach"
          },
          "assignments": {
            "items": [
              {
                "start_date": "02/10/2018",
                "end_date": "22/02/2019",
                "is_active": false,
                "activities": {
                  "items": [
                    {
                      "date": "28/10/2018",
                      "hours": 10,
                      "minutes": 58,
                      "description": "Lorem ipsum"
                    }
                  ]
                }
              }
            ]
          }
        },
        {
          "_id": "11002",
          "full_name": "Will Kleine",
          "address": {
            "_id": "31007",
            "city": "Rosthern"
          },
          "assignments": {
            "items": [
              {
                "start_date": "07/08/2018",
                "end_date": "01/09/2018",
                "is_active": false,
                "activities": {
                  "items": [
                    {
                      "date": "28/10/2018",
                      "hours": 2,
                      "minutes": 47,
                      "description": "Lorem ipsum"
                    }
                  ]
                }
              },
              {
                "start_date": "10/10/2018",
                "end_date": "03/11/2018",
                "is_active": false,
                "activities": {
                  "items": [
                    {
                      "date": "28/10/2018",
                      "hours": 2,
                      "minutes": 10,
                      "description": "Lorem ipsum"
                    }
                  ]
                }
              },
              {
                "start_date": "01/12/2017",
                "end_date": "31/12/2017",
                "is_active": false,
                "activities": {
                  "items": [
                    {
                      "date": "28/10/2018",
                      "hours": 6,
                      "minutes": 20,
                      "description": "Lorem ipsum"
                    }
                  ]
                }
              }
            ]
          }
        }
        # [...]
      ]
    }
  }
}

Se l’utente è di tipo Team_manager, vengono restituiti tutti gli Employee che appartengono al suo stesso team, con le relative Activity.

{
  "data": {
    "Employee___getPage": {
      "items": [
        {
          "_id": "11000",
          "full_name": "Dolorita Wanell",
          "address": {
            "_id": "31005",
            "city": "Santa Fe"
          },
          "assignments": {
            "items": [
              {
                "start_date": "16/08/2017",
                "end_date": "13/02/2018",
                "is_active": false,
                "activities": {
                  "items": [
                    {
                      "date": "28/10/2018",
                      "hours": 0,
                      "minutes": 16,
                      "description": "Lorem ipsum"
                    }
                  ]
                }
              }
            ]
          }
        },
        {
          "_id": "11003",
          "full_name": "Vanna Bamforth",
          "address": {
            "_id": "31008",
            "city": "Pickering"
          },
          "assignments": {
            "items": [
              {
                "start_date": "04/03/2018",
                "end_date": "17/09/2018",
                "is_active": false,
                "activities": {
                  "items": [
                    {
                      "date": "28/10/2018",
                      "hours": 10,
                      "minutes": 9,
                      "description": "Lorem ipsum"
                    }
                  ]
                }
              }
            ]
          }
        },
        {
          "_id": "11019",
          "full_name": "Lorry Shillan",
          "address": {
            "_id": "31024",
            "city": "Cedar Rapids"
          },
          "assignments": {
            "items": [
              {
                "start_date": "29/09/2017",
                "end_date": "13/03/2018",
                "is_active": false,
                "activities": {
                  "items": [
                    {
                      "date": "28/10/2018",
                      "hours": 8,
                      "minutes": 51,
                      "description": "Lorem ipsum"
                    }
                  ]
                }
              }
            ]
          }
        }
        # [...]
      ]
    }
  }
}

Se l’utente è di tipo User, viene restituito il solo Employee associato all’utente, con le relative Activity.

{
  "data": {
    "Employee___getPage": {
      "items": [
        {
          "_id": "82906",
          "full_name": "John User",
          "address": null,
          "assignments": {
            "items": [
              {
                "start_date": "01/01/2020",
                "end_date": "15/01/2020",
                "is_active": false,
                "activities": {
                  "items": [
                    {
                      "date": "02/01/2022",
                      "hours": 0,
                      "minutes": 15,
                      "description": "Lorem ipsum"
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}

GetOutgoingInvoices #

query GetOutgoingInvoices {
  Outgoing_invoice___getPage(options : {
    filter : {
      AND : {
        date___gte: "01/01/2017"
        date___lte: "31/12/2017"
      }
    }
  }) {
    items {
      title
      number
      date
      amount
      amount_received
      amount_remaining
      is_fully_paid
    }
  }
}

Questa query restituisce tutte le fatture emesse nell’anno 2017, ovvero tutti gli oggetti di Outgoing_invoice il cui campo date è compreso tra 01/01/2017 e 31/12/2017.

La query può essere inviata da un qualsiasi utente il cui profilo è autorizzato a consultare gli oggetti di Outgoing_invoice, nel nostro caso:

  • AdministratorUser con il profilo Administrator;
  • AccountantUser con il profilo Accountant.

Fornisce sempre la seguente risposta:

{
  "data": {
    "Outgoing_invoice___getPage": {
      "items": [
        {
          "title": "313 [12/07/2017]",
          "number": "313",
          "date": "12/07/2017",
          "amount": "10,000",
          "amount_received": "13,000",
          "amount_remaining": "-3,000",
          "is_fully_paid": false
        },
        {
          "title": "783 [04/08/2017]",
          "number": "783",
          "date": "04/08/2017",
          "amount": "7,114",
          "amount_received": "0",
          "amount_remaining": "7,114",
          "is_fully_paid": false
        }
      ]
    }
  }
}

GetProjects #

query GetProjects {
  Project___getPage(options: {}) {
    items {
      name
      completed
      serial
      director
    }
  }
}

Questa query restituisce tutti gli oggetti della classe Project.

La query può essere inviata da un qualsiasi utente il cui profilo è autorizzato a consultare gli oggetti di Project, nel nostro caso:

  • AdministratorUser con il profilo Administrator;
  • StaffManagerUser con il profilo Staff_manager.

Fornisce sempre la seguente risposta:

{
  "data": {
    "Project___getPage": {
      "items": [
        {
          "name": "Mars Rocket",
          "completed": false,
          "serial": 1,
          "director": "Mal Cragell"
        },
        {
          "name": "3D Printed Car",
          "completed": false,
          "serial": 2,
          "director": "Vanna Bamforth"
        },
        {
          "name": "Cinemation Drone",
          "completed": true,
          "serial": 3,
          "director": null
        },
        {
          "name": "Customatic",
          "completed": false,
          "serial": 4,
          "director": null
        },
        {
          "name": "Wintermine",
          "completed": false,
          "serial": 5,
          "director": "Meredeth Bulfit"
        },
        {
          "name": "Classtacular App",
          "completed": true,
          "serial": 6,
          "director": null
        },
        {
          "name": "Flintstone",
          "completed": false,
          "serial": 7,
          "director": null
        },
        {
          "name": "Statmetric Portal",
          "completed": false,
          "serial": 8,
          "director": "Brodie Munns"
        },
        {
          "name": "Redhold",
          "completed": false,
          "serial": 9,
          "director": "Annelise Macbane"
        }
      ]
    }
  }
}