Home

cpb-storage-api 0.2.3

CPB-API-STORAGE v0.1.1

REST API provides the facilities for the products data operations on Google Cloud Storage (GCS)

Table of contents


CUSTOM PRODUCT BUILDER BACKEND STORAGE REST API SERVICE

Overview

The service uses standard ExpressJS and Google Cloud NodeJS API Libraries.
It provides the REST API for the Cloud Storage operations for the CPB Backend services.

Requirements

There are no requirements besides the nodejs v12-16.
it should be able to run on any platform.
Currently only nodejs v16 have been tested on OSX.
The nodejs runtime is set to require v16 in the package.json file in the project root.

Documentation

The jsdoc and apidoc (apidoc-markdown) libraries are used for the documentation.
The internal documentation is in doc dir in the project root. It is not checked into git.

The documentation consists of two components:

  • The internal modules docs - the doc/cpb-storage-api/${version} dir in the jsdoc format.
  • The API docs (README.md in the project root ) - apidoc format rendered as markdown (apidoc-md) due to the
    Gitlabs' restriction for rendering the html files. The Gitlab Pages are required for the html rendering. This doc
    content is also included into the module documentation.

The documentation is generated during the development install process (npm run installDev).
It is also can be regenerated at any time by invoking the npm run jsdoc command.
The file INSTALL.md (this file) is prepended to the apidoc output README.md and included into the resulting jsdocs.

### install DEVELOPMENT dependencies
npm run installDev
### generate API documentation
npm run apidoc
### generate complete documentation (internal and api docs)
npm run jsdoc
Structure

This project uses Node Module structure in order to use the import pragmas and for the code isolation.
The modules source code is in the src directory. Each top-level folder under the src root corresponds to its
own module with the naming convention of cpb-{dirname}. Each module's description and dependencies are stored
within its package.json file.

├── Dockerfile
├── INSTALL.md            # this file
├── README.md
├── datastore             # cloud datastore indexes
├── doc                   # generated documentation
├── index.js
├── node_modules
├── out                   # temp dir
├── package-lock.json
├── package.json
src
├── api                   # package:cpb-api
├── apidoc.json           # apidoc config
├── common                # package:cpb-common
├── storage               # package:cpb-storage
Installation

The installation scripts are defined within main package.json file.
For the server instance configuration the environment variables are used.

Environment Variables

  • BUCKET - Google Cloud Storage Bucket for operations. Defaults to custom-product-builder
  • PORT - Server listening port. Defaults to 8080
##### Development Mode
npm run installDev

##### Production Mode
npm install

##### Start Service with default settings
npm start

##### Override default settings
PORT=80 BUCKET=my_bucket npm start

##### Docker (Production)
docker build -t cpb-storage-api:dev .
docker run -p 80:8080 -t cpb-storage-api:dev

homevadimProjectsBuildateamcpb-storage-apiapiindex.js

GET ALL STORE INFORMATION

Back to top

GET /cpb/:shopIdOrShopName

Parameters - Parameter

Name Type Description
shopIdOrShopName String
  • Shopify shopID or CPB shopName

Query Parameters

Name Type Description
fetch String Rescan data if true or retrieve the existing cache from **${BUCKET}/${shopID}/cpb.json file (default)Default value: false
Allowed values: true,false
files String Include storage files (storage) into the output_Default value: false_
Allowed values: true,false
version String Include storage file versions (products.config.versions & storage.files.versions) into the output_Default value: false_
Allowed values: true,false
charges String Include Shopify Recurring Charges (charges) into the output. Currently only active charge is displayed_Default value: true_
Allowed values: true,false
shop String Include Shopify Shop data (shop) into the output.Included by default. If fetch flag is set it requests new shopData from Shopify_Default value: true_
Allowed values: true,false

ShopifyStore

[GET] /filestore list all shopify stores and top-level dirs for the bucket

Back to top

Contains Shopify Store IDs, dirs for the legacy app installs (*.myshopify.com), and miscellaneous dirs for the bucket defined at %ENV.BUCKET% at the server runtime or via app.set('bucket') in the src/api/index.js

GET /filestore

Query Parameters

Name Type Description
fetch String Rescan data if true or retrieve the existing index (default)Default value: false
Allowed values: true,false
files String Include loose files into the output_Default value: false_
Allowed values: true,false
misc String Include misc dirs into the output_Default value: false_
Allowed values: true,false
legacy String Include legacy dirs into the output (ones with the name of the shopify domain name)Default value: false
Allowed values: true,false

Examples

Get all stores with files and misc and legacy directories within the bucket::

curl localhost:8080/filestore | jq .

Get only filestore ids for the bucket

curl http://localhost:8080/store?files=1&fetch=0&legacy=0&misc=0

Success response

Success response - Success 200

Name Type Description
bucket String GCS Storage Bucket
ids Number[] Shopify Store ids
legacy String[] Storage dirs that are named by the filestore domain names
misc String[] Storage dirs that could not be identified as shopify data holders
files Object[] Loose files in the bucket root
files.name String Loose file name
files.versions Object[] File versions
files.versions.id String
files.versions.generation Integer
files.versions.isDeleted Boolean
files.versions.isCurrent Boolean
files.versions.size Integer File Version size
files.versions.url String File Version Download Link
files.versions.metadata Object File versions metadata
files.versions.metadata.md5Hash String
files.versions.metadata.crc32c String
files.versions.metadata.timeCreated Timestamp
files.versions.metadata.updated Timestamp
stats Object Counters for the data
stats.ids Number Number of Store ids
stats.legacy Number Number of the legacy dirs ( named by the filestore domain names)
stats.misc Number Number of unidentified dirs
stats.files Number Number of loose files
stats.deletedFiles Number Number of loose deleted files

Success response example

Success response example - all stores with files and misc and legacy directories within the bucket: Success-Response:

{
  "bucket": "custom-product-builder",
  "ids": [
    10003054628,
    10012622910,
    10025467982
  ],
  "misc": [
    "cpb-assets/",
    "custom-product-builder-stage/",
    "customproductbuilder/",
    "dev-test-shop/"
  ],
  "legacy": [
    "alpha-crystal-jewellery.myshopify.com/",
    "alpha-wraps.myshopify.com/",
    "alumepixalayof.myshopify.com/",
    "amasal.myshopify.com/"
  ],
  "files": [
  {
          "name": "64audio-5540496998550-J9gcVRJDZzGfeiSZc1ZZslq5.jpg",
          "versions": [
            {
            "id": "custom-product-builder/64audio-5540496998550-J9gcVRJDZzGfeiSZc1ZZslq5.jpg/1627414331517243",
            "generation": 1627414331517243,
            "metadata": {
               "md5Hash": "rBkJMvwCwAYY0QtuO4pYRA==",
               "crc32c": "CsVSMQ==",
               "timeCreated": "2021-07-27T19:32:11.547Z",
               "updated": "2021-07-27T19:32:11.547Z"
            },
          "isDeleted": false,
          "isCurrent": true,
          "size": 52167,
          "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/64audio-5540496998550-J9gcVRJDZzGfeiSZc1ZZslq5.jpg?generation=1627414331517243&alt=media"
          }
          ],
            "isDeleted": false,
            "currentFileSize": 52167,
            "generation": 1627414331517243,
            "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/64audio-5540496998550-J9gcVRJDZzGfeiSZc1ZZslq5.jpg?generation=1627414331517243&alt=media",
            "totalSize": 52167,
            "previousFileVersionsCount": 0,
            "previousFileVersionsSize": 0
      }
  ],
  "deletedFiles": [],
  "stats": {
  "ids": 7177,
  "legacy": 66,
  "misc": 42,
  "files": 1005,
  "deletedFiles": 0
}
  "debug":{
     "params": {},
     "query": {}
  }
}

Success response example - Get only filestore ids for the bucket: Success-Response:

{
  "bucket": "custom-product-builder",
  "ids": [
    10003054628,
    10012622910,
    10025467982,
    10039296064
  ],
  "stats": {
    "ids": 7183,
    "legacy": 66,
    "misc": 42,
    "files": 1033,
    "deletedFiles": 0
  },
  "debug": {
    "bucket": "custom-product-builder",
    "fetch": false,
    "versions": false,
    "showFiles": true,
    "misc": false,
    "legacy": false,
    "request": {
      "query": {
        "files": "1",
        "fetch": "0",
        "legacy": "0",
        "misc": "0"
      },
      "params": { }
    },
    "timestamp": "2021-12-19T13:17:46.382Z"
  }
}

[GET] /filestore/:shopIdOrName SHOPIFY STORE PRODUCTS AND FILES

Back to top

Get the filestore data for the given :shop_id with the summarized sizes and ShopifyProductId

GET /filestore/:shopIdOrName

Parameters - Parameter

Name Type Description
shop_id Number Shopify Store Id. That corresponds to the top-level dir name in the storage bucket

Query Parameters

Name Type Description
versions String Include previous file versions_Default value: true_
Allowed values: true,false
fetch String Rescan data or retrieve the existing index (default)Default value: false
Allowed values: true,false
fetch String Rescan data or retrieve the existing index (default)Default value: false
Allowed values: true,false

Examples

Example usage:

STORE_ID=10003054628 curl localhost:8080/filestore/${STORE_ID} | jq .

Success response

Success response - Success 200

Name Type Description
id String Shopify Store ID
bucket String GCS Storage Bucket
products Number[] Shopify Product IDs
deletedProducts Number[] Deleted Shopify Product IDs
files Object[] Bucket Files
files.name String The name of the stored file
files.currentFileSize Number The size of the current file version in bytes
files.size Number The Total size of all the file versions in bytes
files.previousFileVersionsSize Number The size of the previous file versions in bytes
files.previousFileVersionsCount Number The number of the previous file versions
files.generation Number The Generation Number (unique for the file version)
files.url String Download URL for the current file version
files.versions [Object[]] The file versions
files.versions.id String The ID of the file version
files.versions.generation Number The Generation Number of the file version
files.versions.isCurrent Boolean Indicates whether the given file version is current
files.versions.url String The Download URL for the file version
files.versions.size Number The Size of the file version in bytes
files.versions.metadata Object The partial gce metadata
files.versions.metadata.timeCreated Timestamp
files.versions.metadata.updated Timestamp
files.versions.metadata.timeDeleted Timestamp
deletedFiles Object[] Deleted Files in bucket
stats Object Contains the summarized quantitative metrics for the stored data
stats.files Number Number of files stored
stats.deletedFiles Number Number of deleted files in bucket // * @apiSuccess {[Number]} stats.previousFileVersions Number of all file versions stored
stats.products Number Number of products
stats.deletedProducts Number Number of deleted products
stats.size Number Total Size of Data Stored
stats.previousFileVersionsSize [Number] Size of the previous versions
stats.previousFileVersionsCount [Number] The number of the previous file versions
stats.currentFileSize Number Size of the current versions

Success response example

Success response example - Success-Response:

{
  "id": 10003054628,
  "bucket": "custom-product-builder",
  "products": [
    7000615387329,
    7000615420097,
    7000615452865,
    7000615813313
  ],
  "deletedProducts": [],
  "deletedFiles": [],
  "files": [
    {
      "name": "7000615387329.json",
      "versions": [
        {
          "id": "custom-product-builder/10003054628/7000615387329.json/1635936486341218",
          "generation": "1635936486341218",
          "metadata": {
            "timeCreated": "2021-11-03T10:48:06.376Z",
            "updated": "2021-11-03T10:48:06.376Z",
            "timeDeleted": "2021-11-03T10:48:06.641Z"
          },
          "isDeleted": true,
          "size": 100904,
          "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615387329.json?generation=1635936486341218&alt=media"
        },
        {
          "id": "custom-product-builder/10003054628/7000615387329.json/1635936486517468",
          "generation": "1635936486517468",
          "metadata": {
            "timeCreated": "2021-11-03T10:48:06.641Z",
            "updated": "2021-11-03T10:48:06.641Z"
          },
          "isCurrent": true,
          "size": 100904,
          "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615387329.json?generation=1635936486517468&alt=media"
        }
      ],
      "currentFileSize": 100904,
      "generation": 1635936486517468,
      "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615387329.json?generation=1635936486517468&alt=media",
      "totalSize": 201808,
      "previousFileVersionsSize": 100904
    },
    {
      "name": "7000615420097.json",
      "versions": [
        {
          "id": "custom-product-builder/10003054628/7000615420097.json/1635936486855324",
          "generation": "1635936486855324",
          "metadata": {
            "timeCreated": "2021-11-03T10:48:06.890Z",
            "updated": "2021-11-03T10:48:06.890Z",
            "timeDeleted": "2021-11-03T10:48:07.148Z"
          },
          "isDeleted": true,
          "size": 39404,
          "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615420097.json?generation=1635936486855324&alt=media"
        },
        {
          "id": "custom-product-builder/10003054628/7000615420097.json/1635936487029707",
          "generation": "1635936487029707",
          "metadata": {
            "timeCreated": "2021-11-03T10:48:07.148Z",
            "updated": "2021-11-03T10:48:07.148Z"
          },
          "isCurrent": true,
          "size": 39404,
          "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615420097.json?generation=1635936487029707&alt=media"
        }
      ],
      "currentFileSize": 39404,
      "generation": 1635936487029707,
      "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615420097.json?generation=1635936487029707&alt=media",
      "totalSize": 78808,
      "previousFileVersionsSize": 39404
    },
    {
      "name": "7000615452865.json",
      "versions": [
        {
          "id": "custom-product-builder/10003054628/7000615452865.json/1635936486472693",
          "generation": "1635936486472693",
          "metadata": {
            "timeCreated": "2021-11-03T10:48:06.508Z",
            "updated": "2021-11-03T10:48:06.508Z",
            "timeDeleted": "2021-11-03T10:48:06.777Z"
          },
          "isDeleted": true,
          "size": 90487,
          "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615452865.json?generation=1635936486472693&alt=media"
        },
        {
          "id": "custom-product-builder/10003054628/7000615452865.json/1635936486654280",
          "generation": "1635936486654280",
          "metadata": {
            "timeCreated": "2021-11-03T10:48:06.777Z",
            "updated": "2021-11-03T10:48:06.777Z"
          },
          "isCurrent": true,
          "size": 90487,
          "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615452865.json?generation=1635936486654280&alt=media"
        }
      ],
      "currentFileSize": 90487,
      "generation": 1635936486654280,
      "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615452865.json?generation=1635936486654280&alt=media",
      "totalSize": 180974,
      "previousFileVersionsSize": 90487
    },
    {
      "name": "7000615813313.json",
      "versions": [
        {
          "id": "custom-product-builder/10003054628/7000615813313.json/1635936606084578",
          "generation": "1635936606084578",
          "metadata": {
            "timeCreated": "2021-11-03T10:50:06.120Z",
            "updated": "2021-11-03T10:50:06.120Z"
          },
          "isCurrent": true,
          "size": 652,
          "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615813313.json?generation=1635936606084578&alt=media"
        }
      ],
      "currentFileSize": 652,
      "generation": 1635936606084578,
      "url":
  "https://storage.googleapis.com/download/storage/v1/b/custom-product-builder/o/10003054628%2F7000615813313.json?generation=1635936606084578&alt=media",
      "totalSize": 652,
      "previousFileVersionsSize": 0
    }
],
  "stats": {
    "files": 4,
    "previousFileVersions": 7,
    "products": 4,
    "size": 462242,
    "previousFileVersionsSize": 230795,
    "currentFileSize": 231447
  },
  "debug": {
    "params": {
      "id": "10003054628"
    },
    "query": {}
  }
}

Get Shopify Product Config by id from the filestore

Back to top

Get Shopify Product Config by id from the filestore

This method returns the product configuration that otherwise could be retrieved directly from the storage. Some transformations may be applied to the product though. Possible use cases:
  1. Restriction of the public file downloads only to the registered client app to prevent unauthorized data copy and reverse engineering.
  2. Removing of unneeded attributes from the file and sending sanitized version to client while resaving the processed file.
  3. Adding additional attributes to the config.
  4. Storage migrations.
  5. Advanced requests logging for the analytical or debugging purposes
  6. Restriction of the data access for the expired trial app.
GET /filestore/:shop_id/product/:product_id

Error response

Error response - Error 4xx

Name Type Description
ProductNotFound The id was not found.