VBel2
VBel2 helps you quickly build complex APIs that easily integrate with your frontend / existing backend.
Think of it as Django but in Javascript, more lightweight and API focused.
VBel has no dependencies, you just install it and get started !
For more complex use, an SQL database is recommended.
Getting Started
Use the following command
npm install vbel2
Minimal example:
const VBel = require('vbel2');
let vbel = new VBel();
vbel.endpoint("hello", {name:{"type":"string"}}, (obj,req,res) => {
vbel.sendSuccess(`Hello ${obj.name}`);
});
vbel.endpoint("bye", {name:{"type":"string"}}, (obj,req,res) => {
vbel.sendSuccess(`Goodbye ${obj.name}`);
});
vbel.listen(8080,() => {
console.log("http://localhost:8080")
});
You can also use VBel just to serve static files or folders:
const VBel = require('vbel2');
let vbel = new VBel();
vbel.file("/","file.html");
vbel.file("/static","static/");
vbel.listen(8080,() => {
console.log("http://localhost:8080")
});
Overview
VBel2 stands for Vanyle's BackEnd Library 2. It is a framework to build backends in Node.js. VBel2 allows you to quickly build complex websites with minimal effort for your backend.
Most website are just an interface between a user and a database. The only job of the backend is to make sure that the users have proper authorizations to read or edit the database. It's from this observation that VBel2 was built.
With VBel2, you just describe what your database looks like, things like:
- Your tables
- The fields in those tables
- The relationships between the fields
- The permissions required to read or edit the fields
And VBel2 will automatically create the database with the layout provided, create all the endpoints needed to do the actions you specified and generate all the documentation needed to use those endpoints. VBel2 will also generate some JavaScript for your client so that the client can call these backend functions without having to think.
It's as if the client can simply call function or access variables that exist server-side as long as the types of the arguments are correct and that the client has sufficient authorizations.
Of course, VBel2 also allows you to also create your own endpoints, if you want to do more than reading or writing data.
You can easily integrate VBel2 into any existing application as you can use as many or as little of VBel2's features as you need. VBel2 acts just as any express
middleware, so you can just add app.use(vbel)
to your app and you're ready to go. You can also use VBel2 without express, just call vbel(req,res,callback)
and VBel2 will try to handle the request and call callback
if the request was not meant for VBel2 (in the case of a 404 for example)
Using VBel2 to create endpoints
Let's say you have a node.js application built with express and you want to add a new endpoint.
For example, an endpoint that returns a random number from the server.
You could write something like this:
let app = express();
let vbel = new VBel();
vbel.endpoint(
"rnd_number",
{
min:{type:"number"},
max:{type:"number"};
},
(obj,req,res) => {
let nbr = Math.random() * (obj.max - obj.min) + obj.min;
vbel.sendSuccess(res,nbr);
}
);
app.use(vbel);
app.listen(8080);
And on the client size, you can have:
<html>
... Your page
<script src="/client.js"></script>
<script>
async function main(){
let nbr = await rnd_number(0,100);
console.log(nbr.result)
let badType = await rnd_number("hello","world");
console.log(nbr.error);
}
main();
</script>
</html>
VBel sessions
Just like express-session
, VBel provides sessions by default. They work just like express
sessions:
let vbel = new VBel({
sql:null,
cookie_secret:"secret"
});
vbel.endpoint("counter",{},async (obj,req,res) => {
if(typeof req.session.counter !== "number"){
req.session.counter = 0;
}else{
req.session.counter++;
}
vbel.sendSuccess(res,req.session.counter);
});
vbel.listen(8080);
By default, a memory store is used. This store is not production ready and a database should be used instead. To do this, just provide 2 functions to VBel:
const sqlite3 = require('better-sqlite3');
let db = sqlite3("./mydb.db",{});
let vbel = new VBel({
sql:null,
cookie_secret:"secret",
store:{
read:(sessionid) => {
let s = db.prepare("SELECT content FROM sessions WHERE id = ?");
let res = s.get(sessionid);
if(res === null) return;
return JSON.parse(res);
},
write:(sessionid,data) => {
let olddata = read(sessionid);
if(typeof olddata === "undefined" && Object.keys(data).length !== 0){
let s = db.prepare("INSERT INTO sessions (id,content) VALUES (?,?)");
s.run(sessionid,JSON.stringify(data));
}else if(Object.keys(data).length !== 0){
let s = db.prepare("UPDATE sessions SET content = ? WHERE id = ?");
s.run(JSON.stringify(data),sessionid);
}else{
let s = db.prepare("DELETE FROM sessions WHERE id = ?");
s.run(sessionid);
}
}
}
});
You can reuse the code above for your database.
Using VBel2 to manage SQL tables
Sometime, you need more than just calling server side functions from the client,
you need to access some SQL tables.
Well, VBel2 got you covered. You can define an SQL scheme inside your javascript and
VBel2 will generate all the endpoints needed to use the scheme you defined.
VBel2 will make all the necessery checks and SQL requests so that everything works.
const sqlite3 = require('better-sqlite3');
let db = sqlite3("./mydb.db",{});
let config = {
sql:{
_run: (statement,...args) => {
let s = db.prepare(statement);
return s.run.apply(s,args);
},
_get_all:(statement, ...args) => {
let s = db.prepare(statement);
return s.all.apply(s,args);
},
},
doc: true
}
let vbel = new VBel(config);
vbel.table("user",{
isuser:true,
fields:{
name:{
read:"all",
write:"none"
},
birth:{
type:"date",
read:{"match":"id"}
write: (userid,currentObject) => {
return areFriends(userid,currentObject.id);
}
},
posts:{
type:"foreign",
bind:"post",
bind_field:"author_id",
},
rank:{
type:"integer",
write: isAdmin
}
},
methods:{
create:{},
remove:{
handle: () => {
}
},
list:{
permission:"all"
}
}
});
A other example of a custom access function:
function isAdmin(userid){
let r = vbel.getDatabaseValue("user",userid,"rank");
if(r.length !== 1) return false;
return r[0].rank === RANKS.ADMIN;
}
Default Selectors and joinOnDefault
When creating an SQL table, you can define a defaultSelector
to make fetching informations
about the objects in the table more convenient. You can also use joinOnDefault
if the information
you want to fetch are in another table.
vbel.table("post",{
defaultSelector:"post.id,title,user.name AS author,date,SUBSTR(content,0,80) AS preview",
joinOnDefault:"JOIN user ON user.id = author_id",
fields:{
title:{},
content:{},
date:{type:"date"},
methods:{
create:{
generate:{
date: (obj,req,res) => {return new Date();}
}
},
remove:{
permission:isAllowedToRemove
},
list_by_title:{
search:"title",
filter:"date > '1/21/2012'",
limit:15
},
list_by_date:{
sort:"date",
filter:"date > '1/21/2012'",
limit:15
},
list_by_user:{
at:["author_id"]
}
}
});
By default, the methods with automatic handlers are create
, remove
, list
(as well as read
and write
)
for every other field.
You can also add other handler but you need to specify a handler function.
You can use these handler in conjunction with the other endpoints.
Access documentation
Because VBel2 is aware of all the endpoints you create, their types and the database scheme,
VBel2 can provide you with all the documentation you need about all the endpoints.
Just do new VBel({doc:true})
when creating the VBel object and go to /doc
to access the documentation page.
This page will list all the endpoints available, their arguments, the permission required to use them and more !
You can also access the documentation and share it with the doc.html
file created.
Tests
VBel uses jest for testing. You can find the tests inside test.js.