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
eProject_assignment
è stata resa bidirezionale, in modo da poter abilitare il ruolo daActivity
aProject_assignment
; - Nella classe
Activity
sono stati aggiunti gli attributi derivatiproject_name
eassignment_employee
, che indicano rispettivamente il nome del progetto seguendo il percorsoActivity.assignment.project_.name
e il nome dell’impiegato a cui questo è stato assegnato (Activity.Project_assignment.employee
); - Sono stati tolti a tutti i profili i diritti di scrittura.
In più, è stato creato un utente per ciascuno dei profili definiti:
AccountantUser
per il profiloAccountant
, che ha accesso all’applicazioneAccounting
;AdministratorUser
per il profiloAdministrator
, che ha accesso a tutte le applicazioni;StaffManagerUser
per il profiloStaffManager
, che ha accesso all’applicazioneStaff_management
;TeamManagerUser
per il profiloTeamManager
, che ha accesso all’applicazioneTeam_management
. L’utente appartiene al teamAccounting Giants
e gli è assegnato l’employeeJohn Teamuser
;UserUser
per il profiloUser
, che ha accesso all’applicazioneUser_area
. Gli è assegnato l’employeeJohn User
.
Tutte le utenze hanno una password pari a test
.
Il modello ha la struttura riportata nell’immagine qui sotto:
Puoi scaricarlo facendo clic su questo pulsante:
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:
.
Fai clic sul tasto “+” per aprire una nuova scheda, facente riferimento a una nuova richiesta HTTP.
.
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
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:
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
}
}
Otterrai il seguente risultato:
Comunicazione tramite GraphiQL #
La Cloudlet di test mette a disposizione un client GraphiQL che puoi accedere facendo clic su questo pulsante:
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:
Nell’intestazione seleziona l’Application
corretta per l’utente, come spiegato all’inizio della sessione es. : Administration
per l’utente AdministratorUser
.
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 profiloAdministrator
;TeamManagerUser
con il profiloTeam_manager
;UserUser
con il profiloUser
.
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 profiloAdministrator
;TeamManagerUser
con il profiloTeam_manager
;UserUser
con il profiloUser
.
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 profiloAdministrator
;StaffManagerUser
con il profiloStaff_manager
;TeamManagerUser
con il profiloTeam_manager
;UserUser
con il profiloUser
.
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 profiloAdministrator
;StaffManagerUser
con il profiloStaff_manager
;TeamManagerUser
con il profiloTeam_manager
;UserUser
con il profiloUser
.
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 profiloAdministrator
;TeamManagerUser
con il profiloTeam_manager
;UserUser
con il profiloUser
.
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 profiloAdministrator
;AccountantUser
con il profiloAccountant
.
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 profiloAdministrator
;StaffManagerUser
con il profiloStaff_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"
}
]
}
}
}