
express-endpoint
A tool to create and document RESTful api endpoints in a declaritive way.
Install
npm install express-endpoint
or
git clone http://github.com/dokipen/express-endpoint.git
cd express-endpoint
npm link
Develop
The develop script runs the tests and app in a loop, restarting the loop each
time a source file is changed. You'll need inotifywait to use develop.sh. On
gentoo and debian/ubuntu it is provided by the inotify-tools package.
$ npm run-script develop
Demo
http://express-endpoint.herokuapp.com/
Human contact
rcorsaro@gmail.com
Features
- Flexible, pluggable parameter validation and munging.
- HTML documentation of endpoints.
- Respond with appropriate results using content negotiation.
TODO
- Automatically add rule doc to parameter doc
- Authentication
Endpoint
Endpoints can be defined using the module function. It takes a single options
parameter that is an object containing the following options.
- path - The endpoint path as used by the express router. See
http://expressjs.com/guide.html#routing for details.
(required)
- description - A human readable description of the endpoint. (required)
- example - An example URL for the endpoint.
- parameters - The set of parameters the endpoint accepts. See below
for details.
- rules - A set of custom rules to suppliment or override the
default rules. Default rules are defined below.
- handler - The function(req, res) that actually handles the
request. See
http://expressjs.com/guide.html#creating-a server
The validated/sanitized parameters are passed as
req.endpointParams. (required)
- view - The name of the doc template. There is a default.
- render_view - The name of the render template for text/html requests.
There is a default.
- stylesheets - Stylesheet URIs to inject into the views. There are
defaults.
mount(app)
Once the Endpoint
is created, it can be mounted on the express app by calling
endpoint.mount(app)
. mount(app)
is a convenience method. You can also set
things up manually like so:
app.get(endpoint.config.path, endpoint.middleware(), endpoint.config.handler);
middleware(selected)
endpoint.middleware(selected)
returns an Array
of middleware for the
Endpoint
. This included the render
and params
middleware by default.
The render
middleware adds a endpoint.render(payload)
function to the
res
object. The function will render an Object
in the appropriate
format according to the Accept
header.
The params
middleware is the meat of Endpoint
. It is where the parameters
and rules are used to parse the request. It adds an endpoint.params
field to
the req
object that contains the parsed parameters.
Catalog
Catalog is used to render the documentation for all Endpoint
s. It is called
via the module property function catalog(opts)
. It takes a single options
parameter that is an object containing the following properties.
- endpoints - Endpoint objects to catalog. (required)
- view - The name of the doc template. There is a default.
- stylesheets - Stylesheet URIs to inject into the views. There are
defaults.
Middleware
In addition to the Endpoint
middleware, there are two general middlewares.
errorHandler
This handler will render any parsing/validation errors for request
parameters, according to the Accept
header.
var errorHandler = require('express-endpoint').middleware.errorHandler;
app.use(errorHandler());
note This would be better if it were part of the Endpoint middleware, but
the current version of express doesn't support URL specifice errorHandler
middleware.
static
This handler provides the default express-endpoint
static content.
var static = require('express-endpoint').middleware.static;
app.use(static());
Parameters
Parameters are defined as an object with the following parameters.
- name - The name of the parameter.
- rules - An array of
String
rules for the parameter. - description - A detailed description of the parameter.
Rules are specified as strings, with a single optional parameter. The rule
name must match an existing default rule or a custom rule that you defined.
If the rule takes a parameter, it should be appended to the end of the rule
between parenthesis. To define a default rule, the rules would be as follows:
['default(mydefaultvalue)']
For rules that don't take parameters, the parenthesis can be omitted.
['once']
Rules are executed in the order specified. Builtin rules are described below.
Rule
express-endpoint
validates and sanitizes parameters via rules.
express-endpoint
comes with a set of builtin rules, and custom rules are
easily added. To add rules, set the 'rules' Endpoint
options. The default
rules can still be used as long as you don't use the same rule name with your
custom rules. Using the same name as a default rule will override that rule
with your implementation. All rules accept an Array
of values as input, but
can return a single value. Make sure that any rules that return a single value
are specified last.
- default(v) - Sets the parameter to v if it's not specified. This should
usually be called first.
- required - Ensures the parameter is specified at least once.
- max(n) - Ensures the parameter is not specified more then n times.
- once - Ensures the parameter is not specified more then one time.
It also changes the parameter from an Array to a single value.
- url - Ensures all specified values are valid URLs, and parses them
using urlparse.js (http://github.com/dokipen/urlparse.js).
- number - Converts all specified values to numbers, ensuring they are
valid numbers
- regex(r) - Ensures all specified values match the given regex r.
- boolean - Converts ('1', '', or 'true' is true). This also converts the
parameter from an Array to a single boolean object.
- callback - Ensures that the given value is a valid javascript function
name safe for use with JSONP, and that only one value is
given. Converts the value from an array to a single value.
- timestamp - Ensures that the give value is a valid epoch timestamp in
miliseconds or seconds, and converts to a javascript Date.
Due to accepting ms or s, dates before 1971 are not accepted
in seconds. If you are using non-current dates you should
probably roll your own.
A rule is defined as a function(parameterName, stringArgument)
that returns
a validator/sanitizer function(arrayOfParameterValues). It should throw an
Error for invalid values, or return a sanitized Array
of values for valid
values.
Here is an example of defining a custom rule to make sure a value is greater
than or equal to 18. It assumes that the parameter has already been processed
by the 'number' rule.
{ path: '/my/endpoint'
.. [snip] ..
, rules:
{ gte18: function(name, arg) {
return function(vals) {
return vals.map(function(val) {
if (val < 18) {
throw new Error('['+val+'] is less then 18')
}
})
}
}
}
}
You can also look at lib/rules.js for more examples.
Customizing Catalog/Documentation
To customize the CSS, mount your CSS somewhere in the app, then pass the URIs
to your custom CSS to the endpoint and catalog objects via the stylesheets
option. ex.
var express = require('express')
, app = express()
, express_endpoint = require('express-endpoint')
, Endpoint = express_endpoint.Endpoint
, catalog = express_endpoint.catalog;
app.use(static('public'));
app.use(express_endpoint.middleware.errorHandler());
var endpoint = new Endpoint({
stylesheets: ['public/my/styles.css'],
[snip]
});
endpoint.mount(app);
catalog = catalog({
stylesheets: ['public/my/styles.css'],
endpoints: [endpoint]
});
app.get('/docs', catalog);
app.listen(3000);
You can override the views similarly with the view
and render_view
options.
new Endpoint({
view: __dirname + '/myviews/doc.jade',
render_view: __dirname + '/myviews/render.jade'
})
catalog({
view: __dirname + '/myviews/doc.jade',
})