Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial workflow is implemented, yet not working
- Loading branch information
Showing
18 changed files
with
532 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
var Promise = require('bluebird'); | ||
|
||
module.exports = Promise.coroutine(function* (array, representation) { | ||
var response = { | ||
total : array.length, | ||
collection : Promise.coroutine(function* () { | ||
var promises = []; | ||
|
||
for (var i = 0; i < array.length; i++) { | ||
promises.push(representation(array[i])); | ||
} | ||
|
||
// yield here so it runs in parallel | ||
return yield promises; | ||
}); | ||
}; | ||
|
||
return response; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
var Promise = require('bluebird'); | ||
|
||
module.exports = Promise.coroutine(function (error) { | ||
var representation = {}; | ||
|
||
representation.error = error.message; | ||
representation.code = 406; | ||
|
||
this.status = 406; | ||
return representation; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
var Promise = require('bluebird'); | ||
|
||
module.exports = Promise.coroutine(function (url) { | ||
var representation = {}; | ||
|
||
representation.error = 'There is no resource located at ' + url; | ||
representation.code = 404; | ||
|
||
this.status = 404; | ||
return representation; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
var Promise = require('bluebird'); | ||
|
||
module.exports = Promise.coroutine(function (error) { | ||
var representation = {}; | ||
|
||
representation.error = error.message; | ||
representation.code = error.code; | ||
|
||
this.status = 500; | ||
return representation; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
var Promise = require('bluebird'); | ||
|
||
module.exports = Promise.coroutine(function (methods) { | ||
return methods; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
var Promise = require('bluebird'); | ||
var user_representation = require('./user'); | ||
|
||
module.exports = Promise.coroutine(function* (post) { | ||
var representation = {}; | ||
|
||
representation.name = post.title; | ||
representation.description = post.body; | ||
representation.user = Promise.coroutine(function* () { | ||
return yield user_representation(user); | ||
}); | ||
|
||
return representation; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
var Promise = require('bluebird'); | ||
|
||
module.exports = Promise.coroutine(function (user) { | ||
var representation = {}; | ||
|
||
representation.uri = '/users/' + user.id; | ||
representation.name = user.name; | ||
representation.url = 'http://dashron.com/users/' + user.id; | ||
representation.email = user.email; | ||
|
||
return representation; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
var Resource = require('../../lib/resource').Resource; | ||
|
||
/** | ||
* [many description] | ||
* @type {Resource} | ||
*/ | ||
module.exports.many = new Resource({ | ||
resources : { | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
var Resource = require('../../lib/resource').Resource; | ||
var Response = require('../../lib/response').Response; | ||
|
||
/** | ||
* [one description] | ||
* @type {Resource} | ||
*/ | ||
module.exports.many = new Resource({ | ||
resources : { | ||
'users' : require('./users').many, | ||
'posts' : require('./posts').many | ||
}, | ||
methods : { | ||
GET : function* (request) { | ||
return new Response(function () { | ||
return { | ||
"users" : "/users", | ||
"posts" : "/posts" | ||
}; | ||
}); | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
var Resource = require('../../../lib/resource').Resource; | ||
|
||
/** | ||
* [one description] | ||
* @type {Resource} | ||
*/ | ||
module.exports.one = new Resource({ | ||
}); | ||
|
||
/** | ||
* [many description] | ||
* @type {Resource} | ||
*/ | ||
module.exports.many = new Resource({ | ||
resources : { | ||
'#id' : module.exports.one | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
var Resource = require('../../lib/resource').Resource; | ||
var Response = require('../../lib/response').Response; | ||
|
||
var UserRepresentation = require('../representations/user'); | ||
|
||
/** | ||
* [one description] | ||
* @type {Resource} | ||
*/ | ||
module.exports.one = new Resource({ | ||
resources : { | ||
'posts' : require('./user/user.posts').many | ||
} | ||
}); | ||
|
||
/** | ||
* [many description] | ||
* @type {Resource} | ||
*/ | ||
module.exports.many = new Resource({ | ||
resources : { | ||
'#id' : module.exports.one | ||
}, | ||
methods : { | ||
GET : function* (request) { | ||
var users = yield users_model.getAll(); | ||
|
||
return new Response(CollectionRepresentation(users, UserRepresentation)); | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
var api = new (require('../lib/api').API)(); | ||
|
||
api.representations.users = require('./representations/user'); | ||
api.representations.post = require('./representations/post'); | ||
api.representations.options = require('./representations/options'); | ||
api.representations.errors = { | ||
unknown : require('./representations/errors/unknown'), | ||
notFound : require('./representations/errors/notFound') | ||
}; | ||
|
||
api.rootResource = require('./resources/root').many; | ||
|
||
require('http').createServer(function (request, http_response) { | ||
var body = ''; | ||
|
||
request.on('data', function (data) { | ||
body += data; | ||
}); | ||
|
||
request.on('end', function () { | ||
request.body = body; | ||
var response = api[request.method](request); | ||
response.writeTo(http_response); | ||
}); | ||
|
||
request.on('error', function (err) { | ||
var response = new Response(api.representations.errors.unknown(err)); | ||
|
||
response.status = 500; | ||
response.writeTo(http_response); | ||
}); | ||
|
||
}).listen(8080, function () { | ||
console.log('server has started'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,119 @@ | ||
module.exports.API = function API () { | ||
"use strict"; | ||
|
||
/** | ||
* api.js | ||
* Copyright(c) 2014 Aaron Hedges <aaron@dashron.com> | ||
* MIT Licensed | ||
*/ | ||
|
||
var url_module = require('url'); | ||
var Promise = require('bluebird'); | ||
var Response = require('./response').Response; | ||
|
||
var API = module.exports.API = function API () { | ||
this.resources = {}; | ||
this.representations = {}; | ||
}; | ||
|
||
API.prototype.resources = null; | ||
API.prototype.representations = null; | ||
|
||
API.prototype.GET = function (request) { | ||
return this.request('GET', request.url, request.body, request.headers); | ||
}; | ||
|
||
API.prototype.POST = function (request) { | ||
return this.request('POST', request.url, request.body, request.headers); | ||
} | ||
|
||
API.prototype.PUT = function (request) { | ||
return this.request('PUT', request.url, request.body, request.headers); | ||
} | ||
|
||
API.prototype.DELETE = function (request) { | ||
return this.request('DELETE', request.url, request.body, request.headers); | ||
} | ||
|
||
API.prototype.PATCH = function (request) { | ||
return this.request('PATCH', request.url, request.body, request.headers); | ||
} | ||
|
||
API.prototype.OPTIONS = function* (request) { | ||
if (request.headers['request-target'] === '*') { | ||
// applies to server | ||
return; | ||
} | ||
|
||
var OptionsRepresentation = new this.representations['options'](); | ||
var resource = this.locateResource(request.url.path); | ||
|
||
// this is not explicitly defined in the spec, we arbitrarily return an options representation object | ||
var resource_methods = resource.getValidMethods(); | ||
var response = new Response(OptionsRepresentation(resource_methods)); | ||
|
||
response.headers.allow = resource_methods; | ||
response.status = 200; | ||
|
||
return response; | ||
}; | ||
|
||
API.prototype.resources = null; | ||
/** | ||
* Make a request into the API | ||
* | ||
* @param string method | ||
* @param string url | ||
* @param string body | ||
* @param array headers | ||
* @return string | ||
*/ | ||
API.prototype.request = function (method, url, body, headers) { | ||
if (!this.rootResource) { | ||
throw new Error('You must configure a root resource before making API requests'); | ||
} | ||
|
||
if (!this.representations.errors.notFound) { | ||
throw new Error('You must configure a notFound representation before making API requests'); | ||
} | ||
|
||
url = url_module.parse(url, true); | ||
|
||
var resource = this.locateResource(url.pathname); | ||
var response = null; | ||
|
||
if (resource) { | ||
if (resource.allowsMethod(method)) { | ||
return resource[method](url, body, headers); | ||
} else { | ||
return new Response(this.representations.errors.notAcceptable()); | ||
} | ||
} else { | ||
return new Response(this.representations.errors.notFound(url)); | ||
} | ||
}; | ||
|
||
/** | ||
* Route the pathname directly to a resource object | ||
* | ||
* @param string pathname | ||
* @return Resource | ||
*/ | ||
API.prototype.locateResource = function (pathname) { | ||
// this will cause issues | ||
var parts = pathname.split('/'); | ||
// the uri starts with a forward slash, so we will have an empty string at the start of the array | ||
var part = parts.shift(); | ||
|
||
var resource = this.rootResource; | ||
|
||
// loop through every part separated by slashes and incrementally check them against the routes | ||
while (parts.length) { | ||
part = parts.shift(); | ||
resource = resource.getResource(part); | ||
|
||
if (!resource) { | ||
return false; | ||
} | ||
} | ||
|
||
return resource; | ||
} |
Oops, something went wrong.