[ Quick start • Examples • Built-in API methods • API Reference • Contribution guide • Heroes]
Provides helpers for writing your own API methods and using them from server and client sides. See also bla-presentation for more details.
The package is versioned according to SemVer.
- Simple integration.
- Consistent interface of API methods on the server and client sides.
- Normalization for request parameters.
- Automatic documentation generation for all declared API methods.
- Joining all client requests into one during one tick (see batch method).
- Enb builder support.
npm install bla --save
Write API method declaration.
var ApiMethod = require('bla').ApiMethod;
module.exports = new ApiMethod('hello')
.setDescription('Hello API method')
.addParam({
name: 'name',
description: 'User name',
required: true
})
.setAction(function (params) {
return 'Hello, ' + params.name;
});
And save it to api/hello.api.js
.
var Api = require('bla').Api;
var api = new Api(__dirname + '/api/**/*.api.js');
api.exec('hello', {name: 'Stepan'}).then(function (response) {
console.log(response); // 'Hello, Stepan'
});
First, include API middleware to your express application.
var app = require('express')();
var bodyParser = require('body-parser');
var apiMiddleware = require('bla').apiMiddleware;
app
.use(bodyParser.json())
.use('/api/:method?', apiMiddleware(__dirname + '/api/**/*.api.js'));
Include the client library to .
<script type="text/javascript" src="build/bla.min.js"></script>
or specify bla
as enb dependency in package.json.
"enb": {
"dependencies": [
"bla"
]
}
Then use API module with YM module system
modules.require('bla', function (Api) {
var api = new Api('/api/');
api.exec('hello', {name: 'Stepan'}).then(function (response) {
console.log(response); // 'Hello, Stepan'
});
});
with require.js
require(['bla'], function (Api) {
var api = new Api('/api/');
api.exec('hello', {name: 'Stepan'}).then(function (response) {
console.log(response); // 'Hello, Stepan'
});
});
or without module system at all
var api = new bla.Api('/api/');
api.exec('hello', {name: 'Stepan'}).then(function (response) {
console.log(response); // 'Hello, Stepan'
});
See Api class for more information.
Note. express 4.x
is used in all examples. See package.json for more details.
- Api methods
- Server side
- Middleware
- Frontend side
Use makefile to run an example. For instance,
make run examples/backend/basic_usage.js
This method is used on the client side and makes it possible to joint all requests to the server during one tick. It shortens number of request dramatically.
The client side uses this method by default and can be changed with noBatching
option of Api class constructor or the noBatching
option of the Api.exec method.
Do you want the proves that batch is effective? See bla-benchmark.
- Server side
- Frontend side
Creates a new instance of API and collects all your API methods from methodPathPattern
path. Path supports minimatch.
Example:
var Api = require('bla').Api;
var api = new Api(__dirname + '/api/**/*.api.js');
Executes an API method methodName
with the provided params
.
An express request can also be passed using request
parameter. The middleware proxies it for you.
Returns vow.Promise. Promise will be resolved with a method response or rejected with ApiError.
Example:
api.exec('hello', {name: 'Stepan'})
.then(function (response) {
console.log(response);
})
.fail(function (error) {
console.log(error.message);
});
Creates a new instance of ApiMethod with provided methodName
.
ApiMethod class supports chaining for it's methods: setDescription
, addParam
, and setAction
.
Example:
var ApiMethod = require('bla').ApiMethod;
var helloMethod = new ApiMethod('hello');
Change method description to provided description
.
Example:
helloMethod.setDescription('This is a hello method');
Add a new param declaration.
API method param is an object with the follow fields:
Name | Type | Description |
---|---|---|
name | String | Parameter name |
description | String | Parameter description |
[type] | String | Parameter type (String, Number, Boolean, etc.) |
[required] | Boolean | Should the parameter be made obligatory |
Example:
helloMethod.addParam({
name: 'name',
description: 'User name',
required: true
});
Sets a function which should be executed when method runs.
Declared parameters will be passed to the action
function as a first parameter. If the method is executed via the middleware, expresses request will be passed as a second parameter (undefined
for server side execution).
Example:
helloMethod.setAction(function (params, request) {
return 'Hello, world';
});
A third parameter is an Api instance. It's very useful in cases when the api method executes other api methods.
Example:
method.setAction(function (params, request, api) {
return api.exec('method1');
});
Executes an API method with provided params
.
An express request can also be passed using request
parameter. The middleware proxies it for you.
Returns vow.Promise. The promise will be resolved with a method response or rejected with ApiError.
Example:
helloMethod.exec({name: 'Stepan'})
.then(function (response) {
console.log(response);
})
.fail(function (error) {
console.log(error.message);
});
Sets an extra option for the method.
List of available options:
Name | Type | Description |
---|---|---|
hiddenOnDocPage | Boolean | Hides the API method in built documentation. |
executeOnServerOnly | Boolean | Permit to execute method only on server side . |
ApiError is inherited from JavaScript Error class. You can specify type
of the error and message
with human-readable description of the error.
See bellow supported list of errors.
Example:
var ApiError = require('bla').ApiError;
throw new ApiError(ApiError.INTERNAL_ERROR, 'Internal server error');
ApiError.BAD_REQUEST
— Invalid or missed parameter.ApiError.INTERNAL_ERROR
— Unspecified error or error in server logic.ApiError.NOT_FOUND
— API method or middleware wasn't found.
var apiMiddleware = require('bla').apiMiddleware(methodPathPattern, options)
The middleware adds a route path for API to your Express application. You need to pass methodPathPattern
as you did for Api class or an Api instance itself.
Note. The middleware always proxies an express request to an executed method.
Using the second paremeter options
you can tune the middleware up.
Name | Type | Description |
---|---|---|
[disableDocPage] | Boolean | Turn off generating page with documentation. See example. |
[buildMethodName] | Function | express.Request is passed to the function. The function should return a method name. By default methodName is grabbed by executing req.param('method') . See example. |
Method parameters are collected from Express request using req.param method.
For example, the apiMiddleware will look for a parameter named myparam
in the following order:
- In the URL path (
/api/:myparam?
). - In the request's query string (
?myparam=1
). - In the request's body.
The middleware accepts GET
and POST
requests from the client.
Note. Don't forget to add body-parser middleware, because the provided client module uses POST
requests.
Also you must specify :method?
parameter in the route path used by this middleware or buildMethodName
function. Otherwise, the middleware won't find the API method name.
If you don't provide any method name, the middleware will show your the list of all available API methods (special page with documentation). Specified descriptions for methods and params will be used for generating documentation.
Example:
var app = require('express')();
var bodyParser = require('body-parser');
var apiMiddleware = require('bla').apiMiddleware;
app
.use(bodyParser.json())
.use('/api/:method?', apiMiddleware(__dirname + '/../api/**/*.api.js'))
You can find a working examples in example/middleware directory.
The middleware returns a response with a JSON string and a 200
status code (even if an error occured). You can distinguish an error and successful response by checking the data
and error
fields in the root of the response object.
Example of a successful response:
{
"data": "Hello, Stepan"
}
Example of a response with an error:
{
"error": {
"type": "BAD_REQUEST",
"message": "missing name parameter"
}
}
Requirements:
- vow — DOM Promise and Promises/A+ implementation for Node.js and browsers.
Creates a new instance of client API. basePath
is used to build the path for AJAX requests to the server. For example, if you define /api
as a basePath
then all request will be sent to https://<your host>/api/<method name>
.
Also you can specify an extra options:
Name | Type | Description |
---|---|---|
[noBatching] | Boolean|String[] | Disable using batch for all client requests (false by default), or if an array of strings is passed, disable batching only for specific methods. |
You can use the client-side bundle of bla with different module systems. For example:
// ym
modules.require('bla', function (Api) {
var api = new Api('/api/');
});
// require.js
require(['bla'], function (Api) {
var api = new Api('/api/');
});
// without module system
var api = new bla.Api('/api/');
There are two ways for using the noBatching
parameter.
Disable batching globally:
// all api.exec() calls will NOT be batched
var api = new Api('/api/', {noBatching: true});
Disable batching per method:
// api.exec() calls with method name argument 'slow-poke' will not be batched
var api = new Api('/api/', {noBatching: ['slow-poke']});
Sends a request to the server for executing API method with name methodName
and provided params
. The options argument is used for changing the method behavior.
The method returns a vow.Promise.
Name | Type | Description |
---|---|---|
[noBatching] | Boolean | Disable using batch for current request (false by default) |
For example:
api.exec('hello')
.then(function (response) {
// Be polite! Handle the 'response' properly.
// ...
})
.fail(function (reason) {
// Even when rejected, a gentleman shouldn't lose his temper. Do something with the 'reason'.
// ...
});
If you want to disable the batching for a single api.exec()
call:
// method 'slow-poke' won't be batched for this call only
api.exec('slow-poke', {}, {noBatching: true}).then(function () {
// ...
});
It works absolutely the same as the server version of ApiError.