skip to main content

Experimenting with GraphQL

We use GraphQL to make some basic queries on the example model

Now that you have completed the tutorial, you know how to model and make a Livebase application available, you are therefore ready to use the APIs exposed by the platform. The real purpose of Livebase is, in fact, to provide a complete backend that you can query through a GraphQL endpoint.

In this section you will learn how to submit some simple GraphQL queries for consultation, by referring to a Cloudlet on which an engine derived from the final model at the end of the tutorial has been deployed (see the previous lesson), with the following differences:

  • The association between Activity and Project_assignment was made bidirectional, so you can enable the role from Activity to Project_assignment;
  • In the Activity class, the derived attributes project_name and assignment_employee were added, which respectively point to the name of the project (following the path Activity.assignment.project_.name) and to the name of the employee to whom the project was assigned (Activity.Project_assignment.employee);
  • The writing grants have been removed from all profiles.

Moreover, a user was created for each of the defined profiles:

  • AccountantUser for the Accountant profile, who has access to the Accounting application;
  • AdministratorUser for the Administrator profile, who has access to all applications;
  • StaffManagerUser for the StaffManager profile, who has access to the Staff_management application;
  • TeamManagerUser for the TeamManager profile, who has access to the Team_management application. The user belongs to team Accounting Giants and has employee John Teamuser assigned to it;
  • UserUser for the User profile, who has access to the User_area application. The user has employee John User assigned to it.

The password for all users is test

The model has the structure shown in the image below:

Cloudlet model

You can download it by clicking on this button:

SandboxEngine_workforce

Using GraphQL endpoints #

To interface with a Cloudlet’s GraphQL APIs, you need to send requests to its endpoints. You can do this in a number of ways, including:

  • by cURL, in Linux;
  • by Postman, available both for Windows and Linux;
  • by the GraphiQL client, offered by the platform.

In all the examples we are going to submit this simple query called Test, which given the id of an employee (in this case 11000), returns the related Employee object, showing its _id and first_name fields.

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

The result will then be as follows:

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

Communicating by cURL #

cURL (short for “Client URL”) is a command line tool that allows data transfer across various network protocols, including HTTP. If you use Linux as your operating system, you will notice that cURL is already available and ready to use.

Open Terminal and paste this command on the 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}}"}'

Terminal will print the following response:

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"}}}

For the request to be correctly interpreted by the endpoint, it is essential to specify the term POST after the -X option; this is the only HTTP method accepted by GraphQL endpoints. Also note the -H options, specifying which headers should appear in the request (including Content-type, which should be set to application/json, and Authorization). The string after the colon indicates that we are using basic authentication, to which we are passing the AdministratorUser username and the test password, both encrypted. By authenticating as AdministratorUser we will be able to query the Administration application, to which only this user profile has access.

Communicating by Postman #

Postman is an API development platform, which among other features allows you to query the endpoints systematically and quickly.

Once Postman is open, you will see the following screen:
Postman screen.

Click the “+” button to open a new tab, referencing a new HTTP request.
Plus icon.

Select the POST method from the dropdown, then enter the GraphQL endpoint address in the text box alongside.

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

Postman endpoint textbox

Click on Headers, then on the empty entry at the bottom of the table to add a new one. For the Key field, enter Authorization, and for the Value field enter Basic <base64>, where <base64> is the encrypted username and password pair. To get this value, you can proceed as seen in the previous paragraph, i.e. by executing the following command from Terminal (if you are working with Linux):

echo AdministratorUser:test | base64

Alternatively, run the following Javascript code in the inspection window of your browser and copy and paste the result.

btoa("AdministratorUser:test")

Your header table will look like this:
Postman header table

Click on Body and select the GraphQL option, then paste the query into the text box of the same name and click on the Send button.

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

Postman body send

You will get the following result:

Postman query response

Communicating by GraphiQL #

The test Cloudlet provides a GraphiQL client that you can access by clicking on this button:

Access the sandbox

A window will open, asking for an username and a password. Type AdministratorUser as username and test as password. At this point you will see this screen in your browser:

GraphiQL

In the header select the correct Application for the user, as explained at the start of the section e.g. : Administration for the user AdministratorUser.

In the left panel, type your test query and press thebutton, or type Ctrl+Enter. The JSON response from the server will appear in the near panel.

Query examples #

Now that you know the main methods for submitting GraphQL queries, feel free to experiment with these sample queries.

GetActivitiesByEmployee #

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

This query returns all the activities the employee John User is working on, that is, all Activity objects whose derived field assignment_employee has John User as its value.

It can be submitted by any user whose profile is authorized to consult the Activity objects. In our case, these profiles are the following:

  • AdministratorUser with the Administrator profile;
  • TeamManagerUser with the Team_manager profile;
  • UserUser with the User profile.

If the user has the Administrator profile, the activities of the specified employee will be always returned.

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

If the user has the Team_manager profile, a result is obtained only if the specified employee is in the same team.

If, on the other hand, the query is submitted by a User profile, it will return a result only if the specified employee is the one to which the User corresponds.

GetActivitiesByProject #

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

This query returns all activities that refer to the Mars Rocket project, that is, all Activity objects whose derived field project_name has the value Mars Rocket.

It can be submitted by any user whose profile is authorized to consult the Activity objects. In our case, these profiles are the following:

  • AdministratorUser with the Administrator profile;
  • TeamManagerUser with the Team_manager profile;
  • UserUser with the User profile.

If the user is an Administrator, the activities of all employees working on the indicated project will be returned.

{
  "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"
        },
        # [...]
      ]
    }
  }
}

If the user is a Team_manager, then activities on the indicated project affecting only employees in the same team as the user will be returned.

{
  "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"
        }
      ]
    }
  }
}

If the user is a User, then the query will only return activities on the indicated project affecting the employee the user is associated with.

{
  "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
      }
    }
  }
}

This query returns the employees present in the Employee class.

It can be submitted by any user whose profile is authorized to consult the Employee objects. In our case, these profiles are the following:

  • AdministratorUser with the Administrator profile;
  • StaffManagerUser with the Staff_manager profile;
  • TeamManagerUser with the Team_manager profile;
  • UserUser with the User profile.

If the user has the Administrator or Staff_manager profile, all employees will be returned.

{
  "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"
          }
        },
        # [...]
      ]
    }
  }
}

If the user has the Team_manager profile, only employees who belong to the same team will be returned.

{
  "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"
          }
        },
        # [...]
      ]
    }
  }
}

If the user has the User profile, only the Employee object referring him or herself will be returned.

{
  "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
        }
      }
    }
  }
}

This query returns the employee of the Employee class with the id specified by the _id parameter.

The query can be submitted by any user whose profile is authorized to consult the Employee objects. In our case, these profiles are the following:

  • AdministratorUser with the Administrator profile;
  • StaffManagerUser with the Staff_manager profile;
  • TeamManagerUser with the Team_manager profile;
  • UserUser with the User profile.

If the user has the Administrator or Staff_manager profile, the employee with the required id will always be returned.

{
  "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
            }
          }
        ]
      }
    }
  }
}

If the user has the Team_manager profile, the employee will only be returned if they belong to the same team as the user.

If the user has the User profile, the employee will only be returned if it is the one associated with the user.

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
            }
          }
        }
      }
    }
  }
}

This query returns all the Employees and their Activities on the projects.

The query can be submitted by any user whose profile is authorized to consult the Employee and Activity objects. In our case, these profiles are the following:

  • AdministratorUser with the Administrator profile;
  • TeamManagerUser with the Team_manager profile;
  • UserUser with the User profile.

If the user is an Administrator, all Employees with their Activities will be returned.

{
  "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"
                    }
                  ]
                }
              }
            ]
          }
        }
        # [...]
      ]
    }
  }
}

If the user is a Team_manager, all the Employees belonging to his own team will be returned, along with their Activities.

{
  "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"
                    }
                  ]
                }
              }
            ]
          }
        }
        # [...]
      ]
    }
  }
}

If the user is an User, only the Employee associated with the user will be returned, along with its 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
    }
  }
}

This query returns all invoices issued in the year 2017, that is, all objects of Outgoing_invoice whose date field is between 01/01/2017 and 31/12/2017.

The query can be submitted by any user whose profile is authorized to consult the Outgoing_invoice objects. In our case, these profiles are the following:

  • AdministratorUser with the Administrator profile;
  • AccountantUser with the Accountant profile.

It will always give the following answer:

{
  "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
    }
  }
}

This query returns all objects of class Project.

The query can be submitted by any user whose profile is authorized to consult Project objects. In our case, these profiles are the following:

  • AdministratorUser with the Administrator profile;
  • StaffManagerUser with the Staff_manager profile.

It will always give the following answer:

{
  "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"
        }
      ]
    }
  }
}