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
Application
server.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'] } } } } };