Package Exports
- dingle
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (dingle) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Dingle
Dingle is a quick and easy NodeJS framework which can be used to create scalable and maintainable API layouts.
Installation
$ npm install --save dingle
Features
* HTTP and HTTPS
* TCP and UDP
* JSON output
* Client code generation
* Parameter validation
* File uploads
* Execute functions
* Based on ExpressJS
Startup
To start dingle it requires a minimum of an ip to listen on:
var dingle = require('dingle')({
http_listen: '0.0.0.0',
https_listen: '0.0.0.0',
tcp_listen: '0.0.0.0',
udp_listen: '0.0.0.0'
});
In dingle each API call is referred to as a function.
Directory Layout
Each function exists in a module and is loaded from the public directory like so:
public
├───status.js
├───time.js
├───users.js
├───users
│ └───register.js
│ └───forgot_username.js
│ └───forgot_password.js
│ └───sessions
│ └───login.js
│ └───logout.js
│ └───list.js
Each function is referred to using a naming convention where directories are separated by underscores:
status
time
users
users_register
users_forgot_username
users_forgot_password
users_sessions_login
users_sessions_logout
users_sessions_list
Also note function names ARE case sensitive.
HTTP & HTTPS
To access the functions via HTTP or HTTPS
we use the URL.
https://myawesomeapi.com/users_forgot_username/
For GET, PUT and DELETE
requests use url encoded parameters to supply data to the function like so:
https://myawesomeapi.com/users_forgot_username/?email=admin@myawesomeapi.com&password=myawesomeapi.com
For POST
requests the url encoded data must be attached to the multipart body of the request.
TCP & UDP
To access the functions via TCP or UDP
you must first make a connection using either protocol and send data using the following format:
/users_forgot_username/email=email=admin@myawesomeapi.com&password=myawesomeapi.com
You will then receive a response containing the output data.
Function Layout
The module for each function is laid out as follows:
module.method
- Methods available:GET, PUT, DELETE, POST, TCP, UDP
module.name
- Function in a few words.module.description
- Function in a few more words.module.params
- List of parameters the function requires. (Will be validated and passed to module.execute)module.execute
- Perform main script of the function and provide responce.
module.exports = function (type, functions, execute, config) {
var module = {};
module.method = 'GET';
module.name = "Register Users";
module.description = "Use this function to create a user in the MongoDB database before they are given access to the website";
module.params = {
email: {
validate: type.email,
required: true,
description:"Email for registering user ",
error: 'Please enter a valid email address'
},
password: {
validate: type.string,
required: true,
description: "Password for registering user",
error: 'Please enter a password'
}
}
module.execute = function(req, res, params, respond){
//Create User
var user = new NewUser({
email: params.email,
password: params.password
});
//Save User to MongoDB
user.save(function (error){
if (error){
respond(req, res, false,'Registration Failed:' + error,{});
}else{
respond(req, res, true,'Registration Complete',{
user: user._id
});
}
});
}
return module;
};
Once the task has completed inside module.execute you must use the respond callback.
respond(req, res, success, message, output);
Parameter Layout
Dingle will handle parameter validation for you and can be specified like so:
validate
- Validation types available, see below.required
- Whether the value can be blank.description
- Parameters use in a sentence.error
- Error message which is presented if the parameter failed validation.
module.params = {
email: {
validate: type.email,
required: true,
description:"Email for registering user ",
error: 'Please enter a valid email address'
},
password: {
validate: type.string,
required: true,
description: "Password for registering user",
error: 'Please enter a password'
}
}
You can use built in validation types which are based on the validator module:
string
bool
float
int
date
- Returns a javascript date objectfile
- Can only be used in POST method with multipart requests, see belowemail
originalname
ip
url
base64
mongo
- MongoDB object idcard
- Credit or debit card
Custom Types
Custom data types can be added and used in parameter validation like so:
var validator = require('validator');
var dingle = require('dingle')({
http_listen: '0.0.0.0',
https_listen: '0.0.0.0',
tcp_listen: '0.0.0.0',
udp_listen: '0.0.0.0'
});
dingle.type.date = function(string){
//Check for validity
if (!validator.isDate(string)){
throw new Error();
}
//Return sanitized result
return validator.toDate(string);
}
- The parameter is passed into the function as a string.
- Perform the necessary validation and throw an Error() should there be any invalidity.
- Once the data has been validated it must be returned in the correct data type.
File Uploads
When uploading files using the POST
method the following Multer object is returned in the params property:
fieldname
- Field name specified in the form.originalname
- Name of the file on the user's computer.name
- Renamed file name.encoding
- Encoding type of the file.mimetype
- Mime type of the file.path
- Location of the uploaded file.extension
- Extension of the file.size
- Size of the file in bytes.truncated
- If the file was truncated due to size limitation.buffer
- Raw data (is null unless the inMemory option is true).
It's your job to manipulate, read and clean up when finished.
File Downloads
When using HTTP or HTTPS
files can be downloaded from a function using the express response object like so:
module.execute = function(req, res, params, respond){
var file = './uploads/' + params.file;
fs.exists(file, function (exists){
if (exists){
res.download(file, 'download.zip');
}else{
respond(req, res, false,'File could not be found',{});
}
});
}
When downloading a file no status or message can be supplied and so res.download and respond should not be used one after another.
Additional Options
There are further options which can be used as follows:
var dingle = require('dingle')({
//Paths
path_functions: './public', //Path storing functions
path_exports: './export', //Path to build client code into
//App (Default from package.json)
app_name: 'My Awesome App',
app_prefix; 'MAA',
app_version: '0.0.7',
//HTTP
http_hostname: 'myawesomeapi.com',
http_listen: '0.0.0.0',
http_port: 80,
//HTTPS
https_hostname: 'myawesomeapi.com',
https_listen: '0.0.0.0',
https_port: = 443,
https_ssl_key: './key.pem',
https_ssl_cert: './cert.pem',
//TCP
tcp_hostname: 'myawesomeapi.com',
tcp_listen: '0.0.0.0',
tcp_port: = 7691,
//UDP
udp_hostname: 'myawesomeapi.com',
udp_listen: '0.0.0.0',
udp_port: = 7692
});
Executing Functions
You can execute functions from within a function like so:
execute(config, req, function(success, message, output){
console.log(output);
}, params, function);
For example to execute the users_forgot_username
function we can use the following:
module.execute = function(req, res, params, respond){
execute(config, req, function(success, message, output){
if (success){
respond(req, res, true,'Success result from users_forgot_username', output);
}else{
respond(req, res, true,'Error result from users_forgot_username', message);
}
}, params, 'users_forgot_username');
}
We can even execute a function from outside dingle:
var dingle = require('dingle')({
http_listen: '0.0.0.0',
https_listen: '0.0.0.0',
tcp_listen: '0.0.0.0',
udp_listen: '0.0.0.0'
});
dingle.execute(dingle.config, {}, function(success, message, output){
console.log(success);
console.log(message);
console.log(output);
},{
email: 'admin@myawesomeapi.com'
}, 'users_forgot_username');
Customization
You can access internal modules dingle uses to run to gain more functionality using the following properties:
config
- Startup configuration for dingle.calls
- Object with dingle function information.type
- Object with parameter validation types.express
- Express app instance.router
- Express request router.tcp
- Standard net TCP sever.udp
- Socket for UDP server.
You can access information relating to the API calls loaded:
var dingle = require('dingle')({
http_listen: '0.0.0.0',
https_listen: '0.0.0.0',
tcp_listen: '0.0.0.0',
udp_listen: '0.0.0.0'
});
dingle.calls.forEach(function(call){
console.log(call.name + ' ' + call.module.method);
}
You can add additional Express middleware:
var dingle = require('dingle')({
http_listen: '0.0.0.0',
https_listen: '0.0.0.0',
tcp_listen: '0.0.0.0',
udp_listen: '0.0.0.0'
});
dingle.express.use(function (req, res, next) {
next();
});
You can create additional Express routing:
var dingle = require('dingle')({
http_listen: '0.0.0.0',
https_listen: '0.0.0.0',
tcp_listen: '0.0.0.0',
udp_listen: '0.0.0.0'
});
dingle.router.get('/about', function(req, res) {
res.send('About birds');
});