Typical scenario to use basyt is when you need to serve a rest-like JSON API that provides create/read/update/delete/query actions for your data entities.
In basyt, you simply declare entities. Then basyt does the rest for you. If you need authentication or custom actions related to your entity, you can easily decorate your entity.
You can connect your database using basyt collections and seamlessly integrate with your AngularJS web application using basyt angular module.
basyt is an extension over awesome web framework expressjs. By composition of basic middlewares, basyt simplifies building JSON API server over express.
basyt provides builtin methods for creating, reading, updating, deleting, listing and querying declared entities. These methods can be extended by hook definitions.
basyt provides json web token based authentication. You can easily use inside your mobile applications. You do not need to manage sessions, there will not be cookies, hence no CSRF trouble.
basyt provides role based access control. You can easily define authorization levels for creating, updating, deleting, querying and reading for each entity.
basyt provides flexible entity definition capability. You can easily add extra custom actions, define hooks for database operations of entities.
basyt provides generic collection interface. MongoDB collection interface is implemented, and elasticsearch is planned for the next step.
basyt provides socket.io based websocket integration and emits entity update events in Redis to be consumed for notification implementation.
To utilize basyt as foundation of your API, you need several declarations. Firstly basyt needs global APP_CONFIG object.
GLOBAL.APP_CONFIG = {
base_folder: __dirname + '/',
//base_folder definition is required, you probably will keep this line as it is
package_file: GLOBAL.APP_CONFIG.base_folder + 'package.json',
//path for package.json file. basyt uses package.json to get application name and version.
//when not defined package_file is set to base_folder + 'package.json'
basyt: { //scope for basyt related configuration
port: 5850,
//port number that basyt HTTP server will listen
entity_path: '/',
//url base path for entity API endpoints. default is '/'
//if it is set to 'foo' then base address for entity is http://hostname/foo/entity
entities_folder: GLOBAL.APP_CONFIG.base_folder + 'entities',
//path for folder that contains entity definitions.
//when not defined, entities_folder is set to base_folder + 'entities'
controllers_folder: GLOBAL.APP_CONFIG.base_folder + 'controllers',
//path for folder that contains entity-free controller definitions.
//when not defined, controllers_folder is set to base_folder + 'controllers'
enable_ws: true,
//enables socket.io based websocket. default true
enable_cors: true,
//enables CORS setup. default false
enable_auth: true,
//enables user management and authentication. default true
cors: {
//CORS headers to be setup. Required only when enable_cors is true
//following values can be set for CORS setup.
//Content_Type header field is allowed by default
//Authorization header is allowed when auth is enabled
origin: 'http://localhost:8580',
methods: 'GET,PUT,POST,DELETE',
headers: ['accept']
},
auth: {
//required when enable_auth is true.
token: 'your.secret.token',
//token to be used for jwt
method: 'jwt'
//currently only supported method is jwt
}
disable_discovery: false,
//when discovery is enabled, GET request to server's base address will provide all possible API
},
mongodb: { //scope for mongodb collection configuration
connection: 'mongodb://localhost/basyt_db'
}
};
after declaring global APP_CONFIG, you simply instantiate basyt
var basyt = require('basyt');
var basytApp = basyt();
basyt explores entities and controllers in corresponding folders and generates API endpoints. In entities folder, entity declarations are like in the following example
module.exports = {
collection: { //collection is database aspect of entity
storage: "mongodb",
//currently the only storage option is mongodb. it is used to select collection
name: "test_entity",
//name of entity, used for url path and as collection name
strict: true,
//when collection is NOT strict, it accepts attributes that are not defined in attributes list
attributes: { //list of the attributes of entity
//following attributes are given as example
name: {type: "string", required: true},
email: "email",
url: "url",
telephone: {
type: "numeric",
minLength: 7,
maxLength: 11
}
},
event_names: [':test_entity'],
//basyt emits redis event for entity updates.
//By default, it emits entity:: event
//for additional events event_names list is used.
methods: {
//list of collection methods
//here hook functions for entity can be defined. for instance beforeCreate, afterCreate etc.
//see basyt-base-collection/index.js hook functions for complete hook functions and their
//signature
}
},
auth_levels: {
//authentication levels for API actions for entity. Default authentication level is 'USER'
'read': 'USER',
'list': 'USER',
'update': 'USER',
'update_bulk': 'USER',
'query': 'USER',
'create': 'USER',
'create_bulk': 'USER',
'delete': 'USER',
'delete_bulk': 'USER'
},
//you can disable/enable any API action for entity.
disable_read: false,
disable_list: false,
disable_update: false,
disable_delete_bulk: true,
disable_create_bulk: true,
disable_update_bulk: true,
customActions: {
//here you can define any other actions for the entity
test: {
path: '/:entity_id/test',
//url path that action will bind to
method: 'put',
//HTTP method for the action
auth_level: 'ADMIN',
//Authentication level for the action
action: function custom_action(req, res) {
//action function
return res.json({success: true});
}
}
}
};
In controllers folder, entity-free controllers are declared. Those controller files include definitions similar to customActions field of entity declarations.
module.exports = {
example_action: {
path: '/example_action',
//url path that action will bind to
method: 'GET',
//HTTP method for the action
auth_level: 'USER',
//Authentication level for the action
action: function example_action(req, res) {
//action function
return res.json({success: true});
}
}
};
For a controller file named test_controller.js
with content given above, there will be an api for address http://hostname/test_controller /example_action
.
Main package for JSON API Server
Available in npmnpm install basyt
Database connection package for MongoDB
Available in npmnpm install basyt-mongodb-collection
AngularJS module for basyt servers
Available in bowerbower install basyt-angular
Elasticsearch datastore connection
Redis datastore connection
It is a package of patterns that extends capabilities of expressjs that will make you develop your API server quicker.
Nope, it is not. It actually tries hard not to be a framework. Being a framework and providing simplicity contradicts, and basyt prefers to be in the simplicity side.
Well, if you have more than a few entities, you do not want to repeat yourself while writing database operations, validations and authorization services, then it may be.
But if you have more simple API needs, do not bother using any additional packages, expressjs itself is probably more than enough for you
In Turkish basit means simple. That is the motivation: an extension over expressjs to make things simpler. Since our company's initials are YT, we decided to call the project basyt, simple web package from Yonca Teknoloji.