Kim Bui

Follow your passion, be prepared to work hard and sacrifice, and, above all, don't let anyone limit your dreams. ( Donovan Bailey )

  • Home
  • Work
  • About me

Create NodeJs module to work with third party Restful APIs

January 25, 2016 / Leave a Comment

I work with Nodejs and often implement third party Restful APIs in the bitcoin exchange world. I have learned enough to see the pattern and make the implementation smoother every time. Here is what I got and I hope that this will reach someone with the same goal : less time researching and shorter trial-and-error period. Restful APIs can be public(unauthentic) or private (authentic), plus each third party will have their own rules of how to call their private API based on their choice of encrypted method. Good chance is, you can find some modules that is already done for you and it will be a piece of cake, but what if there is none, or what if you want to take it into your own hand and want to write your own module to ensure the security of your privacy?. This tutorial will present a way to write simple Node module that will allow you to use JSON RPC to call APIs, public and private. I assumes that you already know enough of Javascript, Nodejs and npm modules to be able to benefit from this tutorial. I use Yunbi exchange as an example for the APIs. Now, let’s start

  • Step 1 : Understand the third party’s API Most public API is just simple requests, but private APIs require much more in the options, let’s take a look at these private APIs requirements : private API So the request should look like this :

    hash = HMAC-SHA256(‘GET|/api/v2/markets|access_key=xxx&foo=bar&tonce=123456789’, ‘yyy’) .to_hex = ‘someHex’

    curl -X GET ‘https://yunbi.com/api/v2/markets?access_key=xxx&foo=bar&tonce=123456789&signature=hash’

When we write the module for this API, we have to make sure we know the correct hash to compile in order to have the result back. In the next step, I will demonstrate the functions in the node module that is written based on the above requirements.

  • Step 2 : Start writing the module

    // Constructor function moduleName(key, secret) { // Generate headers signed by this user’s key and secret. // The secret is encapsulated and never exposed this._getPrivateHeaders = function (parameters, link) { var paramString, signature; var url = “POST|” + HASH_URL + link + “|” if (!key || !secret) { throw ‘Yunbi: Error. API key and secret required’; }

        // Sort parameters alphabetically and convert to `arg1=foo&arg2=bar`
        paramString = Object.keys(parameters).sort(parameters).map(function (param) {
            return encodeURIComponent(param) + '=' + encodeURIComponent(parameters[param]);
        }).join('&');
        var signature = crypto.createHmac('SHA256', secret).update(url + paramString).digest('hex');
        parameters.signature = signature
    
        signature = crypto.createHmac('sha256', secret).update(paramString).digest('hex');
        //console.log("SIGNATURE " +signature)
    
        Gkey = key
        Gsign = signature
        return {
            Key: key,
            Sign: signature
        };
    };

    }

Next, we will create prototype of the module, which will include a request function, a private post and private get function.

   ModuleName.prototype = {
    constructor: Yunbi,

    // Make an API request
    _request: function (options, callback) {
        request(options, function (err, response, body) {
            // Empty response
            if (!err && (typeof body === 'undefined' || body === null)) {
                err = 'Empty response';
            }

            callback(err, body);
        });

        return this;
    },

    // Make a public API request
    _public: function (link, parameters, callback) {
        var options;

        if (typeof parameters === 'function') {
            callback = parameters;
            parameters = {};
        }

        parameters || (parameters = {});
        options = {
            method: 'GET',
            url: API_URL + link,
            qs: parameters
        };
        return this._request(options, callback);
    },

    // Make a private API request POST
    _privatePost: function (link, parameters, key, secret, callback) {
        var options;

        if (typeof parameters === 'function') {
            callback = parameters;
            parameters = {};
        }

        parameters || (parameters = {});
        parameters.tonce = nonce() / 100;
        parameters.access_key = key
        var paramString = Object.keys(parameters).sort(parameters).map(function (param) {
            return encodeURIComponent(param) + '=' + encodeURIComponent(parameters[param]);
        }).join('&');

        options = {
            method: "POST",
            url: API_URL + link,
            form: parameters,
            headers: this._getPrivateHeaders(parameters, link)
        };
        options.headers['User-Agent'] = "Yunbi API Client/0.0.1"
        return this._request(options, callback);
    },

    // Make a private API request GET
    _privateGet: function (link, key, secret, callback) {
        var options;
        var url = "GET|" + HASH_URL + link + "|"

        var parameters = {}
        parameters.access_key = key
        parameters.tonce = parseInt(nonce() / 100);

        var paramString = Object.keys(parameters).sort(parameters).map(function (param) {
            return encodeURIComponent(param) + '=' + encodeURIComponent(parameters[param]);
        }).join('&');

        var signature = crypto.createHmac('sha256', secret).update(url + paramString).digest('hex');
        parameters.signature = signature
        paramString = paramString + "&" + encodeURIComponent('signature') + "=" + encodeURIComponent(signature)
        options = {
            method: 'GET',
            url: API_URL + link + "?" + paramString
        };
        return this._request(options, callback);
    },

Now we define the methods that are available for the users through this module

    // PUBLIC METHODS

    getTicker: function (A, B, callback) {
        var parameters = {
            market: joinCurrencies(A, B)
        };
        var url = '/tickers/' + joinCurrencies(A, B) + '.json'

        return this._public(url, parameters, callback);
    },


    // PRIVATE METHODS

    myBalances: function (key, secret, callback) {
        return this._privateGet('/members/me.json', key, secret, callback);
    },
  • Step 3 : Testing

    • My personal way of testing with Nodejs and API is just functional unit tests : writing tests for each call, I find this way cost less time and efficient for testing production also in case you have different authentication for production and development environments. But again this is personal choice and I’m sure there are good testing Frameworks out there that I’m happy to hear if you have any suggestion.
  • Step 4 : Publish the module on npmjs

    • When all tests are passed, happy hour is here : time to put your work out there and join (or continue to contribute) to the open source community, or put it to work for your company, projects … forgive me to assume that you also know how to publish your modules. If not, I (will) have another post for common path I go in working with node module, from writing to publishing and upgrading versions.
Posted in: blog Tagged: access API with Nodejs, Authentication API, create Node module, exchanges API, javascript, Nodejs, restful, Restful API, Yunbi
1 2 Next »

Blog Posts

  • Create NodeJs module to work with third party Restful APIs
  • Uploading WordPress site from local server to a live web server

Connect with me

Link to my Github Page
Link to my Linkedin Page

Copyright © 2025 Kim Bui.

Me WordPress Theme by themehall.com