1.12.2 • Published 1 year ago

starless-server v1.12.2

Weekly downloads
-
License
ISC
Repository
-
Last release
1 year ago

Starless Server

All in one, minimalist web server for spa, express, lambda, azure function, graphql and socket.io.

Installation

If this is a brand new project, make sure to create a package.json first with the npm init command.

Installation is done using the npm install command:

npm install starless-server

Quick Start

Install starless-server in your project.

npm install starless-server

Open package.json and add the following scripts:

"scripts": {
  "start": "starless-server start",
  "build": "starless-server build --azure-functions --aws-lambda --aws-sam-lambda"
}
  • start - Runs starless-server start to start a production server
  • build - Bundles app for azure-functions and lambda

    Azure Functions Core Tools is required for building azure-functions

Create two directories routes and public at the root of your application:

  • routes - Associated with a route based on their file name. For example routes/posts.js is mapped to /posts
  • public - Stores static assets such as images, fonts, etc.

Inside the routes directory add the posts.js file to get started. This is the route that is handled when the user request /posts.

Populate routes/posts.js with the following contents:

const posts = [
  {
    id: 1,
    title:
      "Can't Stop Thinking About Her? Here's Why You Need to Meet More Girls",
    description: "lorem ipsum",
    content:
      "You know that feeling. There's this girl you've been chasing forever.
      You positively, absolutely, can't stop thinking about her. She's the most amazing woman in the world
      -- you're certain of it. There's never been another one like her.",
  },
];

module.exports = (req, res) => {
  res.json({
    code: 200,
    message: "Fetched posts successful.",
    data: posts,
  });
};

After the set up is complete:

Routes

In starless-server, a route is a function exported from a .js file in the routes directory. Each route is associated with a route based on its file name. If you create routes/comments.js, it will be accessible at /comments.

Three types of function can be used in routes directory.

  • Azure Function
const httpTrigger = async function (context, req) {
  context.log("HTTP trigger function processed a request.");
  context.res = {
    body: {
      message: "hello from azure function",
    },
  };
};
module.exports = httpTrigger;
  • Lambda
const handler = async (event) => {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: "hello from lambda",
    }),
  };
};
exports.handler = handler;
  • Express
module.exports = (req, res) => {
  res.json({ message: "hello from express" });
};

Note Express next middleware function is not supported in serverless functions.

Express router is also supported because it internally used express middleware.

const express = require("express");

const router = express.Router();

router.get("/", (req, res) => {
  res.json({ message: "hello from express router" });
});

module.exports = router;

Dynamic Routes

starless-server supports express dynamic routes. For example, if you create a file called routes/posts/[id].js, then it will be accessible at posts/1, posts/2, etc.

const posts = [
  {
    id: 1,
    title:
      "Can't Stop Thinking About Her? Here's Why You Need to Meet More Girls",
    description: "lorem ipsum",
    content:
      "You know that feeling. There's this girl you've been chasing forever.
      You positively, absolutely, can't stop thinking about her. She's the most amazing woman in the world
      -- you're certain of it. There's never been another one like her.",
  },
];

module.exports = (req, res) => {
  const post = posts.find((p) => (p.id = req.params.id));

  if (!post) {
    return res.status(404).json({
      code: 404,
      message: "Post not found!",
    });
  }

  res.json({
    code: 200,
    message: "Fetched post successful.",
    data: post,
  });
};

Static File Serving

starless-server can serve static files, like images, under a folder called public in the root directory. Files inside public can then be requested by your browser starting from the base URL /.

Serving Single Page Application

You don’t necessarily need a separate static server in order to run a SPA project in production. Place SPA build folder in the root directory and rename it to dist. starless-server will look for index.html under dist directory. If your index.html is not at the root of dist directory, you can change it from .env with spa_path=dist/somefolder.

Environment Variables

starless-server has built-in support for loading environment variables from .env into process.env.

port=3001
spa_path=dist/authentication
graphql_path=/api/graphql
request_body_size=1000kb

Worker Process

If you want to run multiple instances of server that can distribute workloads among their application threads, you can add worker_processes in environment.

...
worker_processes=4
...

Note Default worker_processes count is 1. If auto is set, server will set all available cpus count.

SSL Certificate

If you want to add SSL certificate, you can set certificate file path in ssl_key and ssl_cert in environment.

...
ssl_key=~/cert/key.pem
ssl_cert=~/cert/cert.pem
...

GraphQL API

starless-server can be used as GraphQL API server.

Create graphql directory at the root of your application and then create two files schema.gql and root.js at graphql directory.

  • schema.gql - Construct a schema, using GraphQL schema language
  • root.js - The root provides a resolver function for each API endpoint

Populate graphql/schema.gql with the following contents:

type Query {
  hello: String
}

Populate graphql/root.js with the following contents:

module.exports = {
  hello: () => {
    return "Hello world!";
  },
};

After the set up is complete:

Socket.IO

starless-server has build in support for socket.io. In starless-server, an event is a function exported from a .js file in the events directory. Each event is associated with its file name. If you create events/chat.js, it will listen at chat event.

Create events directory at the root of your application.

Example events/chat.js

module.exports = (io, socket) => (anotherSocketId, msg) => {
  socket.to(anotherSocketId).emit("chat", socket.id, msg);
};

PeerServer

starless-server has build in support for peerjs. To listen for peer connection you must add peer_connection environment to on in .env file.

peer_connection=on

After starting the server, open the browser and check http://localhost:3000/peerjs/

Hooks

If you want to run some scripts before or after server start, create hooks.js at the root of your application.

There are eight life cycle hooks

  • beforeServerStart - Run before server start
  • afterServerStart - Run after server start
  • afterMasterProcessStart - Run after primary process start
  • afterWorkerStart - Run after worker start
  • errorHandler - Express error handler
  • afterPeerConnected - Run after peer connects to the server
  • afterPeerDisconnected - Run after peer disconnects from the server
  • afterSocketIOStart - Run after socketio server start
  • afterSocketConnected - Run after socket connected
exports.beforeServerStart = (app) => {
  console.log("Before server start.");
};

exports.afterServerStart = (server) => {
  console.log("After server start.");
};

exports.afterMasterProcessStart = (cluster) => {
  console.log("After master process start.");
};

exports.afterWorkerStart = (cluster) => {
  console.log("After worker start.)
}

exports.errorHandler = (err, req, res, next) => {
  console.error(err);
  res.status(500).json({ message: err.message });
};

exports.afterPeerConnected = (client) => {
  console.log("After peer connected.");
};

exports.afterPeerDisconnected = (client) => {
  console.log("After peer disconnected.");
};

exports.afterSocketIOStart = (client) => {
  console.log("After socketio start.");
};

exports.afterSocketConnected = (io, socket) => {
  console.log('After socket connected.')
}

Note Hooks are only works in starless-server. Do not use it for azure functions and lambda applications.

Building Serverless Functions

In starless-server, you can write both Azure Functions and AWS Lambda. When you want to deploy those functions to lambda or azure-functions you don't need to worry about changing azure function code to lambda or lambda code to azure function vice versa. starless-server will automatically handle those heavy task for you when building.

Three options can be passed in build command:

  • --azure-functions - build for azure-function
  • --aws-lambda - build for lambda
  • --aws-sam-lambda - build for sam lambda

Open package.json and add the build scripts:

"scripts": {
  ...
  "build": "starless-server build --azure-functions --aws-lambda --aws-sam-lambda"
}

Azure Functions Core Tools is required for building azure-functions

Run npm run build. Two directories azure_functions, aws_lambda and aws_sam_lambda will created in your application root directory.

  • For deploying azure function see more at Azure Function
  • For lambda you must manually copy codes from aws_lambda directory and paste at lambda functions console. Files not from routes directory are placed and zipped in layers/common/common.zip. You must upload common.zip as lambda layer. See more at Lambda Layers

Swagger

starless-server allows you to serve auto-generated swagger-ui generated API docs, based on a swagger.json file. Create swagger.json at the root of your application. If swagger.json is not existed, starless-server will auto generate blank swagger.json file.

Config

If you want to change certain settings like cors or request body size or peer server options, create config.js at the root of your application.

module.exports = {
  cors: {
    origin: "*", // default cors origin
  },
  bodyParser: {
    limit: "100kb", // default limit
  },
  peer: {
    path: "/",
  },
  socketio: {
    cors: {
      origin: "*",
    },
  },
  rules: [
    {
      url: "/*",
      method: "get",
      cache: true,
    },
  ],
};
1.11.10

1 year ago

1.12.2

1 year ago

1.12.1

1 year ago

1.12.0

1 year ago

1.10.5

2 years ago

1.10.4

2 years ago

1.10.3

2 years ago

1.10.2

2 years ago

1.10.9

2 years ago

1.10.8

2 years ago

1.10.7

2 years ago

1.10.6

2 years ago

1.11.4

2 years ago

1.11.3

2 years ago

1.11.2

2 years ago

1.11.1

2 years ago

1.11.8

1 year ago

1.11.7

1 year ago

1.11.6

1 year ago

1.11.5

1 year ago

1.11.9

1 year ago

1.10.1

2 years ago

1.10.0

2 years ago

1.9.7

2 years ago

1.9.6

2 years ago

1.9.5

2 years ago

1.11.0

2 years ago

1.10.13

2 years ago

1.10.11

2 years ago

1.10.12

2 years ago

1.10.10

2 years ago

1.9.4

2 years ago

1.9.3

2 years ago

1.9.2

2 years ago

1.9.1

2 years ago

1.9.0

2 years ago

1.8.6

2 years ago

1.8.5

2 years ago

1.8.4

2 years ago

1.8.3

2 years ago

1.8.2

2 years ago

1.8.1

2 years ago

1.8.0

2 years ago

1.7.10

2 years ago

1.7.9

2 years ago

1.7.8

2 years ago

1.7.7

2 years ago

1.7.6

2 years ago

1.7.5

2 years ago

1.7.4

2 years ago

1.7.3

2 years ago

1.7.2

2 years ago

1.7.1

2 years ago

1.7.0

2 years ago

1.6.9

2 years ago

1.6.8

2 years ago

1.6.7

2 years ago

1.6.6

2 years ago

1.6.5

2 years ago

1.6.4

2 years ago

1.6.3

2 years ago

1.6.2

2 years ago

1.6.1

2 years ago

1.6.0

2 years ago

1.5.5

2 years ago

1.5.4

2 years ago

1.5.3

2 years ago

1.5.2

2 years ago

1.5.1

2 years ago

1.5.0

2 years ago

1.4.14

2 years ago

1.4.13

2 years ago

1.4.12

2 years ago

1.4.11

2 years ago

1.4.10

2 years ago

1.4.9

2 years ago

1.4.8

2 years ago

1.4.7

2 years ago

1.4.6

2 years ago

1.4.5

2 years ago

1.4.4

2 years ago

1.4.3

2 years ago

1.4.2

2 years ago

1.4.1

2 years ago

1.4.0

2 years ago

1.3.3

2 years ago

1.3.2

2 years ago

1.3.1

2 years ago

1.3.0

2 years ago

1.2.9

2 years ago

1.2.8

2 years ago

1.2.6

2 years ago

1.2.5

2 years ago

1.2.4

2 years ago

1.2.3

2 years ago

1.2.2

2 years ago

1.2.1

2 years ago

1.2.0

2 years ago

1.1.10

2 years ago

1.1.9

2 years ago

1.1.8

2 years ago

1.1.7

2 years ago

1.1.6

2 years ago

1.1.5

2 years ago

1.1.4

2 years ago

1.1.3

2 years ago

1.1.2

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago