mirror of https://gitee.com/bigwinds/arangodb
Foxx: Starting with the Foxx User Documentation
This commit is contained in:
parent
f483f1f137
commit
74e23f8670
|
@ -1,8 +1,64 @@
|
|||
# Foxx: Build APIs and simple web applications in ArangoDB
|
||||
Foxx {#UserManualFoxx}
|
||||
======================
|
||||
|
||||
Foxx: Build APIs and simple web applications in ArangoDB
|
||||
========================================================
|
||||
|
||||
**WARNING: The following documentation file is pure fiction,
|
||||
it is not yet finished**
|
||||
|
||||
Foxx is an easy way to create APIs and simple web applications
|
||||
from within **ArangoDB**.
|
||||
It is inspired by Sinatra, the classy Ruby web framework. If FoxxApplication is Sinatra,
|
||||
[ArangoDB Actions](http://www.arangodb.org/manuals/current/UserManualActions.html)
|
||||
are the corresponding `Rack`. They provide all the HTTP goodness.
|
||||
|
||||
So let's get started, shall we?
|
||||
|
||||
## Foxx Application
|
||||
|
||||
@copydetails JSF_foxx_application_initializer
|
||||
@copydetails JSF_foxx_application_start
|
||||
|
||||
### Handling Requests
|
||||
|
||||
@copydetails JSF_foxx_application_handleRequest
|
||||
@copydetails JSF_foxx_application_head
|
||||
@copydetails JSF_foxx_application_get
|
||||
@copydetails JSF_foxx_application_post
|
||||
@copydetails JSF_foxx_application_put
|
||||
@copydetails JSF_foxx_application_patch
|
||||
@copydetails JSF_foxx_application_delete
|
||||
|
||||
### Before and After Hooks
|
||||
|
||||
You can use the following two functions to do something
|
||||
before or respectively after the normal routing process
|
||||
is happening. You could use that for logging or to manipulate
|
||||
the request or response (translate it to a certain format for
|
||||
example).
|
||||
|
||||
@copydetails JSF_foxx_application_before
|
||||
@copydetails JSF_foxx_application_after
|
||||
|
||||
### More functionality
|
||||
|
||||
@copydetails JSF_foxx_application_helper
|
||||
@copydetails JSF_foxx_application_accepts
|
||||
|
||||
## The functions on a created FoxxApplication
|
||||
|
||||
When you have created your FoxxApplication you can now define routes
|
||||
on it. You provide each with a function that will handle
|
||||
the request. It gets two arguments (four, to be honest. But the
|
||||
other two are not relevant for now):
|
||||
|
||||
* The request object
|
||||
* The response object
|
||||
|
||||
|
||||
You can find more about those in their individual sections.
|
||||
|
||||
An application build with Foxx is written in JavaScript and deployed
|
||||
to ArangoDB directly. ArangoDB serves this application, you do not
|
||||
need a separate application server.
|
||||
|
|
|
@ -197,18 +197,18 @@ function SetRoutesFoxxApplicationSpec () {
|
|||
var myFunc = function () {},
|
||||
routes = app.routingInfo.routes;
|
||||
|
||||
app.requires = {
|
||||
app.requiresLibs = {
|
||||
a: 1
|
||||
};
|
||||
app.models = {
|
||||
app.requiresModels = {
|
||||
b: 2
|
||||
};
|
||||
app.get('/simple/route', myFunc);
|
||||
app.start("myContext");
|
||||
|
||||
assertEqual(app.routingInfo.routes[0].action.context, "myContext");
|
||||
assertEqual(app.routingInfo.routes[0].action.requires.a, 1);
|
||||
assertEqual(app.routingInfo.routes[0].action.models.b, 2);
|
||||
assertEqual(app.routingInfo.routes[0].action.requiresLibs.a, 1);
|
||||
assertEqual(app.routingInfo.routes[0].action.requiresModels.b, 2);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,15 +1,33 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true */
|
||||
/*global module, require, exports */
|
||||
|
||||
// Foxx is an easy way to create APIs and simple web applications
|
||||
// from within **ArangoDB**.
|
||||
// It is inspired by Sinatra, the classy Ruby web framework. If FoxxApplication is Sinatra,
|
||||
// [ArangoDB Actions](http://www.arangodb.org/manuals/current/UserManualActions.html)
|
||||
// are the corresponding `Rack`. They provide all the HTTP goodness.
|
||||
//
|
||||
// So let's get started, shall we?
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Foxx application
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2013 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Lucas Dohmen
|
||||
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FoxxApplication uses Underscore internally. This library is wonderful.
|
||||
var FoxxApplication,
|
||||
BaseMiddleware,
|
||||
FormatMiddleware,
|
||||
|
@ -20,12 +38,19 @@ var FoxxApplication,
|
|||
INTERNAL = require("internal"),
|
||||
internal = {};
|
||||
|
||||
// ArangoDB uses a certain structure we refer to as `UrlObject`.
|
||||
// With the following function (which is only internal, and not
|
||||
// exported) you can create an UrlObject with a given URL,
|
||||
// a constraint and a method. For example:
|
||||
//
|
||||
// internal.createUrlObject('/lecker/gans', null, 'get')
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_createUrlObject
|
||||
/// @brief create a new url object
|
||||
///
|
||||
/// ArangoDB uses a certain structure we refer to as `UrlObject`.
|
||||
/// With the following function (which is only internal, and not
|
||||
/// exported) you can create an UrlObject with a given URL,
|
||||
/// a constraint and a method. For example:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// internal.createUrlObject('/lecker/gans', null, 'get')
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.createUrlObject = function (url, constraint, method) {
|
||||
'use strict';
|
||||
var urlObject = {};
|
||||
|
@ -44,18 +69,22 @@ internal.createUrlObject = function (url, constraint, method) {
|
|||
return urlObject;
|
||||
};
|
||||
|
||||
// ## Creating a new Application
|
||||
// And that's FoxxApplication. It's a constructor, so call it like this:
|
||||
//
|
||||
// app = new FoxxApplication({
|
||||
// urlPrefix: "/wiese",
|
||||
// templateCollection: "my_templates"
|
||||
// })
|
||||
//
|
||||
// It takes two optional arguments as displayed above:
|
||||
//
|
||||
// * **The URL Prefix:** All routes you define within will be prefixed with it
|
||||
// * **The Template Collection:** More information in the template section
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_initializer
|
||||
/// @brief Create a new Application
|
||||
///
|
||||
/// And that's FoxxApplication. It's a constructor, so call it like this:
|
||||
/// It takes two optional arguments as displayed above:
|
||||
/// * **The URL Prefix:** All routes you define within will be prefixed with it
|
||||
/// * **The Template Collection:** More information in the template section
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app = new FoxxApplication({
|
||||
/// urlPrefix: "/wiese",
|
||||
/// templateCollection: "my_templates"
|
||||
/// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FoxxApplication = function (options) {
|
||||
'use strict';
|
||||
var urlPrefix, templateCollection, myMiddleware;
|
||||
|
@ -91,23 +120,17 @@ FoxxApplication = function (options) {
|
|||
];
|
||||
};
|
||||
|
||||
// ## The functions on a created FoxxApplication
|
||||
//
|
||||
// When you have created your FoxxApplication you can now define routes
|
||||
// on it. You provide each with a function that will handle
|
||||
// the request. It gets two arguments (four, to be honest. But the
|
||||
// other two are not relevant for now):
|
||||
//
|
||||
// * The request object
|
||||
// * The response object
|
||||
//
|
||||
// You can find more about those in their individual sections.
|
||||
_.extend(FoxxApplication.prototype, {
|
||||
// Sometimes it is a good idea to actually start the application
|
||||
// you wrote. If this precious moment has arrived, you should
|
||||
// use this function.
|
||||
// You have to provide the start function with the `applicationContext`
|
||||
// variable.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_start
|
||||
/// @brief Start the application
|
||||
///
|
||||
/// Sometimes it is a good idea to actually start the application
|
||||
/// you wrote. If this precious moment has arrived, you should
|
||||
/// use this function.
|
||||
/// You have to provide the start function with the `applicationContext`
|
||||
/// variable.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
start: function (context) {
|
||||
'use strict';
|
||||
var models = this.requiresModels,
|
||||
|
@ -125,18 +148,24 @@ _.extend(FoxxApplication.prototype, {
|
|||
db._collection("_routing").save(this.routingInfo);
|
||||
},
|
||||
|
||||
// The `handleRequest` method is the raw way to create a new
|
||||
// route. You probably wont call it directly, but it is used
|
||||
// in the other request methods:
|
||||
//
|
||||
// app.handleRequest("get", "/gaense", function (req, res) {
|
||||
// //handle the request
|
||||
// });
|
||||
//
|
||||
// When defining a route you can also define a so called 'parameterized'
|
||||
// route like `/gaense/:stable`. In this case you can later get the value
|
||||
// the user provided for `stable` via the `params` function (see the Request
|
||||
// object).
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_handleRequest
|
||||
/// @brief Handle a request
|
||||
///
|
||||
/// The `handleRequest` method is the raw way to create a new
|
||||
/// route. You probably wont call it directly, but it is used
|
||||
/// in the other request methods:
|
||||
///
|
||||
/// When defining a route you can also define a so called 'parameterized'
|
||||
/// route like `/gaense/:stable`. In this case you can later get the value
|
||||
/// the user provided for `stable` via the `params` function (see the Request
|
||||
/// object).
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app.handleRequest("get", "/gaense", function (req, res) {
|
||||
/// //handle the request
|
||||
/// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
handleRequest: function (method, route, argument1, argument2) {
|
||||
'use strict';
|
||||
var newRoute = {}, options, callback;
|
||||
|
@ -157,97 +186,124 @@ _.extend(FoxxApplication.prototype, {
|
|||
this.routingInfo.routes.push(newRoute);
|
||||
},
|
||||
|
||||
// ### Handle a `head` request
|
||||
// This handles requests from the HTTP verb `head`.
|
||||
// As with all other requests you can give an option as the third
|
||||
// argument, or leave it blank. You have to give a function as
|
||||
// the last argument however. It will get a request and response
|
||||
// object as its arguments
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_head
|
||||
/// @brief Handle a `head` request
|
||||
///
|
||||
/// This handles requests from the HTTP verb `head`.
|
||||
/// As with all other requests you can give an option as the third
|
||||
/// argument, or leave it blank. You have to give a function as
|
||||
/// the last argument however. It will get a request and response
|
||||
/// object as its arguments
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
head: function (route, argument1, argument2) {
|
||||
'use strict';
|
||||
this.handleRequest("head", route, argument1, argument2);
|
||||
},
|
||||
|
||||
// ### Manage a `get` request
|
||||
// This handles requests from the HTTP verb `get`.
|
||||
// See above for the arguments you can give. An example:
|
||||
//
|
||||
// app.get('/gaense/stall', function (req, res) {
|
||||
// // Take this request and deal with it!
|
||||
// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_get
|
||||
/// @brief Manage a `get` request
|
||||
///
|
||||
/// This handles requests from the HTTP verb `get`.
|
||||
/// See above for the arguments you can give. An example:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app.get('/gaense/stall', function (req, res) {
|
||||
/// // Take this request and deal with it!
|
||||
/// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
get: function (route, argument1, argument2) {
|
||||
'use strict';
|
||||
this.handleRequest("get", route, argument1, argument2);
|
||||
},
|
||||
|
||||
// ### Tackle a `post` request
|
||||
// This handles requests from the HTTP verb `post`.
|
||||
// See above for the arguments you can give. An example:
|
||||
//
|
||||
// app.post('/gaense/stall', function (req, res) {
|
||||
// // Take this request and deal with it!
|
||||
// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_post
|
||||
/// @brief Tackle a `post` request
|
||||
///
|
||||
/// This handles requests from the HTTP verb `post`.
|
||||
/// See above for the arguments you can give. An example:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app.post('/gaense/stall', function (req, res) {
|
||||
/// // Take this request and deal with it!
|
||||
/// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
post: function (route, argument1, argument2) {
|
||||
'use strict';
|
||||
this.handleRequest("post", route, argument1, argument2);
|
||||
},
|
||||
|
||||
// ### Sort out a `put` request
|
||||
// This handles requests from the HTTP verb `put`.
|
||||
// See above for the arguments you can give. An example:
|
||||
//
|
||||
// app.put('/gaense/stall', function (req, res) {
|
||||
// // Take this request and deal with it!
|
||||
// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_put
|
||||
/// @brief Sort out a `put` request
|
||||
///
|
||||
/// This handles requests from the HTTP verb `put`.
|
||||
/// See above for the arguments you can give. An example:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app.put('/gaense/stall', function (req, res) {
|
||||
/// // Take this request and deal with it!
|
||||
/// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
put: function (route, argument1, argument2) {
|
||||
'use strict';
|
||||
this.handleRequest("put", route, argument1, argument2);
|
||||
},
|
||||
|
||||
// ### Take charge of a `patch` request
|
||||
// This handles requests from the HTTP verb `patch`.
|
||||
// See above for the arguments you can give. An example:
|
||||
//
|
||||
// app.patch('/gaense/stall', function (req, res) {
|
||||
// // Take this request and deal with it!
|
||||
// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_patch
|
||||
/// @brief Take charge of a `patch` request
|
||||
///
|
||||
/// This handles requests from the HTTP verb `patch`.
|
||||
/// See above for the arguments you can give. An example:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app.patch('/gaense/stall', function (req, res) {
|
||||
/// // Take this request and deal with it!
|
||||
/// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
patch: function (route, argument1, argument2) {
|
||||
'use strict';
|
||||
this.handleRequest("patch", route, argument1, argument2);
|
||||
},
|
||||
|
||||
// ### Respond to a `delete` request
|
||||
// This handles requests from the HTTP verb `delete`.
|
||||
// See above for the arguments you can give.
|
||||
// **A word of warning:** Do not forget that `delete` is
|
||||
// a reserved word in JavaScript so call it as follows:
|
||||
//
|
||||
// app['delete']('/gaense/stall', function (req, res) {
|
||||
// // Take this request and deal with it!
|
||||
// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_delete
|
||||
/// @brief Respond to a `delete` request
|
||||
///
|
||||
/// This handles requests from the HTTP verb `delete`.
|
||||
/// See above for the arguments you can give.
|
||||
/// **A word of warning:** Do not forget that `delete` is
|
||||
/// a reserved word in JavaScript so call it as follows:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app['delete']('/gaense/stall', function (req, res) {
|
||||
/// // Take this request and deal with it!
|
||||
/// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
'delete': function (route, argument1, argument2) {
|
||||
'use strict';
|
||||
this.handleRequest("delete", route, argument1, argument2);
|
||||
},
|
||||
|
||||
// ## Before and After Hooks
|
||||
// You can use the following two functions to do something
|
||||
// before or respectively after the normal routing process
|
||||
// is happening. You could use that for logging or to manipulate
|
||||
// the request or response (translate it to a certain format for
|
||||
// example).
|
||||
|
||||
// ### Before
|
||||
// The before function takes a path on which it should watch
|
||||
// and a function that it should execute before the routing
|
||||
// takes place. If you do omit the path, the function will
|
||||
// be executed before each request, no matter the path.
|
||||
// Your function gets a Request and a Response object.
|
||||
// An example:
|
||||
//
|
||||
// app.before('/high/way', function(req, res) {
|
||||
// //Do some crazy request logging
|
||||
// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_before
|
||||
/// @brief Before
|
||||
///
|
||||
/// The before function takes a path on which it should watch
|
||||
/// and a function that it should execute before the routing
|
||||
/// takes place. If you do omit the path, the function will
|
||||
/// be executed before each request, no matter the path.
|
||||
/// Your function gets a Request and a Response object.
|
||||
/// An example:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app.before('/high/way', function(req, res) {
|
||||
/// //Do some crazy request logging
|
||||
/// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
before: function (path, func) {
|
||||
'use strict';
|
||||
if (_.isUndefined(func)) {
|
||||
|
@ -263,16 +319,21 @@ _.extend(FoxxApplication.prototype, {
|
|||
});
|
||||
},
|
||||
|
||||
// ### After
|
||||
// This works pretty similar to the before function.
|
||||
// But it acts after the execution of the handlers
|
||||
// (Big surprise, I suppose).
|
||||
//
|
||||
// An example:
|
||||
//
|
||||
// app.after('/high/way', function(req, res) {
|
||||
// //Do some crazy response logging
|
||||
// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_after
|
||||
/// @brief After
|
||||
///
|
||||
/// This works pretty similar to the before function.
|
||||
/// But it acts after the execution of the handlers
|
||||
/// (Big surprise, I suppose).
|
||||
///
|
||||
/// An example:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app.after('/high/way', function(req, res) {
|
||||
/// //Do some crazy response logging
|
||||
/// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
after: function (path, func) {
|
||||
'use strict';
|
||||
if (_.isUndefined(func)) {
|
||||
|
@ -288,27 +349,36 @@ _.extend(FoxxApplication.prototype, {
|
|||
});
|
||||
},
|
||||
|
||||
// ## The ViewHelper concept
|
||||
// If you want to use a function inside your templates, the ViewHelpers
|
||||
// will come to rescue you. Define them on your app like this:
|
||||
//
|
||||
// app.helper("link_to", function (identifier) {
|
||||
// return urlRepository[identifier];
|
||||
// });
|
||||
//
|
||||
// Then you can just call this function in your template's JavaScript
|
||||
// blocks.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_helper
|
||||
/// @brief The ViewHelper concept
|
||||
///
|
||||
/// If you want to use a function inside your templates, the ViewHelpers
|
||||
/// will come to rescue you. Define them on your app like this:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app.helper("link_to", function (identifier) {
|
||||
/// return urlRepository[identifier];
|
||||
/// });
|
||||
///
|
||||
/// Then you can just call this function in your template's JavaScript
|
||||
/// blocks.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
helper: function (name, func) {
|
||||
'use strict';
|
||||
this.helperCollection[name] = func;
|
||||
},
|
||||
|
||||
// ## Shortform for using the FormatMiddleware
|
||||
//
|
||||
// More information about the FormatMiddleware in the corresponding section.
|
||||
// This is a shortcut to add the middleware to your application:
|
||||
//
|
||||
// app.accepts(["json"], "json");
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_application_accepts
|
||||
/// @brief Shortform for using the FormatMiddleware
|
||||
///
|
||||
/// More information about the FormatMiddleware in the corresponding section.
|
||||
/// This is a shortcut to add the middleware to your application:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app.accepts(["json"], "json");
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
accepts: function (allowedFormats, defaultFormat) {
|
||||
'use strict';
|
||||
|
||||
|
@ -322,9 +392,13 @@ _.extend(FoxxApplication.prototype, {
|
|||
});
|
||||
|
||||
|
||||
// ## The Base Middleware
|
||||
// The `BaseMiddleware` manipulates the request and response
|
||||
// objects to give you a nicer API.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_BaseMiddleware_initializer
|
||||
/// @brief The Base Middleware
|
||||
///
|
||||
/// The `BaseMiddleware` manipulates the request and response
|
||||
/// objects to give you a nicer API.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
BaseMiddleware = function (templateCollection, helperCollection) {
|
||||
'use strict';
|
||||
var middleware = function (request, response, options, next) {
|
||||
|
@ -332,29 +406,39 @@ BaseMiddleware = function (templateCollection, helperCollection) {
|
|||
requestFunctions,
|
||||
_ = require("underscore");
|
||||
|
||||
// ### The Request Object
|
||||
// Every request object has the following attributes from the underlying Actions,
|
||||
// amongst others:
|
||||
//
|
||||
// * path: The complete path as supplied by the user
|
||||
//
|
||||
// FoxxApplication adds the following methods to this request object:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The Request Object
|
||||
/// Every request object has the following attributes from the underlying Actions,
|
||||
/// amongst others:
|
||||
///
|
||||
/// * path: The complete path as supplied by the user
|
||||
///
|
||||
/// FoxxApplication adds the following methods to this request object:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
requestFunctions = {
|
||||
// ### The superfluous `body` function
|
||||
// Get the body of the request
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_BaseMiddleware_request_body
|
||||
/// @brief The superfluous `body` function
|
||||
///
|
||||
/// Get the body of the request
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
body: function () {
|
||||
return this.requestBody;
|
||||
},
|
||||
|
||||
// ### The jinxed `params` function
|
||||
// Get the parameters of the request. This process is two-fold:
|
||||
//
|
||||
// 1. If you have defined an URL like `/test/:id` and the user
|
||||
// requested `/test/1`, the call `params("id")` will return `1`.
|
||||
// 2. If you have defined an URL like `/test` and the user gives a
|
||||
// query component, the query parameters will also be returned.
|
||||
// So for example if the user requested `/test?a=2`, the call
|
||||
// `params("a")` will return `2`.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_BaseMiddleware_request_params
|
||||
/// @brief The jinxed `params` function
|
||||
///
|
||||
/// Get the parameters of the request. This process is two-fold:
|
||||
///
|
||||
/// 1. If you have defined an URL like `/test/:id` and the user
|
||||
/// requested `/test/1`, the call `params("id")` will return `1`.
|
||||
/// 2. If you have defined an URL like `/test` and the user gives a
|
||||
/// query component, the query parameters will also be returned.
|
||||
/// So for example if the user requested `/test?a=2`, the call
|
||||
/// `params("a")` will return `2`.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
params: function (key) {
|
||||
var ps = {};
|
||||
_.extend(ps, this.urlParameters);
|
||||
|
@ -363,36 +447,50 @@ BaseMiddleware = function (templateCollection, helperCollection) {
|
|||
}
|
||||
};
|
||||
|
||||
// ### The Response Object
|
||||
// Every response object has the following attributes from the underlying Actions:
|
||||
//
|
||||
// * contentType
|
||||
// * responseCode
|
||||
// * body
|
||||
// * headers (an object)
|
||||
//
|
||||
// FoxxApplication adds the following methods to this response object.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The Response Object
|
||||
/// Every response object has the following attributes from the underlying Actions:
|
||||
///
|
||||
/// * contentType
|
||||
/// * responseCode
|
||||
/// * body
|
||||
/// * headers (an object)
|
||||
///
|
||||
/// FoxxApplication adds the following methods to this response object.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
responseFunctions = {
|
||||
// ### The straightforward `status` function
|
||||
// Set the status code of your response, for example:
|
||||
//
|
||||
// response.status(404);
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_BaseMiddleware_response_status
|
||||
/// @brief The straightforward `status` function
|
||||
///
|
||||
/// Set the status code of your response, for example:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// response.status(404);
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
status: function (code) {
|
||||
this.responseCode = code;
|
||||
},
|
||||
|
||||
// ### The radical `set` function
|
||||
// Set a header attribute, for example:
|
||||
//
|
||||
// response.set("Content-Length", 123);
|
||||
// response.set("Content-Type", "text/plain");
|
||||
//
|
||||
// or alternatively:
|
||||
//
|
||||
// response.set({
|
||||
// "Content-Length": "123",
|
||||
// "Content-Type": "text/plain"
|
||||
// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_BaseMiddleware_response_set
|
||||
/// @brief The radical `set` function
|
||||
///
|
||||
/// Set a header attribute, for example:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// response.set("Content-Length", 123);
|
||||
/// response.set("Content-Type", "text/plain");
|
||||
///
|
||||
/// or alternatively:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// response.set({
|
||||
/// "Content-Length": "123",
|
||||
/// "Content-Type": "text/plain"
|
||||
/// });
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
set: function (key, value) {
|
||||
var attributes = {};
|
||||
if (_.isUndefined(value)) {
|
||||
|
@ -412,46 +510,57 @@ BaseMiddleware = function (templateCollection, helperCollection) {
|
|||
}, this);
|
||||
},
|
||||
|
||||
// ### The magical `json` function
|
||||
// Set the content type to JSON and the body to the
|
||||
// JSON encoded object you provided.
|
||||
//
|
||||
// response.json({'born': 'December 12, 1915'});
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_BaseMiddleware_response_json
|
||||
/// @brief The magical `json` function
|
||||
///
|
||||
/// Set the content type to JSON and the body to the
|
||||
/// JSON encoded object you provided.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// response.json({'born': 'December 12, 1915'});
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
json: function (obj) {
|
||||
this.contentType = "application/json";
|
||||
this.body = JSON.stringify(obj);
|
||||
},
|
||||
|
||||
// ### The mysterious `render` function
|
||||
// If you initialize your FoxxApplication with a `templateCollection`,
|
||||
// you're in luck now.
|
||||
// It expects documents in the following form in this collection:
|
||||
//
|
||||
// {
|
||||
// path: "high/way",
|
||||
// content: "hallo <%= username %>",
|
||||
// contentType: "text/plain",
|
||||
// templateLanguage: "underscore"
|
||||
// }
|
||||
//
|
||||
// The `content` is the string that will be rendered by the template
|
||||
// processor. The `contentType` is the type of content that results
|
||||
// from this call. And with the `templateLanguage` you can choose
|
||||
// your template processor. There is only one choice now: `underscore`.
|
||||
//
|
||||
// If you call render, FoxxApplication will look
|
||||
// into the this collection and search by the path attribute.
|
||||
// It will then render the template with the given data:
|
||||
//
|
||||
// response.render("high/way", {username: 'FoxxApplication'})
|
||||
//
|
||||
// Which would set the body of the response to `hello FoxxApplication` with the
|
||||
// template defined above. It will also set the `contentType` to
|
||||
// `text/plain` in this case.
|
||||
//
|
||||
// In addition to the attributes you provided, you also have access to
|
||||
// all your view helpers. How to define them? Read above in the
|
||||
// ViewHelper section.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_BaseMiddleware_response_render
|
||||
/// @brief The mysterious `render` function
|
||||
///
|
||||
/// If you initialize your FoxxApplication with a `templateCollection`,
|
||||
/// you're in luck now.
|
||||
/// It expects documents in the following form in this collection:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// {
|
||||
/// path: "high/way",
|
||||
/// content: "hallo <%= username %>",
|
||||
/// contentType: "text/plain",
|
||||
/// templateLanguage: "underscore"
|
||||
/// }
|
||||
///
|
||||
/// The `content` is the string that will be rendered by the template
|
||||
/// processor. The `contentType` is the type of content that results
|
||||
/// from this call. And with the `templateLanguage` you can choose
|
||||
/// your template processor. There is only one choice now: `underscore`.
|
||||
///
|
||||
/// If you call render, FoxxApplication will look
|
||||
/// into the this collection and search by the path attribute.
|
||||
/// It will then render the template with the given data:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// response.render("high/way", {username: 'FoxxApplication'})
|
||||
///
|
||||
/// Which would set the body of the response to `hello FoxxApplication` with the
|
||||
/// template defined above. It will also set the `contentType` to
|
||||
/// `text/plain` in this case.
|
||||
///
|
||||
/// In addition to the attributes you provided, you also have access to
|
||||
/// all your view helpers. How to define them? Read above in the
|
||||
/// ViewHelper section.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
render: function (templatePath, data) {
|
||||
var template;
|
||||
|
||||
|
@ -474,9 +583,9 @@ BaseMiddleware = function (templateCollection, helperCollection) {
|
|||
}
|
||||
};
|
||||
|
||||
// Now enhance the request and response as described above and call next at the
|
||||
// end of this middleware (otherwise your application would never
|
||||
// be executed. Would be a shame, really).
|
||||
/// Now enhance the request and response as described above and call next at the
|
||||
/// end of this middleware (otherwise your application would never
|
||||
/// be executed. Would be a shame, really).
|
||||
request = _.extend(request, requestFunctions);
|
||||
response = _.extend(response, responseFunctions);
|
||||
next();
|
||||
|
@ -488,32 +597,37 @@ BaseMiddleware = function (templateCollection, helperCollection) {
|
|||
};
|
||||
};
|
||||
|
||||
// ## The Format Middleware
|
||||
// Unlike the `BaseMiddleware` this Middleware is only loaded if you
|
||||
// want it. This Middleware gives you Rails-like format handling via
|
||||
// the `extension` of the URL or the accept header.
|
||||
// Say you request an URL like `/people.json`:
|
||||
// The `FormatMiddleware` will set the format of the request to JSON
|
||||
// and then delete the `.json` from the request. You can therefore write
|
||||
// handlers that do not take an `extension` into consideration and instead
|
||||
// handle the format via a simple String.
|
||||
// To determine the format of the request it checks the URL and then
|
||||
// the `accept` header. If one of them gives a format or both give
|
||||
// the same, the format is set. If the formats are not the same,
|
||||
// an error is raised.
|
||||
//
|
||||
// Use it by calling:
|
||||
//
|
||||
// FormatMiddleware = require('foxx').FormatMiddleware;
|
||||
// app.before("/*", FormatMiddleware.new(['json']));
|
||||
//
|
||||
// or the shortcut:
|
||||
//
|
||||
// app.accepts(['json']);
|
||||
//
|
||||
// In both forms you can give a default format as a second parameter,
|
||||
// if no format could be determined. If you give no `defaultFormat` this
|
||||
// case will be handled as an error.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief The Format Middleware
|
||||
///
|
||||
/// Unlike the `BaseMiddleware` this Middleware is only loaded if you
|
||||
/// want it. This Middleware gives you Rails-like format handling via
|
||||
/// the `extension` of the URL or the accept header.
|
||||
/// Say you request an URL like `/people.json`:
|
||||
/// The `FormatMiddleware` will set the format of the request to JSON
|
||||
/// and then delete the `.json` from the request. You can therefore write
|
||||
/// handlers that do not take an `extension` into consideration and instead
|
||||
/// handle the format via a simple String.
|
||||
/// To determine the format of the request it checks the URL and then
|
||||
/// the `accept` header. If one of them gives a format or both give
|
||||
/// the same, the format is set. If the formats are not the same,
|
||||
/// an error is raised.
|
||||
///
|
||||
/// Use it by calling:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// FormatMiddleware = require('foxx').FormatMiddleware;
|
||||
/// app.before("/*", FormatMiddleware.new(['json']));
|
||||
///
|
||||
/// or the shortcut:
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// app.accepts(['json']);
|
||||
///
|
||||
/// In both forms you can give a default format as a second parameter,
|
||||
/// if no format could be determined. If you give no `defaultFormat` this
|
||||
/// case will be handled as an error.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
FormatMiddleware = function (allowedFormats, defaultFormat) {
|
||||
'use strict';
|
||||
var stringRepresentation, middleware = function (request, response, options, next) {
|
||||
|
@ -588,8 +702,8 @@ FormatMiddleware = function (allowedFormats, defaultFormat) {
|
|||
};
|
||||
};
|
||||
|
||||
// We finish off with exporting FoxxApplication and the middlewares.
|
||||
// Everything else will remain our secret.
|
||||
/// We finish off with exporting FoxxApplication and the middlewares.
|
||||
/// Everything else will remain our secret.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief loads a manifest file
|
||||
|
@ -654,11 +768,15 @@ exports.FoxxApplication = FoxxApplication;
|
|||
exports.BaseMiddleware = BaseMiddleware;
|
||||
exports.FormatMiddleware = FormatMiddleware;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint"
|
||||
// End:
|
||||
/// -----------------------------------------------------------------------------
|
||||
/// --SECTION-- END-OF-FILE
|
||||
/// -----------------------------------------------------------------------------
|
||||
|
||||
/// Local Variables:
|
||||
/// mode: outline-minor
|
||||
/// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint"
|
||||
/// End:
|
||||
|
|
Loading…
Reference in New Issue