Develop with the Payroll API

The QuickBooks Online GraphQL API uses the GraphQL API framework. Here’s a brief overview.

Learn about best practices and the advantages of GraphQL and what makes it a great API framework. For a deeper dive, visit GraphQL.org. You can check out courses from edx.org.

Create queries to request data

In GraphQL, queries can fetch data for single or multiple fields, apply filters, and get conditional data. If you’re familiar with the REST API, this is very similar to the GET operation. However, queries in GraphQL are always POST operations.

GraphQL queries are very efficient. When apps send requests with queries, the server only returns the requested data. The response will be the same shape and format as the query.

Server responses are clean, specific, and easy to work with. This also boosts app performance. Servers don’t slow down to fetch unusable or extraneous data.

How to create queries

For the QuickBooks Payroll API, use queries to get data for accounts, transactions, and other resources. Specify the exact fields you want the server to return in the query body.

Here’s a simple query to get company information:

1
2
3
4
5
6
7
8
9
          query RequestEmployerInfo {
                  payrollEmployerInfo {
                     businessInfo {
                         name {
                             legalName
                          }
                          }
                  }
          }

The server returns values for the legalName field.

Learn more about queries from GraphQL.org.

Use mutations to modify data

Mutations are what apps use to perform operations to change, update, or delete data on the server.

In GraphQL, you can use mutations to modify multiple fields with a single request. If you’re familiar with the REST API, mutations are similar to the POST, PUT, and DELETE operations.

While it’s possible to create and update data with queries in GraphQL, it’s best practice to use mutations to change or update data. And unlike queries, mutations run in series instead of in parallel.

How to use mutations

For the QuickBooks Payroll API, you’ll use mutations often for things like transactions and invoices.

Here’s a simple mutation to create an employer deduction:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
          mutation {
            createEmployerDeduction (
              deduction: {
                name: "My plan deduction"
                statutoryDeductionPolicy: "Annual max is 10k"
              }
            ) {
              id
              name
            }
          }

Mutations typically take input data and define fields based on the response the server returns.

In this example, the mutation took the deduction argument and let the server define the id and name fields based on the response.

Create fragments for sets of fields

Fragments are reusable sets of fields you can use across queries.

In GraphQL, you can define and group sets of fields into fragments. Instead of repeating individual fields, simply call the fragment to utilize all the fields and related data at once.

This lets you organize code into modular, bite-sized “chunks.”

How to create and use fragments

For the QuickBooks Payroll API, fragments are useful for queries that constantly reuse the same sets of fields.

Here’s an example of defining a fragment and using it in a query:

1
2
3
4
5
6
7
          query
            queryName {
              fieldName1
              fieldName2 {
                ...fragmentName
              }
            }

We put fragmentName in fieldName2.

Now define the fragment and corresponding set of fields:

1
2
3
4
5
6
          fragment
            fragmentName on FieldName {
              field1
              field2
              field3
            }

Now, instead of entering each individual field, you can just use fragmentName.

Use pagination to fetch subsets of data

Pagination lets you quickly search and request subsets of data within larger datasets.

In GraphQL, you can use the pageInfo object and cursor-based pagination (endCursor and startCursor) to set criteria or collect data after a certain point in the response. This typically yields smaller payloads and faster server responses.

For more about GraphQL pagination, see GraphQL Cursor Connections Specification.

Implement pagination

When querying a group of records, we recommend implementing pagination to avoid timeout errors. We suggest requesting 10 records at a time. The general format for pagination is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
          query queryName {
            fieldName1
            fieldName2(pagination: {first: numOfRecords, after: cursorValue}) {
             pageInfo {
                hasNextPage
                startCursor
                endCursor
                hasPreviousPage
              }
              field1
              field2
            }
          }

In this example, numOfRecords is the number of records you want returned by the query. The field cursorValue is the pointer to the first element that the count should begin from. numRecords is an Integer field and cursorValue is a String field.

Let’s take an example where there are 20 employees in the system and you want to read 5 at a time. The first time you send a request, set your cursorValue to null. Your query will look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
          query readAllEmployeePayslips {
                  company {
                          employees(
                                  pagination: { first: 5, after: null }
                          ) {
                                  pageInfo {
                                          hasNextPage
                                          startCursor
                                          endCursor
                                          hasPreviousPage
                                  }
                                  nodes {
                                          firstName
                                  }
                          }
                  }
          }

The response will return records 1 - 5:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
          {
            "data": {
              "company": {
                     "employees": {
                            "pageInfo": {
                                    "hasNextPage": true,
                                    "startCursor": "0",
                                    "endCursor": "4",
                                    "hasPreviousPage": false
                            },
                            "nodes": [
                               <5 employee nodes with data>
                            ]
                      }
                    }
             }
          }

From this response, if hasNextPage = true, get the value of endCursor and in your next query to read records 6 - 10, increment and pass this value as the cursorValue. So your next query will look like this

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
          query readAllEmployeePayslips {
            company {
                  employees(
                    pagination: { first: 5, after: "5" }
                  ) {
                          pageInfo {
                            hasNextPage
                            startCursor
                            endCursor
                            hasPreviousPage
                          }
                          nodes {
                            firstName
                          }
                    }
             }
          }

This will return records 6 - 10. You continue to do this as long as there are more records to be read. The field hasNextPage in the response is an indicator of whether there are more records left to be read or not. Once the last set of records are reached, the value of hasNextPage will be false.

QuickBooks Payroll API best practices

Learn about API throttling For information about throttling, see API call limits and throttles.

Single endpoints Let’s say you want to build an invoicing app. It needs to constantly request data for a specific set of invoices. The invoices contain particular items for a specific date range. And, the app needs current business addresses for each customer.

With the REST API, you’d need to make several queries to different endpoints: one for the invoice, one for each customer, and one for each item.

GraphQL only requires a single query, sent to a single endpoint.

Get only the data you need GraphQL queries are highly customizable. You specify the exact fields and values you want the server to return. Apps only get the data you query for–there’s no over-fetching or under-fetching.

Develop with any language GraphQL is language-independent. You can use it with any backend framework or programming language implementation.

Simple data hierarchies GraphQL requests and responses are structured the same way. It naturally follows relationships between attributes.