GithubHelp home page GithubHelp logo

wrapi's Introduction

wrapi

Wrap Restful API endpoints as callable functions.

Create a Rest API SDK under 3 minutes.

NPM version Build Status Coverage Status Known Vulnerabilities

With wrapi you make calls to HTTP based APIs just like ordinary JavaScript functions.


Installation

$ npm install wrapi --save

Or

$ yarn add wrapi

Easy Start

  1. Create a JSON file listing all API endpoints you want to work with.
  2. Wrap endpoints with wrapi.
  3. Call individual endpoints as functions.

See Sample Code


JSON File

Declare each endpoint in a json file as per the following specifications.

"function_name": {
	"method": "HTTP_METHOD",					// 'GET', 'POST', 'PUT', 'PATCH' or 'DELETE'
	"path": "relative/path/to/:api/endpoint"	// Use `express` style path params
}

E.g. a small set of github.com API:

{
	"repo": {
		"method" : "GET",
		"path" : "repos/:owner/:repo"
	},

	"contributors": {
		"method" : "GET",
		"path" : "repos/:owner/:repo/contributors"
	},

	"languages": {
		"method" : "GET",
		"path" : "repos/:owner/:repo/languages"
	},

	"tags": {
		"method" : "GET",
		"path" : "repos/:owner/:repo/tags"
	},

	"branches": {
		"method" : "GET",
		"path" : "repos/:owner/:repo/branches"
	}
}

Wrap endpoints

Create a API client object from wrapi. Provide the base url for the API and the JSON object. wrapi will create a client object with all the necessary functions.

const endpoints = require('./github.api.json');
const wrapi = require('wrapi');

const client = new wrapi('https://api.github.com/',	// base url for the API
  endpoints 										// your json object
);

// client object contains functions to call the API

Register

Register additional API endpoints with the client object with a function name.

client.register('zen',
  {
    method : 'GET',
    path: 'zen'
  }
);

Make the call

Call API function with arguments and a callback.

// This will make GET request to 'https://api.github.com/repos/nodejs/node/contributors'
client.contributors('nodejs', 'node', function(err, contributors) {
  if (!err) {
  	console.log(contributors);
  }
});

client.zen(function(err, response) {
  if (!err) {
    console.log('Chris says "' + response + '"');
  }
});

API

wrapi is an open ended framework. It is not restricted any specific or a set of APIs.

All APIs providing HTTP interface to access the endpoints can be wrapped by wrapi, so that you can quickly build your client application.

Endpoint Definition

Note: method & path/url are required.

  • method - Any one of the HTTP methods (default: "GET")
  • path - route path to API Endpoint. Supports express style path params
  • query - an object consists of name-value pairs. This is optional. This is useful where resources are identified via query string parameters
  • options - options to override or to add specific to the API endpoint. E.g. {encoding:null} returns the response data as Buffer
  • url - fully qualified uri string to override. This is useful in cases where an API call connects to a different endpoint

Client object

The wrapi object conveniently provides the client interface to the API. Create the object by calling new wrapi().

The constructor takes the following arguments:

  1. baseURL - The base url for the API. E.g. https://api.github.com/
  2. endpoints - The JSON object listing the API endpoints. Provide {} - empty object or a partial list and then register (additional) endpoints later
  3. options - Optional parameter. wrapi uses request module to connect to API server. The options parameter is the same options parameter used in request

Custom options

  1. catchHTTP4xx5xx - Set this option to true to treat HTTP status 4xx & 5xx as errors. Default value is false. If set, the err argument in your callback function will contain the response body for 4xx & 5xx errors.

Register function

Add endpoints to client object.

register(functionName, endpointDefinition)
  1. functionName - Alias for the endpoint, also the name of the function to call.
  2. endpointDefinition - JSON object defining the endpoint.

Function calls

Call API endpoints via the function in the client object. Arguments to the function depend on the API declaration in the JSON.

Provide the arguments in the following order:

  1. named params in the url path of the endpoint. eg. client.contributors('nodejs', 'node', // nodejs & node are path params
  2. query string as an object with name-value pairs. eg. client.repositories({since:364} // ?since=364
  3. body - JSON content for POST or PUT methods. Skip this argument if not required for the call.
  • To POST multipart/form-data, set this argument as {"formData" : multipartContent }
  1. callback(err, data) - a callback function for the results to be returned. The callback is called when the response is fetched or if there is an error. This callback function gets the results of the response.

    To pipe the results, pass a writable stream as the callback. Listen to error events on outputstream to catch streaming errors. See example.

Examples

In examples folder.

Implementations

License

MIT

wrapi's People

Contributors

palanik avatar

Stargazers

J0sema avatar Miles Blackwood avatar Mohamed Baddi avatar Marshall avatar REGE avatar Abraham avatar  avatar Jiminald avatar Alejandro Sanchez avatar  avatar Karol Baczewski avatar  avatar me avatar

Watchers

James Cloos avatar  avatar  avatar  avatar

Forkers

johnschimmel

wrapi's Issues

resources/endpoints by query options

API where a single endpoint is used to fetch multiple resources. Resources are identified by query string parameter.

eg. BEA Data API.
The API has one URI for all the datasets

http://www.bea.gov/api/data.

All API access is through this URI; no other paths are used.

A dataset is identified by the datasetname parameter.

Return statusCode for catchHTTP4xx5xx

When the server returns empty response for errors, it is not simple to identify as an error case.

e.g.

client.somemethod(params, function(err, data) {
  if (err) {  // evaluates to false on empty response
    console.error(err);
  }
...

Suggested object for error:

{
  statusCode: 404
  body: ''
}

Ability to pipe results

Nice to have. Esp. with large/binary data.
No need for intermediate storage.

Very handy using in a http server.

app.get('/resource', function(req, res, next) {
  apiWrapi.getData(res);
});

Body must be JSON.stringify

It seems that the body object must be JSON.stringify() before being passed to the end point. Although, your examples do not do it and in the tests (https://github.com/palanik/wrapi/blob/master/test/body-content.js) you do not stringify. I have not tried running tests

However, when I don't stringify I get
Error: Argument error, options.body.
Is this normal?
I tried changing {json: false/true} in register. No effect.

Wrapper:

var wrapi = require('wrapi');

var client = new wrapi('http://IP:PORT/api/v1/',	// base url for the API
  null 										// your json object
);

client.register('postEntitlements',{
    method: 'POST',
    path: 'realms/:realmName/entitlements'
},
{json: true});

module.exports = client

Consumer:

'use strict';
let apiClient = require('./external-api/client')

 apiClient.postEntitelments('realm-name', {entitlementIds: ["123","345"]} )
        .then((response) =>{

            done();            
        });
...
function postEntitlements(realmName, ids)
{
    return new Promise((resolve, reject) =>{
        apiClient.postEnts(realmName, JSON.stringify(ids) ,  function(err, response){
            if (err) {
                reject(err);
            }
            resolve( response);
        });
    });
}
...


```

Tests fail in Node 8.x

     Uncaught TypeError: Cannot read property 'toString' of undefined
      at matchStringOrRegexp (node_modules/nock/lib/scope.js:169:22)
      at checkHeaders (node_modules/nock/lib/scope.js:200:16)
      at Array.every (<anonymous>)
      at Object.match (node_modules/nock/lib/scope.js:203:25)
      at node_modules/nock/lib/request_overrider.js:240:26
      at Array.filter (<anonymous>)
      at end (node_modules/nock/lib/request_overrider.js:236:33)
      at OverriddenClientRequest.RequestOverrider.req.end (node_modules/nock/lib/request_overrider.js:170:7)
      at Request.end (node_modules/request/request.js:1528:14)
      at end (node_modules/request/request.js:554:16)
      at Immediate._onImmediate (node_modules/request/request.js:581:7)

Arrays (as csv) for param

Sample end point: /quotes/:tickers
path: /quotes/fb,aapl,goog

Currently, you have to pass a csv string as the argument, like this: api.quotes('fb,aapl,goog', (err, data) => {});

Preferably an array of values can be used: api.quotes(['fb','aapl','goog'], (err, data) => {});

Endpoints with nested function names fail (inconsistent)

sample endpoints definition

    {
        "movies.item.create": {
          "method" : "POST",
          "path": "movies"
        },
        "movies.item": {
          "method" : "GET",
          "path": "movies/:id"
        },
        "movies" : {
          "method" : "GET",
          "path": "movies"
        }
    }

would generate runtime error like

movies.item.create is not a function

h/t @jujasp

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.