Git Product home page Git Product logo

api-nodejs-sdk's Introduction

FreshBooks NodeJS SDK

The FreshBooks NodeJS SDK is a collection of single-purpose packages designed to easily build FreshBooks apps. Each package delivers part of the FreshBooks REST API, so that you can choose the packages that fit your needs.

Package What it's for
@freshbooks/api Get/set data from FreshBooks using the REST API.
@freshbooks/events Register/listen for incoming events via webhooks.
@freshbooks/app Pre-configured ExpressJS app. Includes authentication via PassportJS.

Installation

Use your favorite package manager to install any of the packages and save to your package.json:

$ npm install @freshbooks/api @freshbooks/events @freshbooks/app

# Or, if you prefer yarn
$ yarn add @freshbooks/api @freshbooks/events @freshbooks/app

Usage

@freshbooks/api

Your app will interact with the REST API using the Client object, available from the @freshbooks/api package. The client is instantiated with a valid OAuth token, which is used throughout the lifetime of the client to make API calls.

Configuring the API client

import { Client } from '@freshbooks/api'

// Get token from authentication or configuration
const token = process.env.FRESHBOOKS_TOKEN

// Instantiate new FreshBooks API client
const client = new Client(token)

Get/set data from REST API

All REST API methods return a response in the shape of:

{
  ok: boolean
  data?: T // model type of result
  error?: Error
}

Example API client call:

try {
	// Get the current user
	const { data } = await client.users.me()

	console.log(`Hello, ${data.id}`)
} catch ({ code, message }) {
	// Handle error if API call failed
	console.error(`Error fetching user: ${code} - ${message}`)
}

Building custom queries

If an endpoint supports searching or custom inclusions via query parameters, these parameters can be specified using a QueryBuilderType:

type QueryBuilderType = IncludesQueryBuilder | SearchQueryBuilder

An appropriate method on the API client will support an array of builders:

public readonly invoices = {
  list: (accountId: string, queryBuilders?: QueryBuilderType[]) => Promise<Result<{
      invoices: Invoice[];
      pages: Pagination;
  }>>;
}

The SearchQueryBuilder supports the patterns: Equals, In, Like and Between.

Example API client call with SearchQueryBuilder:

//create and populate SearchQueryBuilder
const searchQueryBuilder = new SearchQueryBuilder()
	.like('address', '200 King Street')
	.between('date', { min: new Date('2010-05-06'), max: new Date('2019-11-10') })

try {
	// Get invoices matching search query
	const { data } = await client.invoices.list('xZNQ1X', [searchQueryBuilder])

	console.log('Invoices: ', data)
} catch ({ code, message }) {
	// Handle error if API call failed
	console.error(`Error fetching user: ${code} - ${message}`)
}

The IncludesQueryBuilder simply requires the name of the key to be included.

Example API client call with IncludesQueryBuilder:

//create and populate IncludesQueryBuilder
const includesQueryBuilder = new IncludesQueryBuilder().includes('lines')

try {
	// Get invoices with included line items
	const { data } = await client.invoices.list('xZNQ1X', [includesQueryBuilder])

	console.log('Invoices: ', data)
} catch ({ code, message }) {
	// Handle error if API call failed
	console.error(`Error fetching user: ${code} - ${message}`)
}
Optional fields

Optional fields are specified in the API data model as optional using Typescript's ? operator, as well as marked as Nullable<T>, where T is the type of value, and Nullable is a type definition to allow null values.

// create a user model with required fields. set other fields as undefined
const user: User = {
  id: '123',
  firstName: 'Johnny',
  lastName: 'Appleseed'
}

// explicity set an optional field
user.phoneNumbers = [
  {
    title: 'Home',
    number: '555-555-5555'
  }
]

// explicitly unset an optional field
user.phoneNumbers = null
Errors

If an API error occurs, the response object contains an error object, with the following shape:

{
  code: string
  message?: string
}
Pagination

If the endpoint is enabled for pagination, the response data object contains the response model and a pages property, with the following shape:

{
	page: number
	pages: number
	total: number
	size: number
}

Example request with pagination:

// Get list of invoices for account
const { invoices, pages } = await client.invoices.list('xZNQ1X')

// Print invoices
invoices.map(invoice => console.log(JSON.stringify(invoice)))

// Print pagination
console.log(`Page ${pages.page} of ${pages.total} pages`)
console.log(`Showing ${pages.size} per page`)
console.log(`${pages.size} total invoices`)

@freshbooks/app

The FreshBooks SDK provides a pre-configured ExpressJS app. This app provides OAuth2 authentication flow, a PassportJS middleware for authenticating requests, and session middleware to retrieve tokens for a session.

Using the ExpressJS app

Setting up the ExpressJS app requires a FreshBooks client__id and client_secret, as well as a callback URL to receive user authentication and refresh tokens. Once configured, routes can be configured as in any other ExpressJS app.

import { Client } from '@freshbooks/api'
import createApp from '@freshbooks/app'

const CLIENT_ID = process.env.CLIENT_ID
const CLIENT_SECRET = process.env.CLIENT_SECRET
const CALLBACK_URL = process.env.CALLBACK_URL

const app = createApp(CLIENT_ID, CLIENT_SECRET, CALLBACK)

// set up callback route
app.get('/auth/freshbooks/redirect', passport.authorize('freshbooks')

// set up an authenticated route
app.get('/settings', passport.authorize('freshbooks'), async (req, res) => {
  // get an API client
  const { token } = req.user
  const client = new Client(token)

  // fetch the current user
  try {
    const { data } = await client.users.me()
    res.send(data.id)
  } catch ({ code, message }) {
    res.status(500, `Error - ${code}: ${message}`)
  }
})

api-nodejs-sdk's People

Contributors

alexkung1 avatar bhaskarmurthy avatar nedu avatar nicholasyee avatar ryanmarr avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.