Quick and easy way to connect your Node.js app with SPHERE.IO HTTP APIs.
Install the module with: npm install sphere-node-connect
sphere_connect = require 'sphere-node-connect'
# handles OAuth2 request to retrieve an access_token
OAuth2 = sphere_connect.OAuth2
# handles requests to HTTP APIs
Rest = sphere_connect.Rest
# or simpler
{OAuth2, Rest} = require 'sphere-node-connect'
The connector exposes 2 objects: OAuth2
and Rest
.
The OAuth2
is used to retrieve an access_token
oa = new OAuth2
config:
client_id: ''
client_secret: ''
project_key: ''
host: 'auth.sphere.io' # optional
accessTokenUrl: '/oauth/token' # optional
timeout: 20000 # optional
rejectUnauthorized: true # optional
logConfig: {} # optional (see `Logging` section)
oa.getAccessToken (error, response, body) -> # do something
The Rest
is used to comunicate with the HTTP API.
rest = new Rest
config:
client_id: ''
client_secret: ''
project_key: ''
host: 'api.sphere.io' # optional
access_token: '' # optional (if not provided it will automatically retrieve an `access_token`)
timeout: 20000 # optional
rejectUnauthorized: true # optional
oauth_host: 'auth.sphere.io' # optional (used when retrieving the `access_token` internally)
user_agent: 'my client v0.1' # optional
logConfig: {} # optional (see `Logging` section)
rest.GET resource, (error, response, body) -> # do something
rest.POST resource, payload, (error, response, body) -> # do something
rest.DELETE resource, (error, response, body) -> # do something
rest.PAGEd resource, (error, response, body) -> # (see `Paged requests` section)
The
Rest
object, when instantiated, has an internal instance of theOAuth
module accessible withrest._oauth
. This is mainly used internally to automatically retrieve anaccess_token
.
Currently GET
, POST
and DELETE
are supported.
Paged results (when querying an endpoint) can be processed in chunks, to avoid the server to return big amount of data all together.
The PAGED
function recursively accumulates the paged results, returning all of them at once.
Use this function to safely query all results (=>
limit=0
)
rest = new Rest options
rest.PAGED '/products', (error, response, body) ->
# do something
Note that by using this function, the
limit
is considered to be 0, meaning all results are queried. So givenlimit
andoffset
parameters will be ignored.
# with query params
rest = new Rest options
rest.PAGED '/products?where=name%3D%22Foo%22&staged=true', (error, response, body) ->
# do something
You can also subscribe to progress notifications
rest = new Rest options
rest.PAGED '/products', (error, response, body) ->
# do something
, (progress) ->
# progress is an object containing the current progress percentage
# and the value of the current results (array)
# {percentage: 20, value: [r1, r2, r3, ...]}
Since the connector is basically a wrapper of the request
HTTP Client, the callback
function comes directly from there, meaning that the 3 arguments are the same:
error
: an error object when applicable (usually fromhttp.ClientRequest
object) otherwisenull
response
: anhttp.IncomingMessage
object containing all kind of information about the request / responsebody
: a JSON object (automatically parsed)
As the SPHERE.IO HTTP API returns JSON responses either with resources or error messages, the application should check the response statusCode
and decide what to do.
It's always a good practice to check first for the existence of an error
object in case there was a problem with the http client request.
(error, response, body) ->
if error
# do something
else
if response.statusCode is 200
# ok
else
# do something else
oa.getAccessToken (error, response, body) ->
if response.statusCode is 200
access_token = body.access_token
else
throw new Error 'Failed to get Access Token.'
# Get a list of all products
rest.GET '/products', (error, response, body) -> console.log(body)
# Create a new product
rest.POST '/products',
name: { en: 'Foo' }
slug: { en: 'foo' }
productType: { id: '123', typeId: 'product-type' }
, (error, response, body) -> console.log(body)
# Update a product
rest.POST '/products/123',
version: 1
actions: [
{ action: 'changeName', name: { en: 'Boo' } }
]
, (error, response, body) -> console.log(body)
# Delete a product
rest.DELETE '/product/abc?version=3', (error, response, body) ->
if response.statusCode is 200
console.log 'Product successfully deleted.'
else if response.statusCode is 404
console.log 'Product does not exist.'
else if response.statusCode == 400
console.log 'Product version does not match.'
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.
Define your SPHERE.IO credentials into a config.js
. Since the tests run against 2 projects on different environments you need to provide the credentials for both. If you just have one project You can provide the same credentials for both.
/* SPHERE.IO credentials */
exports.config = {
staging: {
client_id: "",
client_secret: "",
project_key: "",
oauth_host: "auth.sphere.io",
api_host: "api.sphere.io"
},
prod: {
client_id: "",
client_secret: "",
project_key: "",
oauth_host: "auth.sphere.io",
api_host: "api.sphere.io"
}
}
Releasing a new version is completely automated using the Grunt task grunt release
.
grunt release // patch release
grunt release:minor // minor release
grunt release:major // major release
We <3 CoffeeScript! So please have a look at this referenced coffeescript styleguide when doing changes to the code.
Copyright (c) 2013 Nicola Molinari Licensed under the MIT license.