ArangoDB v2.8 reached End of Life (EOL) and is no longer supported.
This documentation is outdated. Please see the most recent version here: Try latest
Details on Controller
Create
new Controller(applicationContext, options)
This creates a new Controller. The first argument is the controller
context available in the variable applicationContext. The second one is an
options array with the following attributes:
- urlPrefix: All routes you define within will be prefixed with it.
Examples
app = new Controller(applicationContext, {
urlPrefix: "/meadow"
});
HTTP Methods
get
Controller.get(path, callback)
Defines a new route on path
that handles requests from the HTTP verb get
.
This route can also be ‘parameterized’ like /goose/:barn
.
In this case you can later get the value the user provided for barn
via the params
function in the request
.
The function defined in callback
will be invoked whenever this type of
request is recieved.
callback
get’s two arguments request
and response
, see below for further
information about these objects.
Examples
app.get('/goose/barn', function (req, res) {
// Take this request and deal with it!
});
head
Controller.head(path, callback)
Defines a new route on path
that handles requests from the HTTP verb head
.
This route can also be ‘parameterized’ like /goose/:barn
.
In this case you can later get the value the user provided for barn
via the params
function in the request
.
The function defined in callback
will be invoked whenever this type of
request is recieved.
callback
get’s two arguments request
and response
, see below for further
information about these objects.
Examples
app.head('/goose/barn', function (req, res) {
// Take this request and deal with it!
});
post
Controller.post(path, callback)
Defines a new route on path
that handles requests from the HTTP verb post
.
This route can also be ‘parameterized’ like /goose/:barn
.
In this case you can later get the value the user provided for barn
via the params
function in the request
.
The function defined in callback
will be invoked whenever this type of
request is recieved.
callback
get’s two arguments request
and response
, see below for further
information about these objects.
Examples
app.post('/goose/barn', function (req, res) {
// Take this request and deal with it!
});
put
Controller.put(path, callback)
Defines a new route on path
that handles requests from the HTTP verb put
.
This route can also be ‘parameterized’ like /goose/:barn
.
In this case you can later get the value the user provided for barn
via the params
function in the request
.
The function defined in callback
will be invoked whenever this type of
request is recieved.
callback
get’s two arguments request
and response
, see below for further
information about these objects.
Examples
app.put('/goose/barn', function (req, res) {
// Take this request and deal with it!
});
patch
Controller.patch(path, callback)
Defines a new route on path
that handles requests from the HTTP verb patch
.
This route can also be ‘parameterized’ like /goose/:barn
.
In this case you can later get the value the user provided for barn
via the params
function in the request
.
The function defined in callback
will be invoked whenever this type of
request is recieved.
callback
get’s two arguments request
and response
, see below for further
information about these objects.
Examples
app.patch('/goose/barn', function (req, res) {
// Take this request and deal with it!
});
delete
Controller.delete(path, callback)
Defines a new route on path
that handles requests from the HTTP verb delete
.
This route can also be ‘parameterized’ like /goose/:barn
.
In this case you can later get the value the user provided for barn
via the params
function in the request
.
The function defined in callback
will be invoked whenever this type of
request is recieved.
callback
get’s two arguments request
and response
, see below for further
information about these objects.
Examples
app.delete('/goose/barn', function (req, res) {
// Take this request and deal with it!
});
Documenting and constraining a specific route
If you now want to document your route, you can use JSDoc style comments (a
multi-line comment block where the first line starts with /**
instead
of /*
) above your routes to do that:
/** Get all foxxes
*
* If you want to get all foxxes, please use this
* method to do that.
*/
app.get("/foxxes", function () {
// ...
});
The first line will be treated as a summary (For optical reasons in the produced documentation, the summary is restricted to 60 characters). All following lines will be treated as additional notes shown in the detailed view of the route documentation. With the provided information, Foxx will generate a nice documentation for you. Furthermore you can describe your API by chaining the following methods onto your path definition:
pathParam
Route.pathParam(id, options)
If you defined a route “/foxx/:name”, containing a parameter called name
you can
constrain which format this parameter is allowed to have.
This format is defined using joi in the options
parameter.
Using this function will at first allow you to access this parameter in your
route handler using req.params(id)
, will reject any request having a paramter
that does not match the joi definition and creates a documentation for this
parameter in ArangoDBs WebInterface.
For more information on joi see the official Joi documentation.
Parameter
- id: name of the param.
- options: a joi schema or an object with the following properties:
- type: a joi schema.
- description: documentation description for the parameter.
- required (optional): whether the parameter is required. Default: determined by type.
Examples
app.get("/foxx/:name", function { // Do something }).pathParam("name", joi.string().required().description("Name of the Foxx"));
You can also pass in a configuration object instead:app.get("/foxx/:name", function { // Do something }).pathParam("name", { type: joi.string(), required: true, description: "Name of the Foxx" });
queryParam
Route.queryParam(id, options)
Describe a query parameter:
If you defined a route “/foxx”, you can allow a query paramter with the
name id
on it and constrain the format of this parameter by giving it a joi type in the options
parameter.
Using this function will at first allow you to access this parameter in your
route handler using req.params(id)
, will reject any request having a paramter
that does not match the joi definition and creates a documentation for this
parameter in ArangoDBs WebInterface.
For more information on joi see the official Joi documentation.
You can also provide a description of this parameter and
whether you can provide the parameter multiple times.
Parameter
- id: name of the parameter
- options: a joi schema or an object with the following properties:
- type: a joi schema
- description: documentation description for this param.
- required (optional): whether the param is required. Default: determined by type.
- allowMultiple (optional): whether the param can be specified more than once. Default:
false
.
Examples
app.get("/foxx", function { // Do something }).queryParam("id", joi.string() .required() .description("Id of the Foxx") .meta({allowMultiple: false}) });
You can also pass in a configuration object instead:app.get("/foxx", function { // Do something }).queryParam("id", { type: joi.string().required().description("Id of the Foxx"), allowMultiple: false });
bodyParam
Route.bodyParam(paramName, options)
Defines that this route expects a JSON body when requested and binds it to
a pseudo parameter with the name paramName
.
The body can than be read in the the handler using req.params(paramName)
on the request object.
In the options
parameter you can define how a valid request body should look like.
This definition can be done in two ways, either using joi directly.
Accessing the body in this case will give you a JSON object.
The other way is to use a Foxx Model.
Accessing the body in this case will give you an instance of this Model.
For both ways an entry for the body will be added in the Documentation in ArangoDBs WebInterface.
For information about how to annotate your models, see the Model section.
All requests sending a body that does not match the validation given this way
will automatically be rejected.
You can also wrap the definition into an array, in this case this route
expects a body of type array containing arbitrary many valid objects.
Accessing the body parameter will then of course return an array of objects.
Note: The behavior of bodyParam
changes depending on the rootElement
option
set in the manifest. If it is set to true
, it is
expected that the body is an
object with a key of the same name as the paramName
argument.
The value of this object is either a single object or in the case of a multi
element an array of objects.
Parameter
- paramName: name of the body parameter in
req.parameters
. - options: a joi schema or an object with the following properties:
- description: the documentation description of the request body.
- type: the Foxx model or joi schema to use.
- allowInvalid (optional):
true
if validation should be skipped. (Default:false
)
Examples
app.post("/foxx", function (req, res) { var foxxBody = req.parameters.foxxBody; // Do something with foxxBody }).bodyParam("foxxBody", { description: "Body of the Foxx", type: FoxxBodyModel });
Using a joi schema:app.post("/foxx", function (req, res) { var joiBody = req.parameters.joiBody; // Do something with the number }).bodyParam("joiBody", { type: joi.number().integer().min(5), description: "A number greater than five", allowInvalid: false // default });
Shorthand version:app.post("/foxx", function (req, res) { var joiBody = req.parameters.joiBody; // Do something with the number }).bodyParam( "joiBody", joi.number().integer().min(5) .description("A number greater than five") .meta({allowInvalid: false}) // default );
errorResponse
Route.errorResponse(errorClassOrName, code, description, [callback])
Define a reaction to a thrown error for this route: If your handler throws an error
of the errorClass defined in errorClassOrName
or the error has an attribute name
equal to errorClassOrName
,
it will be caught and the response object will be filled with the given
status code and a JSON with error set to your description as the body.
If you want more control over the returned JSON, you can give an optional fourth
parameter in form of a function. It gets the error as an argument, the return
value will be transformed into JSON and then be used as the body.
The status code will be used as described above. The description will be used for
the documentation.
It also adds documentation for this error response to the generated documentation.
Examples
/* define our own error type, FoxxyError */
var FoxxyError = function (message) {
this.name = "FError";
this.message = "the following FoxxyError occurred: " + message;
};
FoxxyError.prototype = new Error();
<br />
app.get("/foxx", function {
/* throws a FoxxyError */
throw new FoxxyError();
}).errorResponse(FoxxyError, 303, "This went completely wrong. Sorry!");
<br />
app.get("/foxx", function {
throw new FoxxyError("oops!");
}).errorResponse("FError", 303, "This went completely wrong. Sorry!", function (e) {
return {
code: 123,
desc: e.message
};
});
onlyif
Route.onlyIf(check)
This functionality is used to secure a route by applying a checking function
on the request beforehand, for example the check authorization.
It expects check
to be a function that takes the request object as first parameter.
This function is executed before the actual handler is invoked.
If check
throws an error the actual handler will not be invoked.
Remember to provide an errorResponse
on the route as well to define the behavior in this case.
Examples
app.get("/foxx", function {
// Do something
}).onlyIf(aFunction).errorResponse(ErrorClass, 303, "This went completely wrong. Sorry!");
onlyIfAuthenticated
FoxxController#onlyIfAuthenticated(code, reason)
Please activate sessions for this app if you want to use this function.
Or activate authentication (deprecated).
If the user is logged in, it will do nothing. Otherwise it will respond with
the status code and the reason you provided (the route handler won’t be called).
This will also add the according documentation for this route.
Examples
app.get("/foxx", function {
// Do something
}).onlyIfAuthenticated(401, "You need to be authenticated");
summary
Route.summary(description)
Set the summary for this route in the documentation.
Can’t be longer than 8192 characters.
This is equal to using JavaDoc style comments right above your function.
If you provide both comment and summary()
the call to summary()
wins
and will be used.
Examples
Version with comment:
/** Short description
*
* Longer description
* with multiple lines
*/
app.get("/foxx", function() {
});
is identical to:
app.get("/foxx", function() {
})
.summary("Short description")
.notes(["Longer description", "with multiple lines"]);
notes
Route.notes(...description)
Set the long description for this route in the documentation
//
Examples
Version with comment:
/** Short description
*
* Longer description
* with multiple lines
*/
app.get("/foxx", function() {
});
is identical to:
app.get("/foxx", function() {
})
.summary("Short description")
.notes(["Longer description", "with multiple lines"]);
extend
In many use-cases several of the functions are always used in a certain combination (e.g.: onlyIf
with errorResponse
).
In order to avoid duplicating this equal usage for several routes in your application you can
extend the controller with your own functions.
These functions can simply combine several of the above on a single name, so you only have to
invoke your self defined single function on all routes using these extensions.
Controller.extend(extensions)
Extends all functions to define routes in this controller.
This allows to combine several route extensions with the invocation
of a single function.
This is especially useful if you use the same input parameter in several routes of
your controller and want to apply the same validation, documentation and error handling
for it.
The extensions
parameter is a JSON object with arbitrary keys.
Each key is used as the name of the function you want to define (you cannot overwrite
internal functions like pathParam
) and the value is a function that will be invoked.
This function can get arbitrary many arguments and the this
of the function is bound
to the route definition object (e.g. you can use this.pathParam()
).
Your newly defined function is chainable similar to the internal functions.
Examples
Define a validator for a queryParameter, including documentation and errorResponses
in a single command:
controller.extend({
myParam: function (maxValue) {
this.queryParam("value", {type: joi.number().required()});
this.onlyIf(function(req) {
var v = req.param("value");
if (v > maxValue) {
throw new NumberTooLargeError();
}
});
this.errorResponse(NumberTooLargeError, 400, "The given value is too large");
}
});
<br />
controller.get("/goose/barn", function(req, res) {
// Will only be invoked if the request has parameter value and it is less or equal 5.
}).myParam(5);
Documenting and constraining all routes
In addition to documenting a specific route, you can also do the same for all routes of a controller. For this purpose use the allRoutes object of the according controller. The following methods are available.
Examples
Provide an error response for all routes handled by this controller:
ctrl.allRoutes
.errorResponse(Unauthorized, 401, 'Not authenticated.')
.errorResponse(NotFound, 404, 'Document not found.')
.errorResponse(ImATeapot, 418, 'I\'m a teapot.');
ctrl.get('/some/route', function (req, res) {
// ...
throw new NotFound('The document does not exist');
// ...
}); // no errorResponse needed here
ctrl.get('/another/route', function (req, res) {
// ...
throw new NotFound('I made you a cookie but I ated it');
// ...
}); // no errorResponse needed here either
errorResponse
Controller.allRoutes.errorResponse(errorClass, code, description)
This is equal to invoking Route.errorResponse
on all routes bound to this controller.
Examples
app.allRoutes.errorResponse(FoxxyError, 303, "This went completely wrong. Sorry!");
<br />
app.get("/foxx", function {
// Do something
});
onlyIf
Controller.allRoutes.onlyIf(code, reason)
This is equal to invoking Route.onlyIf
on all routes bound to this controller.
Examples
app.allRoutes.onlyIf(myPersonalCheck);
<br />
app.get("/foxx", function {
// Do something
});
onlyIfAuthenticated
Controller.allRoutes.onlyIfAuthenticated(code, description)
This is equal to invoking Route.onlyIfAuthenticated
on all routes bound to this controller.
Examples
app.allRoutes.onlyIfAuthenticated(401, "You need to be authenticated");
<br />
app.get("/foxx", function {
// Do something
});
pathParam
Controller.allRoutes.pathParam(id, options)
This is equal to invoking Route.pathParam
on all routes bound to this controller.
Examples
app.allRoutes.pathParam("id", joi.string().required().description("Id of the Foxx"));
<br />
app.get("/foxx/:id", function {
// Secured by pathParam
});
You can also pass in a configuration object instead:
app.allRoutes.pathParam("id", {
type: joi.string(),
required: true,
description: "Id of the Foxx"
});
<br />
app.get("/foxx/:id", function {
// Secured by pathParam
});
bodyParam
Controller.allRoutes.queryParam(id, options)
This is equal to invoking Route.queryParam
on all routes bound to this controller.
Examples
app.allroutes.queryParam("id",
joi.string()
.required()
.description("Id of the Foxx")
.meta({allowMultiple: false})
});
<br />
app.get("/foxx", function {
// Do something
});
You can also pass in a configuration object instead:
app.allroutes.queryParam("id", {
type: joi.string().required().description("Id of the Foxx"),
allowMultiple: false
});
<br />
app.get("/foxx", function {
// Do something
});
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
Controller.before(path, callback)
Defines an additional function on the route path
which will be executed
before the callback defined for a specific HTTP verb is executed.
The callback
function has the same signature as the callback
in the
specific route.
You can also omit the path
, in this case callback
will be executed
before handleing any request in this Controller.
If callback
returns the Boolean value false
, the route handling
will not proceed. You can use this to intercept invalid or unauthorized
requests and prevent them from being passed to the matching routes.
Examples
app.before('/high/way', function(req, res) {
//Do some crazy request logging
});
after
Controller.after(path, callback)
Similar to Controller.before(path, callback)
but callback
will be invoked
after the request is handled in the specific route.
Examples
app.after('/high/way', function(req, res) {
//Do some crazy response logging
});
around
Controller.around(path, callback)
Similar to Controller.before(path, callback)
callback
will be invoked
instead of the specific handler.
callback
takes two additional paramaters opts
and next
where
opts
contains options assigned to the route and next
is a function.
Whenever you call next
in callback
the specific handler is invoked,
if you do not call next
the specific handler will not be invoked at all.
So using around you can execute code before and after a specific handler
and even call the handler only under certain circumstances.
If you omit path
callback
will be called on every request.
Examples
app.around('/high/way', function(req, res, opts, next) {
//Do some crazy request logging
next();
//Do some more crazy request logging
});
The Request and Response Objects
When you have created your FoxxController 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
These objects are provided by the underlying ArangoDB actions and enhanced by the BaseMiddleware provided by Foxx.
The Request Object
The request object inherits several attributes from the underlying Actions:
-
compatibility: an integer specifying the compatibility version sent by the client (in request header x-arango-version). If the client does not send this header, ArangoDB will set this to the minimum compatible version number. The value is 10000 * major + 100 * minor (e.g. 10400 for ArangoDB version 1.4).
-
user: the name of the current ArangoDB user. This will be populated only if authentication is turned on, and will be null otherwise.
-
database: the name of the current database (e.g. _system)
-
protocol: http or https
-
server: a JSON object with sub-attributes address (containing server host name or IP address) and port (server port).
-
path: request URI path, with potential database name stripped off.
-
url: request URI path + query string, with potential database name stripped off
-
headers: a JSON object with the request headers as key/value pairs. Note: All header field names are lower-cased
-
cookies: a JSON object with the request cookies as key/value pairs
-
requestType: the request method (e.g. “GET”, “POST”, “PUT”, …)
-
requestBody: the complete body of the request as a string
-
parameters: a JSON object with all parameters set in the URL as key/value pairs
-
urlParameters: a JSON object with all named parameters defined for the route as key/value pairs.
In addition to these attributes, a Foxx request objects provides the following convenience methods:
body
request.body()
Get the JSON parsed body of the request. If you need the raw version, please
refer to the rawBody function.
rawBody
request.rawBody()
The raw request body, not parsed. The body is returned as a UTF-8 string.
Note that this can only be used sensibly if the request body contains
valid UTF-8. If the request body is known to contain non-UTF-8 data, the
request body can be accessed by using request.rawBodyBuffer
.
rawBodyBuffer
request.rawBodyBuffer()
The raw request body, returned as a Buffer object.
params
request.params(key)
Get the parameters of the request. This process is two-fold:
- If you have defined an URL like /test/:id and the user requested /test/1, the call params(“id”) will return 1.
- 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.
cookie
request.cookie(name, cfg)
Read a cookie from the request. Optionally the cookie’s signature can be verified.
Parameter
- name: the name of the cookie to read from the request.
- cfg (optional): an object with any of the following properties:
- signed (optional): an object with any of the following properties:
- secret: a secret string that was used to sign the cookie.
- algorithm: hashing algorithm that was used to sign the cookie. Default: “sha256”.
If signed is a string, it will be used as the secret instead.
If a secret is provided, a second cookie with the name name + “.sig” will be read and its value will be verified as the cookie value’s signature.
If the cookie is not set or its signature is invalid, “undefined” will be returned instead.
Examples
var sid = request.cookie("sid", {signed: "keyboardcat"});
requestParts
Only useful for multi-part requests.
request.requestParts()
Returns an array containing the individual parts of a multi-part request.
Each part contains a headers
attribute with all headers of the part,
and a data
attribute with the content of the part in a Buffer object.
If the request is not a multi-part request, this function will throw an
error.
The Response Object
Every response object has the body attribute from the underlying Actions to set the raw body by hand.
You provide your response body as a string here.
Response status
response.status(code)
Set the status code of your response, for example:
Examples
response.status(404);
Response set
response.set(key, value)
Set a header attribute, for example:
Examples
response.set("Content-Length", 123);
response.set("Content-Type", "text/plain");
or alternatively:
response.set({
"Content-Length": "123",
"Content-Type": "text/plain"
});
Response json
response.json(object)
Set the content type to JSON and the body to the JSON encoded object
you provided.
Examples
response.json({'born': 'December 12, 1915'});
Response cookie
response.cookie(name, value, cfg)
Add a cookie to the response. Optionally the cookie can be signed.
Parameter
- name: the name of the cookie to add to the response.
- value: the value of the cookie to add to the response.
- cfg (optional): an object with any of the following properties:
- ttl (optional): the number of seconds until this cookie expires.
- path (optional): the cookie path.
- domain (optional): the cookie domain.
- secure (optional): mark the cookie as safe transport (HTTPS) only.
- httpOnly (optional): mark the cookie as HTTP(S) only.
- signed (optional): an object with any of the following properties:
- secret: a secret string to sign the cookie with.
- algorithm: hashing algorithm to sign the cookie with. Default: “sha256”.
If signed is a string, it will be used as the secret instead.
If a secret is provided, a second cookie with the name name + “.sig” will be added to the response, containing the cookie’s HMAC signature.
Examples
response.cookie("sid", "abcdef", {signed: "keyboardcat"});
Response send
response.send(value)
Sets the response body to the specified value. If value is a Buffer
object, the content type will be set to application/octet-stream
if not
yet set. If value is a string, the content type will be set to text/html
if not yet set. If value is an object, it will be treated as in res.json
.
Examples
response.send({"born": "December 12, 1915"});
response.send(new Buffer("some binary data"));
response.send("<html><head><title>Hello World</title></head><body></body></html>");
Response sendFile
response.sendFile(filename, options)
Sets the content of the specified file as the response body. The filename
must be absolute. If no content type is yet set for the response, the
response’s content type will be determined automatically based
on the filename extension. If no content type is known for the extension,
the content type will default to application/octet-stream
.
The options
array can be used to control the behavior of sendFile.
Currently only the following option exists:
lastModified
: if set to true, the last modification date and time of the file will be returned in theLast-Modified
HTTP header
Examples
response.sendFile('/tmp/results.json');
response.sendFile(applicationContext.fileName('image.png'), { lastModified: true });
Controlling Access to Foxx Applications
Access to Foxx applications is controlled by the regular authentication mechanisms present in ArangoDB. The server can be run with or without HTTP authentication.
If authentication is turned on, then every access to the server is authenticated via HTTP authentication. This includes Foxx applications. The global authentication can be toggled via the configuration option.
If global HTTP authentication is turned on, requests to Foxx applications will require HTTP authentication too, and only valid users present in the _users system collection are allowed to use the applications.
Since ArangoDB 1.4, there is an extra option to restrict the authentication to just system API calls, such as /_api/… and /_admin/…. This option can be turned on using the “server.authenticate-system-only” configuration option. If it is turned on, then only system API requests need authentication whereas all requests to Foxx applications and routes will not require authentication.
This is recommended if you want to disable HTTP authentication for Foxx applications but still want the general database APIs to be protected with HTTP authentication.
If you need more fine grained control over the access to your Foxx application, we built an authentication system you can use. Currently we only support cookie-based authentication, but we will add the possibility to use Auth Tokens and external OAuth providers in the near future. Of course you can roll your own authentication mechanism if you want to, and you can do it in an application-specific way if required.
To use the per-application authentication, you should first turn off the global HTTP authentication (or at least restrict it to system API calls as mentioned above). Otherwise clients will need HTTP authentication and need additional authentication by your Foxx application.
To have global HTTP authentication turned on for system APIs but turned off for Foxx, your server startup parameters should look like this:
--server.disable-authentication false --server.authenticate-system-only true
Note: During development, you may even turn off HTTP authentication completely:
--server.disable-authentication true --server.authenticate-system-only true
Please keep in mind that turning HTTP authentication off completely will allow unauthenticated access by anyone to all API functions, so do not use this is production.
Now it’s time to configure the application-specific authentication. We built a small demo application to demonstrate how this works.
To use the application-specific authentication in your own app, first activate it in your controller.
Active Authentication
Controller.activateAuthentication(opts)
To activate authentication for this controller, call this function before defining any routes.
In the opts
object you can set the following keys:
- type: Currently we only support cookie, but this will change in the future
- cookieLifetime: An integer. Lifetime of cookies in seconds
- cookieName: A string used as the name of the cookie
- sessionLifetime: An integer. Lifetime of sessions in seconds
Examples
app.activateAuthentication({
type: "cookie",
cookieLifetime: 360000,
cookieName: "my_cookie",
sessionLifetime: 400,
});
Login
FoxxController#login(path, opts)
Add a route for the login. You can provide further customizations via the
the options:
- usernameField and passwordField can be used to adjust the expected attributes in the post request. They default to username and password.
- onSuccess is a function that you can define to do something if the login was successful. This includes sending a response to the user. This defaults to a function that returns a JSON with user set to the identifier of the user and
- key set to the session key.
- onError is a function that you can define to do something if the login did not
work. This includes sending a response to the user. This defaults to a function
that sets the response to 401 and returns a JSON with error set to
“Username or Password was wrong”.
Both onSuccess and onError should take request and result as arguments.
Examples
app.login('/login', {
onSuccess(req, res) {
res.json({"success": true});
}
});
Logout
FoxxController#logout(path, opts)
This works pretty similar to the logout function and adds a path to your
app for the logout functionality. You can customize it with a custom onSuccess
and onError function:
- onSuccess is a function that you can define to do something if the logout was successful. This includes sending a response to the user. This defaults to a function that returns a JSON with message set to “logged out”.
- onError is a function that you can define to do something if the logout did not
work. This includes sending a response to the user. This defaults to a function
that sets the response to 401 and returns a JSON with error set to
“No session was found”.
Both onSuccess and onError should take request and result as arguments.
Examples
app.logout('/logout', {
onSuccess(req, res) {
res.json({"message": "Bye, Bye"});
}
});
Register
FoxxController#register(path, opts)
This works pretty similar to the logout function and adds a path to your
app for the register functionality. You can customize it with a custom onSuccess
and onError function:
- onSuccess is a function that you can define to do something if the registration was successful. This includes sending a response to the user. This defaults to a function that returns a JSON with user set to the created user document.
- onError is a function that you can define to do something if the registration did not
work. This includes sending a response to the user. This defaults to a function
that sets the response to 401 and returns a JSON with error set to
“Registration failed”.
Both onSuccess and onError should take request and result as arguments.
You can also set the fields containing the username and password via usernameField (defaults to username) and passwordField (defaults to password). If you want to accept additional attributes for the user document, use the option acceptedAttributes and set it to an array containing strings with the names of the additional attributes you want to accept. All other attributes in the request will be ignored.
If you want default attributes for the accepted attributes or set additional fields (for example admin) use the option defaultAttributes which should be a hash mapping attribute names to default values.
Examples
app.register('/logout', {
acceptedAttributes: ['name'],
defaultAttributes: {
admin: false
}
});
Change Password
FoxxController#changePassword(route, opts)`
Add a route for the logged in user to change the password.
You can provide further customizations via the
the options:
- passwordField can be used to adjust the expected attribute in the post request. It defaults to password.
- onSuccess is a function that you can define to do something if the change was successful. This includes sending a response to the user. This defaults to a function that returns a JSON with notice set to “Changed password!”.
- onError is a function that you can define to do something if the login did not
work. This includes sending a response to the user. This defaults to a function
that sets the response to 401 and returns a JSON with error set to
“No session was found”.
Both onSuccess and onError should take request and result as arguments.
Examples
app.changePassword('/changePassword', {
onSuccess(req, res) {
res.json({"success": true});
}
});
Restricting routes
To restrict routes, see the documentation for Documenting and Restraining the routes.