4

I have a simple http client module(api.js) which is returning a promise as in the followings:

 exports.endpoint = '';

        exports.GET =  function(args){
            args.method = 'GET';
            args.uri = this.endpoint + args.uri;
            return asyncApiCall(args);
        };
        exports.POST =  function(args){
            args.method = 'POST';
            args.uri = this.endpoint + args.uri;
            return asyncApiCall(args);
        };
        exports.PUT =  function(args){
            args.method = 'PUT';
            args.uri = this.endpoint + args.uri;
            return asyncApiCall(args);
        };
        exports.DELETE= function(args){
            args.method = 'DELETE';
            args.uri = this.endpoint + args.uri;
            return asyncApiCall(args);
        };

        var asyncApiCall = function(args){
            var rp = require('request-promise');
            var options = {
            method: args.method,
            uri: args.uri,
            body : args.body,
            json: args.json
        }

        return rp(options);

        };

and I use the module like this:

var api = require('./api.js');
var args = {
    uri : '/posts'

}
api.endpoint = 'http://localhost:3000';
api.GET(args)
    .then(function(res){
                console.log(res);
            }, function(err){
                console.log(err);
            });

Now, I want to improve the module as much as possible. Is there any way to not repeat the export.functionName? I found the module.exports in NodeJS, but I am not sure how to use it in this case. How can I set the endpoint variable once in asyncApiCall function instead of all the other functions that return asyncApiCall?

mohi
  • 1,093
  • 2
  • 16
  • 21

3 Answers3

2

A lot of people chose to put their export methods on a new object and export via module.exports, e.g.

var myExports = {
   get: function () {},
   post: function () {}
}
module.exports = myExports;

As for module.exports vs exports

It looks like it may be appropriate to set up a full constructor with your methods tied to it, like so:

var requests = function (endpoint) {
   this.endpoint = endpoint;
}

requests.prototype.GET = function (args) {
    args.method = 'GET';
    args.uri = this.endpoint + args.uri;
    return asyncApiCall(args);
}

// And so on

module.exports = requests;

And then call it like so:

var api = require('./api.js');
var endpoint = new api("http://localhost:3000");

endpoint.GET()
Community
  • 1
  • 1
Jack Guy
  • 8,346
  • 8
  • 55
  • 86
2

Just another style:

var rp = require('request-promise'); // Put it here so you don't have to require 1 module so many times.

var asyncApiCall = function(args) {
  var options = {
    method: args.method,
    uri: args.uri,
    body : args.body,
    json: args.json
  };
  return rp(options);
};

// Let's hack it.
var endpoint = '';
var apis = {};
['GET', 'POST', 'PUT', 'DELETE'].forEach(function(method) {
  apis[method] = function(args) {
    args.method = method;
    args.uri = endpoint + args.uri;
    return asyncApiCall(args);
  }
});

module.exports = apis;
module.exports.endpoint = '';
haotang
  • 5,520
  • 35
  • 46
  • I have a problem here. The endpoint cannot be set anymore the way I wanted to set it (api.endpoint = 'http://localhost:3000';) check my question please – mohi Nov 10 '15 at 17:52
  • OK, got it! 'this' is needed for endpoint. I edited your answer – mohi Nov 10 '15 at 18:02
1

Wrap this in a class and export a new instance of it

function Module() {

}

Module.prototype.GET = function () {}

module.export = new Module()
// or
module.export = Module
// to call the constructor for your endpoint variable.
eljefedelrodeodeljefe
  • 6,304
  • 7
  • 29
  • 61