Commerce Layer JS SDK
A JavaScript Library wrapper that makes it quick and easy to interact with the Commerce Layer API.
What is Commerce Layer?
Commerce Layer is a multi-market commerce API and order management system that lets you add global shopping capabilities to any website, mobile app, chatbot, wearable, voice, or IoT device, with ease. Compose your stack with the best-of-breed tools you already mastered and love. Make any experience shoppable, anywhere, through a blazing-fast, enterprise-grade, and secure API.
Table of contents
Getting started
To get started with Commerce Layer JS SDK you need to install it, get the credentials that will allow you to perform your API calls, and import the SDK into your application's code. The sections below explain how to achieve this.
If you want, you can also read this tutorial from Commerce Layer's blog.
Installation
Commerce Layer JS SDK is available as an npm and yarn package that you can install with the command below:
npm install @commercelayer/sdk
// or
yarn add @commercelayer/sdk
Authentication
All requests to Commerce Layer API must be authenticated with an OAuth2 bearer token. Hence, before starting to use this SDK you need to get a valid access token. Kindly check our documentation for more information about the available authorization flows.
Feel free to use Commerce Layer JS Auth, a JavaScript library that helps you wrap our authentication API.
Import
You can use the ES6 default import with the SDK like so:
import CommerceLayer from '@commercelayer/sdk'
const cl = CommerceLayer({
organization: 'your-organization-slug',
accessToken: 'your-access-token'
})
Options
When instantiating a new SDK client you can pass some options to initialize it:
{
organization: string
accessToken: string
timeout?: number
headers?: RequestHeaders
userAgent?: string
fetch?: Fetch
refreshToken?: RefreshToken
}
Same options can be changed after SDK initialization or passed at runtime while executing an API call:
const options = { ... }
const cl = CommerceLayer(options)
cl.config(options)
cl.customers.list({}, options)
SDK usage
The JavaScript SDK is a wrapper around Commerce Layer API which means you would still be making API requests but with a different syntax. For now, we don't have comprehensive SDK documentation for every single resource our API supports (about 400+ endpoints), hence you will need to rely on our comprehensive API Reference as you go about using this SDK. So for example, if you want to create an order, take a look at the Order object or the Create an order documentation to see the required attributes and/or relationships. The same goes for every other supported resource.
To show you how things work, we will use the SKUs and Shipping Categories resource in the following examples. The code snippets below show how to use the SDK when performing the standard CRUD operations provided by our REST API. Kindly check our API reference for the complete list of available resources and their attributes.
Create
How to create an SKU
const shippingCategories = await cl.shipping_categories.list({ filters: { name_eq: 'Merchandising' } })
const attributes = {
code: 'TSHIRTMM000000FFFFFFXL',
name: 'Black Men T-shirt with White Logo (XL)',
description: "A very beautiful and cozy mens t-shirt",
weight: "500",
unit_of_weight: "gr"
shipping_category: cl.shipping_categories.relationship(shippingCategories[0].id),
}
const newSku = await cl.skus.create(attributes)
ℹ️ Check our API reference for more information on how to create an SKU.
Retrieve / List
How to fetch a single SKU
const sku = await cl.skus.retrieve('BxAkSVqKEn')
const sku = await cl.skus.list({ filters: { code_eq: 'TSHIRTMM000000FFFFFFXLXX' } })
const sku = (await cl.skus.list()).first()
const sku = (await cl.skus.list()).last()
ℹ️ Check our API reference for more information on how to retrieve an SKU.
How to fetch a collection of SKUs
const skus = await cl.skus.list()
When fetching a collection of resources you can leverage the meta
attribute to get its meta
information like so:
const skus = await cl.skus.list()
const meta = skus.meta
ℹ️ Check our API reference for more information on how to list all SKUs.
How to fetch a collection of SKUs and sort the results
const skus = await cl.skus.list({ sort: { created_at: 'asc' } })
const skus = await cl.skus.list({ sort: { created_at: 'desc' } })
ℹ️ Check our API reference for more information on how to sort results.
How to fetch a collection of SKUs and include associations
const skus = await cl.skus.list({ include: [ 'prices' ] })
const skus = await cl.skus.list({ include: [ 'stock_items' ] })
ℹ️ Check our API reference for more information on how to include associations.
How to fetch a collection of SKUs and return specific fields (sparse fieldsets)
const skus = await cl.skus.list({ fields: { skus: [ 'name', 'metadata' ] } })
const skus = await cl.skus.list({ include: [ 'prices' ], fields: { prices: [ 'currency_code', 'formatted_amount' ] } })
ℹ️ Check our API reference for more information on how to use sparse fieldsets.
How to fetch a collection of SKUs and filter data
const skus = await cl.skus.list({ filters: { code_start: 'TSHIRT' } })
const skus = await cl.skus.list({ filters: { code_end: 'XLXX' } })
const skus = await cl.skus.list({ filters: { name_cont: 'White Logo' } })
const skus = await cl.skus.list({ filters: { created_at_gt: '2018-01-01', created_at_lt: '2018-01-31'} })
const skus = await cl.skus.list({ filters: { updated_at_or_created_at_gt: '2019-10-10' } })
const skus = await cl.skus.list({ filters: { name_cont: 'Black', shipping_category_name_start: 'MERCH'} })
ℹ️ Check our API reference for more information on how to filter data.
How to paginate a collection of SKUs
When you fetch a collection of resources, you get paginated results. You can request specific pages or items in a page like so:
const skus = await cl.skus.list({ pageNumber: 3, pageSize: 5 })
const skuCount = skus.meta.recordCount
const pageCount = skus.meta.pageCount
PS: the default page number is 1, the default page size is 10, and the maximum page size allowed is 25.
ℹ️ Check our API reference for more information on how pagination works.
How to iterate through a collection of SKUs
To execute a function for every item of a collection, use the map()
method like so:
const skus = await cl.skus.list()
skus.map(p => console.log('Product: ' + p.name + ' - Code: ' + p.code))
How to fetch resource relationships
Many resources have relationships with other resources and instead of including these associations as seen above, you can fetch them directly. This way, in the case of 1-to-N relationships, you can filter or sort the resulting collection as standard resources.
const billingAddress = await cl.orders.billing_address('xYZkjABcde')
const orders = await cl.customers.orders('XyzKjAbCDe', { fields: ['status', 'number'] })
In general:
- An API endpoint like
/api/customers
or /api/customers/<customerId>
translates to cl.customers
or cl.customers('<customerId>')
with the SDK. - 1-to-1 relationship API endpoints like
/api/orders/<orderId>/shipping_address
translates to cl.orders('<orderId>', { include: ['shipping_address'] }}
with the SDK. - 1-to-N relationship API endpoints like
/api/customers/<customerId>?include=orders
or /api/customers/<customerId>/orders
translates to cl.customers.retrieve('<customerId>', { include: ['orders'] })
or cl.customers.orders('<customerId>')
with the SDK.
ℹ️ Check our API reference for more information on how to fetch relationships.
How to count resources
Many times you simply need to count how many resources exist with
certain characteristics. You can then call the special count
function passing a filter to get as result the total number of
resources.
const placedOrders = await cl.orders.count({ filters: { status_eq: 'placed' } })
Update
How to update an existing SKU
const sku = {
id: 'xYZkjABcde',
description: 'Updated description...',
imageUrl: 'https://img.yourdomain.com/skus/new-image.png'
}
cl.skus.update(sku)
ℹ️ Check our API reference for more information on how to update an SKU.
Delete
How to delete an existing SKU
cl.skus.delete('xYZkjABcde')
ℹ️ Check our API reference for more information on how to delete an SKU.
Overriding credentials
If needed, Commerce Layer JS SDK lets you change the client configuration and set it at a request level. To do that, just use the config()
method or pass the options
parameter and authenticate the API call with the desired credentials:
cl.config({ organization: 'you-organization-slug', accessToken: 'your-access-token' })
const skus = await cl.skus.list()
or
cl.skus.list({}, { organization: 'you-organization-slug', accessToken: 'your-access-token' })
Handling validation errors
Commerce Layer API returns specific errors (with extra information) on each attribute of a single resource. You can inspect them to properly handle validation errors (if any). To do that, use the errors
attribute of the catched error:
const attributes = { code: 'TSHIRTMM000000FFFFFFXL', name: '' }
const newSku = await cl.skus.create(attributes).catch(error => console.log(error.errors))
ℹ️ Check our API reference for more information about the errors returned by the API.
Using interceptors
You can use interceptors to intercept SDK messages and modify them on the fly before the request is sent to the API or before the response is parsed and returned by the client. You can also access the error object before it is thrown by the SDK.
Interceptors are special functions that are able to handle SDK messages and return a (eventually) modified version of them for use by the client.
const requestInterceptor = (request: RequestObj): RequestObj => {
console.log(request)
return request
}
const responseInterceptor = (response: ResponseObj): ResponseObj => {
console.log(response)
return response
}
const errorInterceptor = (error: ErrorObj): ErrorObj => {
console.log(error)
return error
}
Here an example of how to use them:
cl.addRequestInterceptor(requestInterceptor)
cl.addResponseInterceptor(responseInterceptor, errorInterceptor)
const customers = await cl.customers.list()
cl.removeInterceptors()
Raw Response Reader
The RawResponseReader is a special interceptor that allows to catch the original message coming frome the API before it is parsed and translated in SDK objects.
const rrr = cl.addRawResponseReader({ headers: true })
const customers = await cl.customers.list()
cl.removeRawResponseReader()
console.log(rrr.rawResponse)
console.log(rrr.headers)
Refreshing access token
It is possible that you are using an access token that is about to expire especially if it has been used for many API calls.
In this case you can define a special function that takes care of refreshing the token when a call fails because it has expired.
async function myRefreshTokenFunction(espiredToken: string): Promise<string> {
return (await getAccessToken()).accessToken
}
cl.config({ refreshToken: myRefreshTokenFunction })
const newToken = cl.currentAccessToken
Contributors guide
-
Fork this repository (learn how to do this here).
-
Clone the forked repository like so:
git clone https://github.com/<your username>/commercelayer-sdk.git && cd commercelayer-sdk
-
Make your changes and create a pull request (learn how to do this).
-
Someone will attend to your pull request and provide some feedback.
Need help?
-
Join Commerce Layer's Slack community.
-
Create an issue in this repository.
-
Ping us on Twitter.
License
This repository is published under the MIT license.