Skip to content

Latest commit

 

History

History
809 lines (723 loc) · 22 KB

README.md

File metadata and controls

809 lines (723 loc) · 22 KB

Shopify API Node.js

Version npm Build Status Coverage Status

Shopify API bindings for Node.js.

Installation:

$ npm install --save shopify-api-node

API

This module exports a constructor function which takes an options object.

Shopify(options)

Creates a new Shopify instance.

Arguments

  • options - Required - A plain JavaScript object that contains the configuration options.

Options

  • shopName - Required - A string that specifies the shop name. The shop's "myshopify.com" domain is also accepted.
  • apiKey - Required for private apps - A string that specifies the API key of the app. This option must be used in conjunction with the password option and is mutually exclusive with the accessToken option.
  • password - Required for private apps - A string that specifies the private app password. This option must be used in conjunction with the apiKey option and is mutually exclusive with the accessToken option.
  • accessToken - Required for public apps - A string representing the permanent OAuth 2.0 access token. This option is mutually exclusive with the apiKey and password options. If you are looking for a premade solution to obtain an access token, take a look at the shopify-token module.
  • agent - Optional - An object that is passed as the agent option to got. This allows to use a proxy server. See Got documentation for more details.
  • apiVersion - Optional - A string to specify the Shopify API version to use for requests. Defaults to the oldest supported stable version.
  • autoLimit - Optional - This option allows you to regulate the request rate in order to avoid hitting the rate limit. Requests are limited using the token bucket algorithm. Accepted values are a boolean or a plain JavaScript object. When using an object, the calls property and the interval property specify the refill rate and the bucketSize property the bucket size. For example { calls: 2, interval: 1000, bucketSize: 35 } specifies a limit of 2 requests per second with a burst of 35 requests. When set to true requests are limited as specified in the above example. Defaults to false. Mutually exclusive with the maxRetries option.
  • hooks - Optional - A list of got request hooks to attach to all outgoing requests, like beforeRetry, afterResponse, etc. Hooks should be provided in the same format that Got expects them and will receive the same arguments Got passes unchanged.
  • maxRetries - Optional - The number of times to attempt to make the request to Shopify before giving up. Defaults to 0, which means no automatic retries. If set to a value greater than 0, shopify-api-node will make up to that many retries. shopify-api-node will respect the Retry-After header for requests to the REST API, and the throttled cost data for requests to the GraphQL API, and retry the request after that time has elapsed. Mutually exclusive with the autoLimit option.
  • parseJson - Optional - The function used to parse JSON. The function is passed a single argument. This option allows the use of a custom JSON parser that might be needed to properly handle long integer IDs. Defaults to JSON.parse().
  • presentmentPrices - Optional - Whether to include the header to pull presentment prices for products. Defaults to false.
  • stringifyJson - Optional - The function used to serialize to JSON. The function is passed a single argument. This option allows the use of a custom JSON serializer that might be needed to properly handle long integer IDs. Defaults to JSON.stringify().
  • timeout - Optional - The number of milliseconds before the request times out. If the request takes longer than timeout, it will be aborted. Defaults to 60000, or 1 minute.

Return value

A Shopify instance.

Exceptions

Throws an Error exception if the required options are missing.

Example

const Shopify = require('shopify-api-node');

const shopify = new Shopify({
  shopName: 'your-shop-name',
  apiKey: 'your-api-key',
  password: 'your-app-password'
});

shopify.callLimits

The callLimits property allows you to monitor the API call limit. The value is an object like this:

{
  remaining: 30,
  current: 10,
  max: 40
}

Values start at undefined and are updated every time a request is made. After every update the callLimits event is emitted with the updated limits as argument.

shopify.on('callLimits', (limits) => console.log(limits));

When using the GraphQL API, a different property is used to track the API call limit: callGraphqlLimits.

Keep in mind that the autoLimit option is ignored while using GraphQL API.

shopify.on('callGraphqlLimits', (limits) => console.log(limits));

Resources

Every resource is accessed via your shopify instance:

const shopify = new Shopify({
  shopName: 'your-shop-name',
  accessToken: 'your-oauth-token'
});

// shopify.<resource_name>.<method_name>

Each method returns a Promise that resolves with the result:

shopify.order
  .list({ limit: 5 })
  .then((orders) => console.log(orders))
  .catch((err) => console.error(err));

The Shopify API requires that you send a valid JSON string in the request body including the name of the resource. For example, the request body to create a country should be:

{
  "country": {
    "code": "FR",
    "tax": 0.25
  }
}

When using shopify-api-node you don't have to specify the full object but only the nested one as the module automatically wraps the provided data. Using the above example this translates to:

shopify.country
  .create({ code: 'FR', tax: 0.25 })
  .then((country) => console.log(country))
  .catch((err) => console.error(err));

Similarly, the Shopify API includes the resource name in the JSON string that is returned in the response body:

{
  "country": {
    "id": 1070231510,
    "name": "France",
    "tax": 0.2,
    "code": "FR",
    "tax_name": "TVA",
    "provinces": []
  }
}

shopify-api-node automatically unwraps the parsed object and returns:

{
  id: 1070231510,
  name: 'France',
  tax: 0.2,
  code: 'FR',
  tax_name: 'TVA',
  provinces: []
}

This behavior is valid for all resources.

Metafields

Shopify allows for adding metafields to various resources. You can use the owner_resource and owner_id properties to work with metafields that belong to a particular resource as shown in the examples below.

Get metafields that belong to a product:

shopify.metafield
  .list({
    metafield: { owner_resource: 'product', owner_id: 632910392 }
  })
  .then(
    (metafields) => console.log(metafields),
    (err) => console.error(err)
  );

Create a new metafield for a product:

shopify.metafield
  .create({
    key: 'warehouse',
    value: 25,
    type: 'integer',
    namespace: 'inventory',
    owner_resource: 'product',
    owner_id: 632910392
  })
  .then(
    (metafield) => console.log(metafield),
    (err) => console.error(err)
  );

Pagination

Pagination in API version 2019-07 and above can be done as shown in the following example:

(async () => {
  let params = { limit: 10 };

  do {
    const products = await shopify.product.list(params);

    console.log(products);

    params = products.nextPageParameters;
  } while (params !== undefined);
})().catch(console.error);

Each set of results may have the nextPageParameters and previousPageParameters properties. These properties specify respectively the parameters needed to fetch the next and previous page of results.

This feature is only available on version 2.24.0 and above.

Shopify rate limit avoidance

shopify-api-node has two optional mechanisms for avoiding requests failing with 429 Rate Limit Exceeded errors from Shopify.

The autoLimit option implements a client side leaky bucket algorithm for delaying requests until Shopify is likely to accept them. When autoLimit is on, each Shopify instance will track how many requests have been made, and delay sending subsequent requests if the rate limit has been exceeded. autoLimit is very efficient because it almost entirely avoids sending requests which will return 429 errors, but, it does not coordinate between multiple Shopify instances or across multiple processes. If you're using shopify-api-node in many different processes, autoLimit will not correctly avoid 429 errors.

The maxRetries option implements a retry based strategy for getting requests to Shopify, where when a 429 error occurs, the request is automatically retried after waiting. Shopify usually replies with a Retry-After header indicating to the client when the rate limit is available, and so shopify-api-node will wait that long before retrying. If you are using shopify-api-node in many different processes, they will all be competing to use the same rate limit shopify enforces, so there is no guarantee that retrying after the Retry-After header delay will work. It is recommended to set maxRetries to a high value like 10 if you are making many concurrent requests in many processes to ensure each request is retried for long enough to succeed.

autoLimit and maxRetries can't be used simultaneously. Both are off by default.

Available resources and methods

  • accessScope
    • list()
  • apiPermission
    • delete()
  • applicationCharge
    • activate(id[, params])
    • create(params)
    • get(id[, params])
    • list([params])
  • applicationCredit
    • create(params)
    • get(id[, params])
    • list([params])
  • article
    • authors()
    • count(blogId[, params])
    • create(blogId, params)
    • delete(blogId, id)
    • get(blogId, id[, params])
    • list(blogId[, params])
    • tags([blogId][, params])
    • update(blogId, id, params)
  • asset
    • create(themeId, params)
    • delete(themeId, params)
    • get(themeId, params)
    • list(themeId[, params])
    • update(themeId, params)
  • balance
    • list()
    • transactions([params])
  • blog
    • count()
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • cancellationRequest
    • accept(fulfillmentOrderId[, message])
    • create(fulfillmentOrderId[, message])
    • reject(fulfillmentOrderId[, message])
  • carrierService
    • create(params)
    • delete(id)
    • get(id)
    • list()
    • update(id, params)
  • checkout
    • complete(token)
    • count([params])
    • create(params)
    • get(token)
    • list([params])
    • shippingRates(token)
    • update(token, params)
  • collect
    • count([params])
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
  • collection
    • get(id[, params])
    • products(id[, params])
  • collectionListing
    • get(id)
    • list([params])
    • productIds(id[, params])
  • comment
    • approve(id)
    • count([params])
    • create(params)
    • get(id[, params])
    • list([params])
    • notSpam(id)
    • remove(id)
    • restore(id)
    • spam(id)
    • update(id, params)
  • country
    • count()
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • currency
    • list()
  • customCollection
    • count([params])
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • customer
    • accountActivationUrl(id)
    • count([params])
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • orders(id[, params])
    • search(params)
    • sendInvite(id[, params])
    • update(id, params)
  • customerAddress
    • create(customerId, params)
    • default(customerId, id)
    • delete(customerId, id)
    • get(customerId, id)
    • list(customerId[, params])
    • set(customerId, params)
    • update(customerId, id, params)
  • customerSavedSearch
    • count([params])
    • create(params)
    • customers(id[, params])
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • deprecatedApiCall
    • list()
  • discountCode
    • create(priceRuleId, params)
    • delete(priceRuleId, id)
    • get(priceRuleId, id)
    • list(priceRuleId)
    • lookup(params)
    • update(priceRuleId, id, params)
  • discountCodeCreationJob
    • create(priceRuleId, params)
    • discountCodes(priceRuleId, id)
    • get(priceRuleId, id)
  • dispute
    • get(id)
    • list([params])
  • disputeEvidence
    • get(disputeId)
    • update(disputeId, params)
  • disputeFileUpload
    • create(disputeId, params)
    • delete(disputeId, id)
  • draftOrder
    • complete(id[, params])
    • count()
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • sendInvoice(id[, params])
    • update(id, params)
  • event
    • count([params])
    • get(id[, params])
    • list([params])
  • fulfillment
    • cancel(orderId, id)
    • cancelV2(id)
    • complete(orderId, id)
    • count(orderId[, params)
    • create(orderId, params)
    • createV2(params)
    • get(orderId, id[, params])
    • list(orderId[, params])
    • open(orderId, id)
    • update(orderId, id, params)
    • updateTracking(id, params)
  • fulfillmentEvent
    • create(orderId, fulfillmentId, params)
    • delete(orderId, fulfillmentId, id)
    • get(orderId, fulfillmentId, id)
    • list(orderId, fulfillmentId[, params])
    • update(orderId, fulfillmentId, id, params)
  • fulfillmentOrder
    • cancel(id, params)
    • close(id[, message])
    • get(id)
    • list([params])
    • locationsForMove(id)
    • move(id, locationId)
    • setFulfillmentOrdersDeadline(params)
    • fulfillments(id)
  • fulfillmentRequest
    • accept(fulfillmentOrderId[, message])
    • create(fulfillmentOrderId, params)
    • reject(fulfillmentOrderId[, message])
  • fulfillmentService
    • create(params)
    • delete(id)
    • get(id)
    • list([params])
    • update(id, params)
  • giftCard
    • count([params])
    • create(params)
    • disable(id)
    • get(id)
    • list([params])
    • search(params)
    • update(id, params)
  • giftCardAdjustment
    • create(giftCardId, params)
    • get(giftCardId, id)
    • list(giftCardId)
  • inventoryItem
    • get(id)
    • list(params)
    • update(id, params)
  • inventoryLevel
    • adjust(params)
    • connect(params)
    • delete(params)
    • list(params)
    • set(params)
  • location
    • count
    • get(id)
    • inventoryLevels(id[, params])
    • list()
  • marketingEvent
    • count()
    • create(params)
    • delete(id)
    • get(id)
    • list([params])
    • update(id, params)
    • engagements(id, params)
  • metafield
    • count([params])
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • order
    • cancel(id[, params])
    • close(id)
    • count([params])
    • create(params)
    • delete(id)
    • fulfillmentOrders(id)
    • get(id[, params])
    • list([params])
    • open(id)
    • update(id, params)
  • orderRisk
    • create(orderId, params)
    • delete(orderId, id)
    • get(orderId, id)
    • list(orderId)
    • update(orderId, id, params)
  • page
    • count([params])
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • payment
    • count(checkoutToken)
    • create(checkoutToken, params)
    • get(checkoutToken, id)
    • list(checkoutToken)
  • payout
    • get(id)
    • list([params])
  • policy
    • list([params])
  • priceRule
    • create(params)
    • delete(id)
    • get(id)
    • list([params])
    • update(id, params)
  • product
    • count([params])
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • productImage
    • count(productId[, params])
    • create(productId, params)
    • delete(productId, id)
    • get(productId, id[, params])
    • list(productId[, params])
    • update(productId, id, params)
  • productListing
    • count()
    • create(productId[, params])
    • delete(productId)
    • get(productId)
    • list([params])
    • productIds([params])
  • productResourceFeedback
    • create(productId[, params])
    • list(productId)
  • productVariant
    • count(productId)
    • create(productId, params)
    • delete(productId, id)
    • get(id[, params])
    • list(productId[, params])
    • update(id, params)
  • province
    • count(countryId[, params])
    • get(countryId, id[, params])
    • list(countryId[, params])
    • update(countryId, id, params)
  • recurringApplicationCharge
    • activate(id, params)
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • customize(id, params)
  • redirect
    • count([params])
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • refund
    • calculate(orderId, params)
    • create(orderId, params)
    • get(orderId, id[, params])
    • list(orderId[, params])
  • report
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • resourceFeedback
    • create(params)
    • list()
  • scriptTag
    • count([params])
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • shippingZone
    • list([params])
  • shop
    • get([params])
  • smartCollection
    • count([params])
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • order(id, params)
    • products(id[, params])
    • update(id, params)
  • storefrontAccessToken
    • create(params)
    • delete(id)
    • list()
  • tenderTransaction
    • list([params])
  • theme
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)
  • transaction
    • count(orderId)
    • create(orderId, params)
    • get(orderId, id[, params])
    • list(orderId[, params])
  • usageCharge
    • create(recurringApplicationChargeId, params)
    • get(recurringApplicationChargeId, id[, params])
    • list(recurringApplicationChargeId[, params])
  • user
    • current()
    • get(id)
    • list()
  • webhook
    • count([params])
    • create(params)
    • delete(id)
    • get(id[, params])
    • list([params])
    • update(id, params)

where params is a plain JavaScript object. See the Rest Admin API reference for parameters details.

GraphQL

The shopify instance also allows to use the GraphQL API through the graphql method, which returns a promise that resolves with the result data:

const shopify = new Shopify({
  shopName: 'your-shop-name',
  accessToken: 'your-oauth-token'
});

const query = `{
  customers(first: 5) {
    edges {
      node {
        displayName
        totalSpent
      }
    }
  }
}`;

shopify
  .graphql(query)
  .then((customers) => console.log(customers))
  .catch((err) => console.error(err));

Hooks

shopify-api-node supports being passed hooks which are called by got (the underlying HTTP library) during the request lifecycle.

For example, we can log every error that is encountered when using the maxRetries option:

const shopify = new Shopify({
  shopName: 'your-shop-name',
  accessToken: 'your-oauth-token',
  maxRetries: 3,
  // Pass the `beforeRetry` hook down to Got.
  hooks: {
    beforeRetry: [(options, error, retryCount) => console.error(error)]
  }
});

For more information on the available got hooks, see the got v11 hooks documentation.

Become a master of the Shopify ecosystem by:

Use Polaris, a React powered Frontend Framework which mimics the Shopify merchant admin:

Polaris

Shopify Apps already using Shopify API node:

(add yours!)

Supported by:

MONEI

License

MIT