autoexpressapi v1.0.4
Auto express API
TOC
Installation
npm install autoexpressapi
Usage
// js:
const autoExpressAPI = require("autoexpressapi");
// ts:
import autoExpressAPI from "autoexpressapi";
// ... initialize express server as 'app'
autoExpressAPI(app);
Documentation
function autoExpressAPI(server: IRouter, config: Config = {}) => void
server: The express app
config: The config object - see Config
returns: void
Registers all endpoints in a directory specified in the config to the express app. See Endpoints.
Config
config.path: string
The path to the folder containing the routes.
If the path is relative, it is computed using process.cwd()
.
Default: routes
config.ignorePrefix: string
If any file has this prefix, it will be ignored.
Default: $
config.allRoutesFile: string
The name of a file (without extension), to which all remaining requests will be redirected. (requests where the headers weren't sent)
If set to "none"
there will be no all route.
Default: all
config.indexRouteFile: string
The name of a file (without extension), to which will the root (/) path redirected.
Default: index
config.url: string
The base url for the requests (which will be before all the endpoints).
Has to end with /
.
Default: /
Endpoints
One file = one endpoint. Endpoint urls are directory computed. For example consider following directory structure:
routes
|- api
|- users.js
|- user
|- login.js
|- register.js
|- home.js
|- contacts.js
Following endpoints will be created:
/api/users
/user/login
/user/register
/home
/contacts
Index endpoint
The filename is set by a config property indexRouteFile.
For this example consider it to be index
.
In any folder when a index.js
file is created, it will point to the root.
For example for following directory structure:
routes
|- api
|- index.js
|- users.js
|- home.js
|- index.js
The endpoints created will be:
/api -> ./api/index.js
/api/users -> ./api/users.js
/home -> ./home.js
/ -> ./index.js
There are two ways of creating a root url for a directory.
1. `
routes
|- api
|- users.js
|- api.js
```
routes |- api |- users.js |- index.js ``` **The second way is considered the right way**, so when the first option occurs, a warning will be logged.
All endpoint
The filename is set by a config property allRoutesFile.
For this example consider it to be all
.
In any folder when a all.js
file is created, it will point to every endpoint, where the headers weren't already sent.
For example for following directory structure:
routes
|- api
|- index.js
|- users.js
|- all.js
|- home.js
|- index.js
|- all.js
The endpoints created will be:
/api -> ./api/index.js
/api/users -> ./api/users.js
/api/* -> ./api/all.js (all where the response wasn't sent)
/home -> ./home.js
/ -> ./index.js
/* -> ./all.js (all where the response wasn't sent)
The order in which are the all endpoints executed: /api/*
, /*
(the most nested ones first)
Endpoint file structure
An endpoint usually exports an object. For example: TS:
export = {
// the endpoint object
};
JS:
module.exports = {
// the endpoint object
};
Methods
The object contains method properties, that are named after HTTP Methods. The method is a classic express handler method (can be async too). For example:
module.exports = {
get: (req, res, next) => {
// do something
res.send();
next();
},
post: (req, res) => {
res.json({});
}
};
List of currently supported methods:
all
checkout
copy
delete
get
head
lock
merge
mkactivity
mkcol
move
m-search
notify
options
patch
post
purge
put
report
search
subscribe
trace
unlock
unsubscribe
The all
method just redirects every request from that endpoint to itself.
Middleware
Each object can also contain a middleware property. It can be: 1. express handler function -> it will be used as middleware for all the methods in that endpoint. Example:
```js
module.exports = {
get: (req, res, next) => {
res.send(req.test);
next();
},
middleware: (req, res, next) => {
req.test = "test";
next();
}
};
```
- an array of express handler functions -> all the functions in that array will be used for all the methods. First function is going to be executed first etc...
- an object -> An object containing the method specific middlewares. These can be express methods or arrays of express methods. Example:
The order these are going to be executed:```js module.exports = { get: (req, res, next) => { res.json({ allspec: req.allspec, gspec: req.gspec }); next(); }, post: (req, res, next) => { res.json({ allspec: req.allspec, pspec: req.pspec, postUser: req.postUser }); next(); }, middleware: { get: (req, res, next) => { req.gspec = "Get specific"; next(); }, all: (req, res, next) => { req.test = "For all methods"; next(); }, post: [ (req, res, next) => { req.pspec = "Post specific"; next(); }, (req, res, next) => { req.postUser = `${req.pspec} user`; next(); } ] } }; ```
POST:
middleware.all (all is always first)
middleware.post[0]
middleware.post[1]
post
End middleware
The same as middleware, but it's executed after the execution of the endpoint. Example:
module.exports = {
get: (req, res, next) => {
if (req.body.send === true)
res.send();
next();
},
endMiddleware: (req, res, next) => {
if (!res.headersSent)
res.send("Error: didn't send");
next();
}
};
All endpoint file structure
The all
endpoint isn't an object - it's just a function:
module.exports = (req, res, next) => {
res.send("This endpoint does not exist!");
next();
}
Logging
Auto express API provides a way for the user to configure it's logging or apply custom one. Custom logging is supported mainly in Typescript, in Javascript it could have unexpected behaviour.
The default behaviour of the logger is to print the logs to the console if the conditions in Log config allow that.
Log config
Log config is an object that allows the user to configure the logging. Here are its properties:
logConfig.muteLogs: boolean
If the logs (logger.log/info) are muted
Default: true
logConfig.ignoreWarnings: boolean
If warnings are ignored. (logger.warn)
Default: false
logConfig.debug: boolean
If debug mode is on -> all debug messages are going to be printed.
Default: false
logConfig.logger: ILogger
The logger to use
Default: new ConsoleSettingLogger()
Custom logging
If you want to write custom logging, I recommend you to look at the code on github, so you understand how it works. I will explain it here very briefly.
If you want a custom logger, just make a class and implement the ILogger
interface.
Do not forget to check the conditions of logConfig
!!! - These are not checked by default!
Another option is to extend one of the logger classes - ConsoleLogger
or ConsoleSettingLogger
.