Comparing version 0.4.5 to 0.4.6
## 0.4.x | ||
### 0.4.6 | ||
* Add resource and action middleware abstraction | ||
* Minor corrections to existing README for previous features | ||
### 0.4.5 | ||
@@ -4,0 +8,0 @@ Enhancement - getUserString is now shared as an overrideable global config option |
{ | ||
"name": "autohost", | ||
"version": "0.4.5", | ||
"version": "0.4.6", | ||
"description": "Resource driven, transport agnostic host", | ||
@@ -83,3 +83,3 @@ "main": "src/index.js", | ||
}, | ||
"license": "MIT License - http://opensource.org/licenses/MIT", | ||
"license": "MIT", | ||
"bugs": { | ||
@@ -86,0 +86,0 @@ "url": "https://github.com/LeanKit-Labs/autohost/issues" |
@@ -224,2 +224,3 @@ # autohost | ||
urlPrefix: '', // URL prefix for all actions in this resource | ||
middleware: [],// one or more middleware functions to mount to the resource's url | ||
actions: { | ||
@@ -230,2 +231,3 @@ send: { | ||
topic: 'send', // topic segment appended the resource name | ||
middleware: [], // one or more middleware functions to mount to the action's url | ||
handle: function( envelope ) { | ||
@@ -264,2 +266,3 @@ // see section on envelope for more detail | ||
urlPrefix: '', // URL prefix for all actions in this resource | ||
middleware: [],// one or more middleware functions to mount to the resource's url | ||
actions: { | ||
@@ -270,2 +273,3 @@ send: { | ||
topic: 'send', // topic segment appended the resource name | ||
middleware: [], // one or more middleware functions to mount to the action's url | ||
handle: function( envelope ) { | ||
@@ -287,10 +291,45 @@ // see section on envelope for more detail | ||
Note: If defining resources for use with [hyped](https://github.com/leankit-labs/hyped) - the resource name is not automatically pre-pended to the url. | ||
### resources | ||
### static | ||
You can host nested static files under a resource using this property. The directory and its contents found at the path will be hosted after the resource name in the URL. | ||
To enable this, simply add the module names as an array in the `modules` property of the configuration hash passed to init. | ||
### middleware | ||
Provides a mechanism for defining resource-level middleware either in a single function or in a list of functions. These functions are provided with an envelope and are able to make changes to it before it reaches action-specific middleware or the handle call. | ||
Below are several examples of different middleware patterns. This should demonstrate both synchronous and asynchronous patterns for proceding and short-circuiting the stack. | ||
```javascript | ||
... | ||
// all middleware must return either the result of next or a promise/data structure | ||
middleware: [ | ||
function( envelope, next ) { | ||
// invokes the next middelware or handle call | ||
return next(); | ||
}, | ||
function( envelope, next ) { | ||
// demonstrates returning a data structure | ||
if( envelope.data.example === 1 ) { | ||
return { data: { message: 'This will short circuit the stack and respond immediately' } }; | ||
} else if( envelope.data.example === 2 ) { | ||
// demonstrates returning next asynchronously | ||
return somethingPromisey() | ||
.then( function( x ) { | ||
envelope.context.importantThing = x; | ||
return next(); | ||
} ); | ||
} else if( envelope.data.example === 3 ) { | ||
// demonstrates short-circuiting a stack via a promise | ||
return anotherPromise() | ||
.then( function( x ) { | ||
return { data: x }; | ||
} ); | ||
} else { | ||
return next(); | ||
} | ||
} | ||
} | ||
... | ||
``` | ||
## Actions | ||
@@ -334,2 +373,8 @@ The hash of actions are the operations exposed on a resource on the available transports. | ||
### middleware | ||
Provides a mechanism for defining action-level middleware either in a single function or in a list of functions. These functions are provided with an envelope and are able to make changes to it before it reaches the handle call. | ||
__IMPORTANT__ | ||
Middleware **must** return either the result of the `next` call _or_ a promise/data structure to short circuit the stack with a response. They are mutually exclusive. Do not call both. Do not fail to return one or the other. | ||
### handle | ||
@@ -467,2 +512,4 @@ The handle is a callback that will be invoked if the caller has adequate permissions. The handle call can return a hash (or a promise that resolve to one) with the following properties: | ||
To enable this, simply add the module names as an array in the `modules` property of the configuration hash passed to init. | ||
## HTTP Transport | ||
@@ -469,0 +516,0 @@ The http transport API has three methods to add middleware, API routes and static content routes. While resources are the preferred means of adding static and API routes, it's very common to add application specific middleware. Custom middleware is added *after* standard middleware and passport (unless specific middleware was disabled via configuration). |
@@ -40,6 +40,6 @@ var _ = require( 'lodash' ); | ||
var addAction = function( resourceName, actionName, handle, method, url, topic ) { | ||
var addAction = function( resourceName, actionName, handle, method, url, topic, resourceMiddleware, actionMiddleware ) { | ||
var fqn = [ resourceName, actionName ].join( '.' ); | ||
httpAdapter.action( | ||
{ name: resourceName }, | ||
{ name: resourceName, middleware: resourceMiddleware }, | ||
actionName, | ||
@@ -49,2 +49,3 @@ { | ||
url: url || '/' + actionName, | ||
middleware: actionMiddleware, | ||
handle: handle | ||
@@ -51,0 +52,0 @@ }, |
@@ -71,2 +71,13 @@ var path = require( 'path' ); | ||
function executeStack( resource, action, envelope, stack ) { | ||
var calls = stack.slice( 0 ); | ||
var call = calls.shift(); | ||
if( call ) { | ||
return call.bind( resource )( envelope, executeStack.bind( undefined, resource, action, envelope, calls ) ); | ||
} else { | ||
log.error( 'Invalid middelware was supplied in resource "%s", action "%s".', resource.name, action.name ); | ||
return { status: 500, data: { message: 'The server failed to provide a response' } }; | ||
} | ||
} | ||
function getActionMetadata( state, resource, actionName, action, meta, resources ) { | ||
@@ -116,5 +127,13 @@ var url = buildActionUrl( state, resource.name, actionName, action, resource, resources ); | ||
var result; | ||
var stack = []; | ||
if( resource.middleware ) { | ||
stack = stack.concat( resource.middleware ); | ||
} | ||
if( action.middleware ) { | ||
stack = stack.concat( action.middleware ); | ||
} | ||
stack.push( action.handle ); | ||
if ( meta.handleErrors ) { | ||
try { | ||
result = action.handle.apply( resource, [ envelope ] ); | ||
result = executeStack( resource, action, envelope, stack ); | ||
} catch ( err ) { | ||
@@ -126,3 +145,3 @@ log.error( 'API EXCEPTION! route: %s %s failed with %s', | ||
} else { | ||
result = action.handle.apply( resource, [ envelope ] ); | ||
result = executeStack( resource, action, envelope, stack ); | ||
} | ||
@@ -165,2 +184,3 @@ if ( result ) { | ||
_.each( resource.actions, function( action, actionName ) { | ||
action.name = actionName; | ||
wireupAction( state, resource, actionName, action, meta, resources ); | ||
@@ -167,0 +187,0 @@ } ); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
146153
2474
755
3