The logging mode. This can be changed to see more or less details. It can also be
exploited in your own logging using the import('dffrnt.utils').LG functions.
The Port Number this web-server will listen on.
An object specifiying paths to SSL files. This is null, if SSL/HTTPS/2 is not
required. If it is configured, and the {@link CFG.Settings.SSL.Cert} and/or {@link CFG.Settings.SSL.Key}
files are nowhere to be found, you'll obviously have issues.
An optional list of any URLs pointing to auth/rest Spaces (see: {@link CFGSpaces}) that this particular
web-server may need to connect to remotely. This allows you to customize the FQDN of any auth/rest
Spaces you've configured without breaking the whole system (lol).
A Space is really just a Socket.IO.Namespace that Client-Browsers and instances of dffrnt.api can
connect to. Depending on the implementation of dffrnt.api, certain Spaces will be required to connect
to another auth/rest Space -- even if all of said Spaces are within the same instance:
| Instance | Requirement |
|---|---|
auth only |
Needs a remote connection to it's internal Namespace. |
rest only |
Needs a remote connection to an auth-Space (if using authentication). |
page only |
Needs a remote connection to a rest-Space (unless page data is all static). |
auth+rest |
Needs a remote connection to a auth-Space. |
rest+page |
Needs a remote connection to a rest-Space. |
auth+rest+page |
Needs a remote connection to an auth-Space and a rest-Space. |
If this property is not set, the system will assume ${protocol}://localhost/gbl-${spaceName}, where
${spaceName} is the name provided for any given auth/rest Space in {@link CFGSpace.config}.
These can refer to Spaces that are internal, as well as external to this particular web-server. This can be
useful when there becomes a need to "break up" the functionality into separate web-server. Take this project
structure, for example:
[Your-Machine]
├── dffrnt.api-auth/ >> This web-server will handle the Authentication @ https://localhost:7443/gbl-auth
├── dffrnt.api-rest/ >> This web-server will handle the Data Requests @ https://localhost:8443/gbl-rest
└── dffrnt.api-view/ >> This web-server is the Web-App for the Clients @ https://mysite.com
The settings for each instance would be configured as follows:
// [Your-Machine]/dffrnt.api-auth/config/settings.cfg.js
module.exports = {
// Needs a remote connection to it's internal Namespace.
Services: ["https://localhost:7443/gbl-auth"]
};
// [Your-Machine]/dffrnt.api-auth/config/settings.cfg.js
module.exports = {
// Needs a remote connection the auth-Space.
Services: ["https://localhost:7443/gbl-auth"]
};
// [Your-Machine]/dffrnt.api-auth/config/settings.cfg.js
module.exports = {
// Needs a remote connection to the auth-Space, and the rest-Space.
Services: ["https://localhost:7443/gbl-auth","https://localhost:8443/gbl-rest"]
};
In the scenario above, you have a single-machine running 3-instances of dffrnt.api. Each are
configured accordingly to handle their specified tasks.
But what if you wanted to take the separation even further? Like using separate machines for each instance? For example
[Machine-1]
├── dffrnt.api-auth/ >> This machine will handle the Authentication @ Port 443 (https://auth.mysite.com)
[Machine-3]
├── dffrnt.api-rest/ >> This machine will handle the Data Requests @ Port 443 (https://rest.mysite.com)
[Machine-3]
└── dffrnt.api-view/ >> This machine will is the actual WebApp @ Port 443 (https://mysite.com)
The settings for each would be configured as follows:
// [Machine-1]/dffrnt.api-auth/config/settings.cfg.js
module.exports = {
// Needs a remote connection to it's internal Namespace.
Services: ["https://auth.mysite.com"]
};
// [Machine-2]/dffrnt.api-auth/config/settings.cfg.js
module.exports = {
// Needs a remote connection the auth-Space.
Services: ["https://auth.mysite.com"]
};
// [Machine-3]/dffrnt.api-auth/config/settings.cfg.js
module.exports = {
// Needs a remote connection to the auth-Space, and the rest-Space.
Services: ["https://auth.mysite.com","https://rest.mysite.com"]
};
You could take it even further, setting up multiple instances of each implementation, every one
of them on their own machine, use NGinX (or something) to load-balance each Service and
these config-settings would still apply. Unfortunately, I don't have the time or patience to
write up that example.
dffrnt.api comes with OpenAPI 3.0 support by automagically (lol) creating REST documentation
for any EndPoints created within your App. That said, the top-level description of your REST-API
is up to you to define.
Once the application-server is up and running, the JSON document can be found at /apidocs.
This is shot-for-shot the same info, externalDocs, and servers object described in the
OpenAPI 3.0 spec (execpt for the openapi version), so
check that out to get an idea of what goes where. Any other objects are defined... _automagically (LOL).
{
info: {
title: "My API",
description: "It's an API Doc.",
termsOfService: "https://www.mysite/terms",
contact: {
name: "My Site Support",
email: "custome.support@mysite.com",
url: "https://www.mysite/support",
},
version: "2.1.8"
},
}
A collection of STTG.Folder configurations for file-serving.
The dffrnt.api framework automatically installs and uses two predefined
-- and reserved -- STTG.Folders, Publics & Uploads. These folder
configurations are required internally, but can be altered by redifining them
here; however, doing so -- particularily, with Publics -- could potentially introduce
problems. That said, do it at your own risk, and only if you know what you're doing.
This is where various, public, browser-related files/folders go:
| Location | Description |
|---|---|
public/comps |
Bower components. |
public/css |
CSS files. |
public/less |
LESS files; if using. |
public/fonts |
Various Font files. |
public/html |
Extra HTML files. |
public/images |
Site Images. |
public/images/icons |
Site Icons |
public/js |
Important JavaScript bundles, and extra files (if needed). |
{
Publics: {
Folder: 'public',
Age: 365*86400,
Matcher: /\?(?:\w+=.+)$/,
},
}
This is where any uploads to your site will go. The name and structure of this directory is entirely up to you.
{
Uploads: {
Folder: 'storage',
Age: 365*86400,
Matcher: /\?(?:\w+=.+)$/,
},
}
Configurations for session-handling, authentication, and call-limits.
An arbitrary string used to sign sessions. The longer the better.
The maximum Age of saved (In) & unsave (Out) SessionCookies.
This is the maximum Age -- in milliseconds -- of an unsaved SessionCookie. This
should be shorter than the Session.Age.In value.
This is the maximum Age -- in milliseconds -- of an saved SessionCookie. A
SessionCookie is saved when a User is considered logge-in. This should be longer
than the Session.Age.Out value.
Configurations for the REDIS server. This is used for sessions, but any non-reserved DBs
are exposed to CFG.AuthPoints & CFG.DataPoints configuration. Those would be declared
here and can serve any purpose you want them to.
Reserved DBs are as follows. Their Index properties can be changed (if you already have DBs in-use),
but their Name must remain the same. (IT's a weird way to do things, I know, but REDIS only use indexes to reference their DBs.)
The properties used to connect to your REDIS server.
The url/ip-address of your REDIS server.
The port-number of your REDIS server.
The password of your REDIS server.
This is the DB where all session-data is stored. The Index can be changed; the Name
cannot be.
The other stores. The 3 list here are resvered, but you can add more if you'd
like. The Indexes of the reserved stores can be changed; their Names cannot
be.
...
...
An collection of optional Plugins that you can define and use within
config/authpoints.cfg.js & config/endpoints.cfg.js via the Plugins object.
Configurations for this
Applicationserver.Example
These are placed in
config/settings.cfg.js.module.exports = { Debug: false, Port: 8080, SSL: { Cert: "./mysite.chain.pem", Key: "./mysite.key.pem", }, Services: [ 'http://localhost:8080/gbl-accessor', 'http://localhost:8080/gbl-rest', ], APIDoc: { ... }, Folders: { Publics: { Folder: 'public', Age: 365*86400, Matcher: /\?(?:\w+=.+)$/, Headers: null, }, Uploads: { ... }, }, Session: { Secret: "¿mYd0GiS!nmYeyE&shEs4yS@uE?", Age: { In: ((1000*60*60)*24), Out: (1000*300) }, REDIS: { Config: { Host: 'localhost', Port: 6379, Password: 'p@55w012d', }, Main: { Index: 0, Name: 'Client' }, Stores: [ { Index: 1, Name: 'Users' }, { Index: 2, Name: 'Limits' }, { Index: 3, Name: 'Lockers' }, ] }, Auth: { Flush: false, SQL: { Login: "SELECT user_name, password FROM users WHERE user_name = ?", Profile: "SELECT * FROM users WHERE id = ?" }, Format: { Account: 'user_name', Profile: [ ... ], Scopes: [ ... ] } }, Limits: { All: { "IP/Day": { total: 5000, method: 'all', lookup: ['connection.remoteAddress'], }, }, Optional: { "Constant/Second": { total: 200, method: 'get', lookup: ['connection.remoteAddress'] } } } } };