Sand HTTP Application Server

raw JSON →
2.10.2 verified Thu Apr 23 auth: no javascript abandoned

sand-http is an HTTP application server module designed for the Sand.js framework. It provides a structured approach to building web applications with features like automatic server lifecycle management, regular expression-based routing, Express.js-style middleware, MVC patterns for controllers and views, and graceful error handling per request. As of version 2.10.2, released in early 2021, the package appears to be in an abandoned or minimal maintenance state, with no significant updates in recent years. It heavily leverages CommonJS module syntax and relies on static Generator Functions for controller actions, a pattern that has largely been superseded by async/await in modern Node.js development. Its unique selling points, such as the `sand.ctx` execution context for helper classes, aim to simplify request-scoped data access within the Sand.js ecosystem. The project emphasizes compatibility with ES6 syntactic features within application code, though the module itself is CommonJS.

error SyntaxError: Unexpected token '*'
cause Attempting to run `static *generatorFunction()` in an environment that does not support generator functions, or a transpiler is not correctly configured.
fix
Ensure you are using a Node.js version that supports generator functions (Node.js 6+). If using a transpiler (like Babel), ensure it's configured to handle ES6+ features, including generators.
error TypeError: app.use is not a function
cause The `app` instance is not a `Sand` application or `Http` is not a valid grain.
fix
Verify that app is initialized with new Sand() and that Http is correctly required from sand-http. Ensure the sand package itself is correctly installed and initialized.
error Error: Cannot find module 'sand-http'
cause The `sand-http` package is not installed or not resolvable from the current working directory.
fix
Run npm install sand-http in your project directory. Check your node_modules folder and ensure sand-http is present.
error SyntaxError: Cannot use import statement outside a module
cause Attempting to use ES Modules `import` syntax (`import Http from 'sand-http'`) with `sand-http`, which is a CommonJS module, in a file not designated as an ES module.
fix
Change import Http from 'sand-http'; to const Http = require('sand-http'); and similarly for Controller and Sand. The package primarily supports CommonJS.
breaking sand-http's controller actions are `static Generator Functions`. Modern Node.js applications predominantly use `async/await` for asynchronous operations. Directly converting these to `async/await` will break the framework's `this.req` and `this.res` context binding, which relies on the generator's `yield` mechanism for request-scoped execution.
fix Adhere strictly to `static *actionName()` generator function syntax for controller actions. Avoid `async/await` directly in actions unless explicit middleware or context binding is implemented to support it, which is not natively provided by `sand-http` in its current form.
deprecated The package uses CommonJS (`require`) module syntax exclusively. While Node.js still supports CommonJS, the ecosystem is moving towards ECMAScript Modules (`import/export`). Integrating `sand-http` into an ESM-first project requires transpilation or careful interoperability configurations.
fix For new projects, consider modern frameworks built with ESM. If using `sand-http`, ensure your project uses CommonJS or a bundler configured to handle CJS modules within an ESM project. Direct `import` statements for `sand-http` will fail at runtime.
gotcha Routing patterns in `config/routes.js` use XRegExp-compatible strings, and shortcut character classes like `\d`, `\w` must be double-escaped (e.g., `\\d`). Failing to double-escape will result in incorrect routing or regex parsing errors.
fix Always double-escape backslashes in regex character classes within route definitions: `'/users/(?<userId>\\d+)'` instead of `'/users/(?<userId>\d+)'`.
gotcha The `sand.ctx` global variable is used to access the request-specific context (including `req` and `res`) from helper classes. Relying on global context in asynchronous code can lead to race conditions or incorrect context if not carefully managed, especially with older Node.js versions or non-generator async patterns.
fix When developing helper functions that rely on `sand.ctx`, ensure they are only called within the scope of a `static Generator Function` action or explicitly pass `this` (the context object) to the helper if it performs asynchronous operations that might lose the `sand.ctx` reference.
deprecated The `sand-http` package, and its parent framework Sand.js, appear to be abandoned with the last significant update over three years ago. This implies no active maintenance, security patches, or support for newer Node.js features and best practices.
fix Exercise caution when using this package in new projects or critical applications. Be prepared to fork and maintain the code yourself or migrate to a more actively maintained framework. Evaluate the long-term viability and security implications before committing to `sand-http`.
npm install sand-http
yarn add sand-http
pnpm add sand-http

This quickstart initializes a Sand.js application with the `sand-http` grain, setting up a basic HTTP server, routes, and a controller. It demonstrates the framework's file structure and the use of static Generator Functions for actions. Access at `http://localhost:3000/`.

"use strict";

const Http = require('sand-http');
const Sand = require('sand');
const path = require('path');
const fs = require('fs');

// Create dummy config and controller files for quickstart
const configDir = path.join(__dirname, 'config');
const controllersDir = path.join(__dirname, 'controllers');
const viewsDir = path.join(__dirname, 'views');

if (!fs.existsSync(configDir)) fs.mkdirSync(configDir);
if (!fs.existsSync(controllersDir)) fs.mkdirSync(controllersDir);
if (!fs.existsSync(viewsDir)) fs.mkdirSync(viewsDir);

fs.writeFileSync(path.join(configDir, 'routes.js'), `
module.exports = {
	'/': 'MyController.index'
};
`);

fs.writeFileSync(path.join(configDir, 'http.js'), `
module.exports = {
	all: {
		port: 3000
	}
};
`);

fs.writeFileSync(path.join(controllersDir, 'MyController.js'), `
"use strict";

const Controller = require('sand-http').Controller;

class MyController extends Controller {
	static *index() {
		this.res.writeHead(200, {'Content-Type': 'text/plain'});
		this.res.end('Hello from Sand HTTP!');
	}
}

module.exports = MyController;
`);

console.log('Starting Sand HTTP server on port 3000...');
let app = new Sand({log: '*'});
app.use(Http);
app.start();

process.on('SIGINT', () => {
  console.log('Stopping Sand HTTP server...');
  app.shutdown();
  process.exit();
});