node-web-server-with-stuff

1.4.5 • Public • Published

node-web-server-with-stuff

This is a vanilla JS web server made with the nodeJS buit-in http module. It also includes a couple of modules I wrote to make my life easier (up2require and c4console). I made this module with my personal learning/development process in mind. Got used to use Heroku, so it's ready for the heroku deploy (respects its env.PORT by default). It also by default will run in production mode on it and in dev mode locally.

Installation

npm i node-web-server-with-stuff

Usage

Most basic setup-and-run would be

require('node-web-server-with-stuff').server.run()

In this case it will run with default settings: port 3000 locally and whichever Heroku provides for it up there, dev-mode locally and prod-mode up there, /public/ folder for pages supposed to be present in the project root directory and it's better be having at least an index.html, /api/ folder for various API handlers supposed to be present at the root too, but it's not the end of the world if it isn't there. By default API endpoints are secured by one system-level variable ADMIN_KEY, so you may want to set it in Settings tab on Heroku. If none set the key value defaults to its name "ADMIN_KEY". But custom security access checks are much preferred and by default they would be loaded from /access/ folder.

But imported module also can provide some helper functions and/or handle an options object.

const {server, up2, c} = require('node-web-server-with-stuff')
const options = {/* dev: false, port: 5500 */, public: '/front'}
server.run(options)
const {dev} = server
if (dev) require = up2(require)
// ...

Here options object provides a way to configure the server (it can take dev mode and port even though in this instance they are skipped). Here it allows to select another folder for public files. Also there are two functions imported here. up2 is an alias for upgradeToUpdate from my up2require module and c is my shorthand for an advanced console.log variant from my c4console module. In this example I let server decide if it's a dev run or a prod one and use or don't use up2 based on that.

We can also configure the APIs. Here is an elaborate example. It provides additional given things (like the database connection or additional functions) to any custom check function or API-handler that cares to take them.

process.env.ADMIN_KEY = '5UPP3Rpassw0rd' // you would do this in a separate .gitignore-d file
const {server} = require('node-web-server-with-stuff')
 
const {validateFn, rules, anything} = require('./from/your/modules.js')
const conn = db.connect(/* credentials */) // your database of choice connection here
const options = {/* secure: false, */ accessors: '/checks', api: ['/data', '/secret_api'],
  given: {conn, validateFn, rules, anything} }
server.run(options)

And then in the /data (or /secret_api) folder could be for example a notes.js (or notes.cjs) file (those API-handlers can also be deep in the sufolders) and in such file would be

module.exports = function ({request, granted, conn, validateFn, rules, anything}) {
  // and here would be the function body, and it's supposed to simply
  // return what should be sent to the client by this API-endpoint
  // data received from the client is available as a promise in request.data
  // granted - is the data returned by the check function
}

This function will handle requests with any http methods at URL /data/notes and those would have to have the cookie key=5UPP3Rpassw0rd or they would be rejected before the handler function will be called. Also that admin-cookie would be renewed for half an hour. To use custom checks we will have to add them in the /checks/ folder as .js or .cjs files. For example there can be user.js that provides a function for checking if user is actually logged in.

module.exports = async ({request, response, conn}) => {
  const user = await conn.collection('users').findOne({token: request.cookie.token})
  if (user) return user.login // this returned value will be passed to the
                             // API handler above as granted (or grant)
}

And if this function will throw or return falsy value the API will gracefully fail to provide the data requested. Otherwise a handler will be called to handle the requested API. The file can also look like this

module.exports = {
  GET: {access: 'guest', handler({conn}) {
    // this one will require no credentials whatsoever
    // get notes via the connection and simply return them
  }},
  POST: {access: 'user', handler({req, resp, grant, conn, validateFn, rules}) {
    // this one will use the checks.user(request, response, given) to check
    // if user is recognised and it can for example get, validate and save
    // new notes for him or throw - needs to throw JSON string to send it
    // to the client
  }},
  DELETE: {access: 'moderator', handler({conn}) {
    // this one will use the checks.moderator(request, response, given) to
    // check user and it can for example delete some notes
  }}
}

In these examples request (or req) and response (or resp) objects have all the getters, setters and methods provided by the httpity module. For example request.data is a promise giving us the cumulative object from the request body and request URL querystring both parsed if needed. And granted (or grant) may for example contain an id, login or name of the user confirmed (returned) by the used checks.method() or any other internal information corresponding to the successful access check.

Package Sidebar

Install

npm i node-web-server-with-stuff

Weekly Downloads

4

Version

1.4.5

License

ISC

Unpacked Size

16.5 kB

Total Files

7

Last publish

Collaborators

  • unibreakfast