light-ning
Version:
(ALPHA) framework without dependecies...
371 lines (283 loc) • 6.1 kB
Markdown
# Light-weight Framework for creating API Services

<br>
``Light as a feather, fast as lightning...``
``ES6 only``
## "To the game, Sherlock!"
<br>
```
import app from 'light-ning';
```
```
app.run()
```
#### Important!
<br>
``You need create the "controllers" and "routes" directories
where are you calling "run" method.``
*``create "controllers" directory only if you need to use actions in routes and controllers.``
```"routes" directory must include "app.js" file and import all your route-files therein:```
<br>
```
import './user'
import './articles'
```
etc.
If your node js file (where are you calling "run" method)
not in root directory, you need to set prefix before the "run":
```
app.set('prefix', 'path to directory');
app.run()
```
## Router:
<br>
```
import { Router } from 'light-ning';
```
#### Actions
<br>
```
Router.routes('/user', [
{
method: 'GET',
path: '/',
action: 'User@index',
},
{
method: 'GET',
path: '/:id',
action: 'User@show',
},
{
method: 'POST',
path: '/',
action: 'User@create',
},
{
method: 'PUT',
path: '/:id',
action: 'User@update',
},
{
method: 'DELETE',
path: '/:id',
action: 'User@destroy',
},
]);
```
You'll can write ``method`` property
in any register ``'POST'`` or ``'post'`` etc.
Property "action" it's a path of two parts: ControllerName@Method.
(It work only if you use Controllers).
What action do:
``User@index`` equals ``UserController.index(req, res)``
and pass object with ``req, res, etc.`` options in "index" method. [More below...](#controllers)
*Method for action cannot be `static`.
#### Middlewares
<br>
```
Router.routes('/user', [
{
method: 'GET',
path: '/',
middleWares: [ firstFunc, secondFunc ],
},
]);
```
Middlewares performed in succession from left to right.
For pass the course, you need call "next" in your middleware:
```
const middleware = next => {
if (true) {
next();
} else {
throw new Error('access denied');
}
}
```
You'll can pass data in your middleware like this:
```
const middleware_1 = next => {
if (true) {
next(anyData);
}
}
```
```
const middleware_2 = (data, next) => {
console.log(data); // anyData
}
```
#### Important!
<br>
``Do not place "middleWares" with "action" in one route. In this case, "middleWares" will be ignored.``
``Method name - can be any``
#### Guard
<br>
You'll can use guard property for enable
"guardian" mode.
```
Router.routes('/user', [
{
method: 'GET',
path: '/',
guard: true,
action: 'user@index'
},
]);
```
After enable, you need to set "guardian"
middleware into "app":
```
const guardian = ({req, next, response}) => {
if (req.body.user === session.user) {
next();
} else {
response({ code: 403 });
}
}
app.set('guardian', guardian);
```
``guardian`` middleware get default ``req, res`` node js objects,
``next`` function for pass the course
and custom ``response`` method for easy reponses.
[More below...](#response)
#### Root path
<br>
Setting the root path for group routes.
`Do not export "Router"`
```
Router.routes('/user', [
```
```
{
method: 'GET',
path: '/',
action: 'User@index',
},
{
method: 'GET',
path: '/:id',
action: 'User@show',
},
```
This router create routes like:
```
/user/
/user/:id
```
etc.
<a name="controllers" id="controllers" href="controllers"></a>
## Controllers:
<br>
After route ``action: 'User@index'``, object with data get
in controller. It looks like:
```
{
req: request, // default node js object
res: response, // default node js object
response: Response, // method for easy response
}
```
#### Important!
Controller class should `export`. (only `export`, not `default export`)
```
export class UserController {
index(data) {
let {req, res} = data;
}
show({req, response}) {
if (req.body.user === session.user) {
return response({ data: session.user });
}
response({ code: 403 });
}
}
```
If you not pass custom error into response object, they get
default error from http-errors dictionary by status code.
<a name="response" id="response" href="response"></a>
Method "Response" has 3 params:
```
{
error: 'Are you ok?', // custom error
code: 422, // status code
data: []
}
```
#### Important!
<br>
* ``"error" must sending with "code" (code can sending without error)``
* ``"data" must sending without "error" (in this case, data will be ignored)``
## Base Controller
You'll can extend your controller from ``BaseController``:
```
import { BaseController } from 'light-ning';
```
```
export class UserController extends BaseController {
filter = ['password']; // es7
constructor() {
super();
this.filter = ['password'] // es6
}
index({response}) {
let user = {
login: 'user',
email: 'user@mail.com',
password: 'secret'
};
let data = this.filtrate(user);
console.log(data); // { login: 'user', email: 'user@mail.com' }
response({ data: data });
}
};
```
``BaseController`` has method ``filtrate`` for easy filter data
for response.
``filtrate`` works from ``filterMode`` (``'omit'`` by default).
You'll can set 2 modes:
* ``omit``
* ``pick``
their names speak for themselves.
```
filter = ['password'];
```
Omit mode:
```
filterMode = 'omit';
```
```
this.filtrate({
login: 'user',
password: 'secret'
});
// result: { login: 'user' }
```
Pick mode:
```
filterMode = 'pick';
```
```
this.filtrate({
login: 'user',
password: 'secret'
});
// result: { password: 'secret' }
```
## Configure
<bt>
You'll can create ``config.json`` near your node js file
(where are you calling "run" method) and set:
```
{
"port": your port
}
```
or you can set port in app:
```
app.set('port', your port);
app.run();
```
Default port: ``6060``
### [look source on github](https://github.com/sentiurin/light-ning)