Building an App in Jobber Platform
Tags: integration, graphql, testing
Published: 2023-12-14 17:33:07


## Building the application
We are back with the second post of this three-part series. In the [first post](https://dev.to/jobber/building-an-app-in-jobber-platform-57aj) we talked about Jobber’s objectives for rebuilding the QBO integration, the principles behind it and which architectural decisions the team had to make while building the integration. The Jobber platform through the Developer Center was introduced and in this post we will dig deeper into the details which entail building the application using [Jobber’s Developer Center](https://developer.getjobber.com/landing).

### Getting started

To get started with building applications in Jobber’s platform, there are a few pre-requirements:

1. Create a [developer account](https://getjobber.com/developer-sign-up/) in Jobber;
2. Create a [Developer Center account](https://developer.getjobber.com/signup/). (It is important to note that the Jobber developer account is a completely separate account from the Developer Center account);

### Creating the app 
After creating the developer’s accounts, head over to your [apps](https://developer.getjobber.com/apps) page and click on the 'NEW' button to create your first app.

When creating your application, you will be prompted for:

- **App name** (required)
- **Developer name** (required)
- **OAuth Callback URL** (optional)
- **Manage App URL** (optional)
- **App description** (required)
- **Features & benefits** (optional)
- **Scopes** (required)
- **App logo** (optional)
- **Gallery images** (optional)
- **Webhooks** (optional)

Any details about this app such as App Name or Description can be modified later, but it is important to select the correct scopes when starting as these currently cannot be edited later (a new app will need to be created instead). **App name**, **Developer name**, **App description**, **Features & benefits**, **App logo**, and **Gallery images** are all important pieces that'll make up the content of your app listing in Jobber's App Marketplace.

The **App Name**, **Developer name**, **App Description**, **Manage app URL**, and **Features or benefits** will be used by your app's listing on the marketplace (if you choose to publish your app). Check the [Publishing Your Application](https://developer.getjobber.com/docs/build_with_jobber/manage_apps/#publishing-your-application-on-the-marketplace) section for more details.

The **OAuth Callback URL** is the URL that a Jobber user will be redirected to immediately after connecting and authorizing access to your app.

The **Manage App URL** is an alternative URL that can be used for any accounts that have already connected to your app but will have a need to navigate back to it to manage or configure functionalities.

**Scopes** are where you can set exactly what kinds of data your app will be able to read or write from Jobber accounts using the GraphQL API. They also determine exactly what is shown on the OAuth screen when a Jobber user is connecting to your app. While an app is in a Draft state, the scopes can be freely edited. However, if an app is published and would like to add more scopes, all accounts that have connected to the app previously will need to re-authorize the app. More details on editing an app can be found [here](https://developer.getjobber.com/docs/publishing_your_app/editing_a_published_app).

**[Webhooks](https://developer.getjobber.com/docs/using_jobbers_api/setting_up_webhooks/)** allow for real-time data to be sent to your application when an event occurs on models within Jobber. Webhooks are configured at the application level and will trigger when an account with an installation performs the topic. As an example, if you've configured a webhook to listen to CLIENT_CREATE, whenever a user creates a new client, the URL provided will be sent a POST request with the details in the body.

For more details on how Jobber apps work and the processes around implementing, testing, and submitting your app for review, see the guides in the [Build With Jobber](https://developer.getjobber.com/docs/build_with_jobber/app_lifecycle) section. There is also an [App Template Project](https://developer.getjobber.com/docs/app_template_project) section if you would like to download and set up a working template app to start with. It is a good way to quickly start the development using some of the pre-setup projects with UI components, authentication and API examples. In the next section, we will explore more about how the Authentication and GraphQL API works.

#### Authenticating the app
Jobber uses [OAuth 2.0](https://auth0.com/intro-to-iam/what-is-oauth-2) for app authorization. OAuth 2.0 is widely adopted across various platforms, including web, desktop, and mobile applications. It's used by major applications like Facebook and GitHub.

Upon [adding your app](https://developer.getjobber.com/apps), Jobber provides a client identifier and secret. The client ID is public, and used for identification, while the secret is confidential for authenticating with the Jobber API.

To authorize your app, an admin initiates the process via Jobber's App Marketplace or a provided link:
```
https://api.getjobber.com/api/oauth/authorize?client_id=<CLIENT_ID>&redirect_uri=<REDIRECT_URL>&state=<STATE>
```
Components:
- `<CLIENT_ID>`: Your app's Client ID from the Developer Center
- `<CALLBACK_URL>`: The URL where Jobber redirects after authorization.
- `<STATE>`: A random string to prevent cross-site request forgery attacks

When a user interacts with a link or clicks the Connect button in Jobber's App Marketplace, they will be asked to grant authorization to the app by clicking an "Allow Access" button. If the user is not already logged into their Jobber account, they will need to log in before reaching the authorization screen.

![An authorization modal for the Jobber platform. The title reads "Developer app wants access to your jobber account" above a pointed list of scopes the app is requesting. At the bottom right of the modal are a grey "cancel" button, and a green "allow access" button ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p96072jma2hpjjk76jxc.png)
After approval, Jobber redirects the user to your app's callback URL with an authorization code:

```
https://yourapplication.com/callback?code=AUTHORIZATION_CODE&state=STATE
```
In case the user denies the access request, Jobber will redirect the user-agent to your application's redirect URI without any additional parameters.

Your app then obtains an access token by making a POST request to Jobber's token endpoint. The token is used for API interactions.

```
https://api.getjobber.com/api/oauth/token?client_id=<CLIENT_ID>&client_secret=<CLIENT_SECRET>&grant_type=authorization_code&code=<AUTHORIZATION_CODE>
```
If the access token expires, use the refresh token to obtain a new one. Refresh tokens may expire due to app disconnection, manual client secret rolling, re-authorization after scope change, or Refresh Token Rotation.


If both the access and refresh tokens expire, the user will need to initiate the OAuth flow again. Your app should prompt them to do so by redirecting them to Jobber and back to the app's Callback URL.

Visit our [Developer Center](https://developer.getjobber.com/docs/building_your_app/app_authorization/) for detailed information on how the authorization works.

### Using the GraphQL Playground 

Before fully building out your app you can view the GraphQL Docs and Schema and make API requests using the GraphQL Playground tool and allowing access to your tester Jobber account. To do this, click on the three dots next to your [app](https://developer.getjobber.com/apps) in the Developer Center and then click Test in Playground.

![a dropdown modal with the options: "edit", "copy secret", "copy client id", "test in playground", and "request review". The "request review" and "edit" options are highlighted](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xia03vpmpfzjh2w29hi2.png)
This will take you through the same Oauth2 flow that a normal admin user would do, and afterwards you'll be redirected to GraphQL Playground where you can view the available queries and mutations with the DOCS button on the right, or you can download the entire Schema. Note that the scopes on your application will be respected and you may not be able to query for all of the data seen within our schema.

![a screenshot of the graphql playground showing available queries in the jobber api schema](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6v24ffrsukz2t9p36th.png)

An example query will already be provided for you, but a second example query you could use to view the **id**, **jobNumber**, and **title** of every Job in your tester account is:

```
query SampleQuery {
  jobs {
    nodes {
      id
      jobNumber
      title
    }
  }
}
```
Alternatively, you can make API requests by posting your GraphQL query or mutation to **https://api.getjobber.com/api/graphql**. You will need to include the Access token from step 4 under the **Authorization** header, preceded by the word **bearer**.

## Other important things
### App-configured custom fields
[Custom fields](https://developer.getjobber.com/docs/using_jobbers_api/custom_fields/) in Jobber are a popular feature, allowing various data formats to be linked to six Jobber objects: **Clients**, **Properties**, **Quotes**, **Jobs**, **Invoices**, and soon **Team members**. These fields are set up at the account level and store values at the object level. Admin users typically configure these fields, but the API also permits apps to create new custom fields with proper permissions.

Custom field configurations include settings like **custom field name**, **automatic data transfer to related objects**, **default values**, and **data types** (True/False, Numeric, Area, Dropdown, Text, Link), along with **units of measure** for numeric and area fields. 

When an app configures a custom field, its name and logo are displayed to Jobber users whenever they encounter the field in Jobber's user interface. This enhances the user experience and association with the app. For example, if an app called “XYZ App” configured two custom fields on all job objects, the resulting user experience would look like the screenshot below.

![A screenshot of the Job view in Jobber. Two arrows point to a section of the job view that show the app configured custom fields. The arrows point to the app logo, and the app's name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/inuoy9v47sqhdtx5um9r.png)

### API Versioning 
[API versioning](https://developer.getjobber.com/docs/using_jobbers_api/api_versioning/) is a method that Jobber uses to continuously improve its platform and features while ensuring a predictable process for third-party developers to upgrade their applications. Here's a summary of the approach:

- Dangerous and breaking changes are introduced in versioned releases.
- Versions are labeled with date formats (YYYY-MM-DD) and irregularly published to the [changelog](https://developer.getjobber.com/docs/changelog).
- New versions are added whenever there are breaking or dangerous changes to the API.
- Old versions are supported for 12 months after the release of a newer version.
- If you're using an unsupported version, you'll be automatically upgraded to the earliest supported version, even if it includes breaking changes.


![a timeline from January 2022 to June 2023. A bar labeled 2022-03-10 extends from the markers for March 2022 past June 2023. Above it, a bar labeled 2022-01-01 extends from the markers for January 2022 to March 2023. Above the bar a speech bubble points to january 2023 and has the caption "Warning is returned on requests using 2022-01-01". Another speech bubble points to March 2023 and has the caption "Requests using 2022-01-01 will return data from version 2022-03-10"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lj79i1gf4jdr40whj1j4.png)

### API rate limits
Jobber's GraphQL API has [rate limits](https://developer.getjobber.com/docs/using_jobbers_api/api_rate_limits/) in place to ensure the stability of the platform for all interacting apps. There are two rate limiters in use:

- **DDoS Protection Middleware**: This limits clients to 2500 requests per 5 minutes on a per app/account basis, rather than by IP address. If an app exceeds this limit, subsequent requests to the same Jobber account will receive a "429 Too Many Requests" error. This limit is generally less restrictive than the GraphQL Query Cost limit.
- **GraphQL Query Cost Calculation**: Each app/account combination has a maximum number of points available for making queries. The cost of each query is deducted from this point pool. Points are restored over time using the [leaky bucket algorithm](https://en.wikipedia.org/wiki/Leaky_bucket). If queries are reasonably sized, staying within these limits is straightforward. If you find it challenging, consider introducing delays between queries and caching common results. Error handling can also help regulate queries when throttled.

To [avoid rate limits](https://developer.getjobber.com/docs/using_jobbers_api/api_rate_limits/#avoiding-rate-limits), it's recommended to use pagination to collect data in batches, utilize cursor-based pagination for Relay-based queries, and avoid deeply nested queries whenever possible. If nested queries are needed, always apply pagination to connection types. Using these strategies will help you stay within the rate limits and ensure the smooth functioning of your app with Jobber's API.

### Handling API Errors

Handling API error scenarios is crucial for maintaining a robust and reliable interaction with Jobber's GraphQL API. Some of the errors you might encounter are **Type Nullability**, **Scopes & Permissions**, **App-level Authorization**, **Jobber Preventative Errors**, **Scalar Coercion**, **Rate-Limiting Errors** and **Inactive User Error**.
In the [Developer Center documentation](**url**) you can find an extended explanation of these errors and how to avoid them.


## Testing the application
During the application building process a Jobber Tester Account was created, linked to your app through the App Authorization flow and GraphQL queries/mutations tested in GraphiQL. Now is the [time to test the application](https://developer.getjobber.com/docs/building_your_app/testing_your_app) integrated with Jobber and prepare it for publication on the Jobber App Marketplace.

For your app to be published in Jobber's App Marketplace, there are typically 3 main steps to the testing process:

1. **Internal Testing by Developer**:
Thoroughly test your application internally before submitting it for review. Avoid involving existing Jobber customers in testing without coordinating with your Jobber developer representative and keep information about your app private until it's approved through Jobber's App Review process.
 
2. **App Review Testing by Jobber**:
After your internal testing, submit your app for review by Jobber who will verify your app's functionality and may request changes. Your App Marketplace listing details will also be reviewed and Jobber will perform various test cases, including checking proper functionality, data formatting, and data syncing with Jobber.
 
3. **Beta Testing with Actual Jobber Customers**:
Once approved by Jobber's App Review team, there's typically a 2-week beta testing period with selected Jobber users. Be prepared to make further changes based on feedback from these users.

By following these steps, you can ensure that your app is thoroughly tested, meets Jobber's requirements, and is ready for publication on the [Jobber App Marketplace](https://secure.getjobber.com/marketplace).


### Load testing the QBO sync app
Load testing is an important component in our application’s release cycle. It ensures that any new feature or application we’re releasing can handle the expected load rates without performance degradation or downtime. For our QBO Sync app, we needed to ensure it could handle anticipated growth in connected users over the next few years, in addition to the expected release volume.

We split our load testing into two phases: _Lightweight_ and _Robust_. The Lightweight phase aimed to quickly validate our app's ability to handle the load we expected to see, while our Robust phase would implement a tooling based approach that would provide us with more data over time. After investigating several tools we decided on building custom tooling for the lightweight phase.

Why would you build out custom tooling? We determined that building our own tool would mean writing less code, testing more of our system, and allowing us to gain more confidence in our approach.

We built a system that would trigger events inside of the main Jobber Online platform, which would then send webhooks to our app. By triggering events on test accounts inside of our main platform rather than mocking them, we were able to test a more complete picture of the application. This also meant that we didn't have to mock out our [webhook authenticity check](https://developer.getjobber.com/docs/using_jobbers_api/setting_up_webhooks/#verify-authenticity-of-the-webhook) which had posed a challenge in our investigation.

Having a purpose-built solution quickly available made the most sense for the needs of this project and helped us bridge the gap of evaluating and implementing a robust load testing tool.

### End-to-End testing the QBO sync app 

![A flow chart describing the end-to-end testing procedure for the QBO app. First, A seeding script script creates data in the Jobber platform which sends webhooks to the QBO sync app. This then responds by syncing that data into Quickbooks Online. Second, a testing script verifies that the expected data is present in quickbooks online. Lastly, a teardown script removes the seed data from Jobber. ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hiq721bg8zdwd13in51p.png)

The nature of our application being a passthrough for data between Jobber and Quickboooks Online meant we needed to come up with a novel solution for end-to-end testing. In the early stages of the project, our end to end testing was done manually by engineers following lengthy Test Case documents. One of the main goals of our end-to-end testing was to replace this manual testing with an automated, repeatable system. This would be both easier and faster to perform than manual testing, meaning that we could perform the tests more often and eventually find bugs earlier. 

Conventionally, end-to-end tests would be contained inside a single application. The trigger for a test would be some interaction in the UI, and the expected result would be a change in the interface of the same application. 

The trigger for most actions in our application are webhooks sent by Jobber, which are processed by our application, creating or editing data inside QuickBooks Online. This presented a challenge: both the triggers for our test events, and the results we needed to verify were outside of our application, not to mention being in separate systems themselves. We realized quickly that a conventional approach to end-to-end testing wouldn’t work for us, and we’d have to build our own system. 

To test our app’s workflow, we separated our testing framework into three components. 


1. **Data Seeding**: We built a [rake task](https://www.rubyguides.com/2019/02/ruby-rake/) that creates and edits data inside of Jobber, which in turn sends webhooks to our application. 

2. **Verification**: Using [Rspec](https://www.rubyguides.com/2018/07/rspec-tutorial/) as a test framework, we make requests to the Quickbooks API to verify the data that was created in the first step is in the correct state in QBO. These tests are triggered by a rake task and are run separately from our unit tests.


3. **Cleanup**: The QBO API doesn't allow for deletion of all of the models (i.e. inventory items) that we are testing, instead allowing developers to reset the entirety of the data in a sandbox. We then build another small rake task to wipe the test data created by the data seeding from Jobber. 

## Launching the application
After completing development and testing, it is time to publish the application so that Service Providers can start using it. The publishing process involves providing the listing details to appear in Jobber’s App Marketplace, having the Jobber team review the application, and setting up an entry point for users if your application has a settings page or if you want them to manage functionalities within your application.

### Providing listing details
Upon publication, the listing on the marketplace will be characterized by the utilization of the App name, Developer name, App description, Manage App URL (optional for a basic listing), Features or benefits, Gallery images, and App logo fields. The finalized appearance of the app will look like the following:

![A listing for an example app in the Jobber app marketplace. We can see the app logo, app name, description, features and benefits, and a button that the user click to connect the app to their Jobber account](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fsh6l6dgk7uk9c8uwava.png)

### Review process
When submitting your application, Jobber will prompt you to fulfill the [App Pre-Submission Checklist](https://forms.gle/etnZAQN8F6X62GyMA). For additional details on the app testing procedure, refer to the [Testing An App](https://forms.gle/etnZAQN8F6X62GyMA) section. To initiate a review of your app, simply click on the three dots action menu adjacent to your app within the Manage Apps view. If you have no plans to publish your app on Jobber's App Marketplace, please consult the Custom Integrations section.

During the review process, Jobber may request any changes necessary to best integrate with Jobber's ecosystem. Once the review is complete, the app will be ready for users. The review process can also be canceled at any time if desired.

### Adding a Manage App button
If the application includes a settings page or another page to manage functionalities, you can leverage the Manage App URL field in our Developer Center. This allows you to unveil a new button for Jobber admin users directly from the App Marketplace listing. The button will be visible exclusively to Jobber admin users who are exploring your App Marketplace listing post their Jobber account is successfully linked to your application. More information on the [Developer Center](https://developer.getjobber.com/docs/publishing_your_app/manage_app_button/).

## Summary 
Building and launching an application using Jobber’s platform is straightforward and the Developer Center provides you with all the information you need.

In the third and final post, we will discuss the challenges we encountered, share some best practices for building an application on Jobber's platform, delve into the lessons learned, highlight significant successes, and outline our future plans.

--- 

## About Jobber
Our awesome Jobber technology teams span across Payments, Infrastructure, AI/ML, Business Workflows & Communications. We work on cutting edge & modern tech stacks using React, React Native, Ruby on Rails, & GraphQL.

If you want to be a part of a collaborative work culture, help small home service businesses scale and create a positive impact on our communities, then visit our [careers](https://getjobber.com/about/careers?utm_source=devto&utm_medium=social&utm_campaign=eng_blog) site to learn more!


--- 
_A post by Christian do Prado Silva, Diogo Gallo, and Christian Ellinger_