Browse Source

mostly documentation

master
mortie 7 years ago
parent
commit
4cc03ea767
8 changed files with 153 additions and 21 deletions
  1. 93
    1
      README.md
  2. 0
    0
      client/utils.js
  3. 17
    0
      example.js
  4. 16
    16
      index.js
  5. 0
    0
      js/middleware.js
  6. 12
    3
      js/static.js
  7. 1
    1
      package.json
  8. 14
    0
      web/index.html

+ 93
- 1
README.md View File

@@ -1,3 +1,95 @@
# webframe

Web server.
Webframe is a small and dependency free web application framework.

## Usage

Install:

npm install --save webframe

Use:

var webframe = require("webframe");
var app = new webframe.App();

The file example.js contains an example of a small web application.

## Why a new web framework?

A new installation of express is 2.3 megabytes. You end up with 42 dependencies
in your node\_modules directory. The Koa framework is 2.5 megabytes, with 36
dependencies. This isn't bad for a big web application, but I write a lot of
tiny web applications where megabytes of dependencies just feels wrong. As a
result, I have in the past often just used the http module directly. This
framework is a nice middle ground; it provides some of the utility of big web
frameworks, but without adding a ton of extra dependencies to the application.

## Documentation

### webframe.App([options])

Creates a new instance, with an optional options argument.

Options:

* `server`: Your own HTTP (like the one created by http.createHttpServer).
* `port`: The port to listen on. Defaults to the PORT environment variable, or
8080.
* `host`: The host to listen on. Defaults to "127.0.0.1". For the server to be
accessible to the outside world, listen on "0.0.0.0".
* `client_utils`: Whether to add some utility functions to /webframe.js.
Defaults to false.
* `res404`: The string to return for a 404 error. "{{pathname}}" will be
replaced with the pathname.
* `res403`: The string to return for a 403 error. "{{pathname}}" will be
replaced with the pathname.

var app = webframe.App({ client_utils: true });

### app.route(method, path [, middleware], func)

Add a route.

* `method`: What HTTP method the route should be available at.
Valid options: "GET", "POST", "PUT", "DELETE", or "ALL".
* `path`: The path. If it starts with a "^", it will be interpreted as a
regular expression (with `new RegExp(path)`), and the route will be ran on
all matching paths. Routes without a pattern are prioritized over those with
a pattern.
* `middleware`: Optional. An array of middleware functions which will be ran
before the route's function.
* `func`: function(request, response). The function which handles the request.

### app.get, app.post, app.put, app.delete, app.all

Utility functions which just call app.route() with a predefined method value.

E.g `app.get("/foo", handler)` is the same as
`app.route("GET", "/foo", handler)`.

### app.info(str), app.notice(str), app.warning(str), app.panic(str)

Logging functions. They all print a message. `app.panic` also exits, and is
intended for errors so bad you have to crash.

In the future, it will be possible to control the logging level.

### Middleware

`webframe.middleware` contains middleware for the route functions.

* `webframe.middleware.cookies`: Adds `request.cookies`, parsed COOKIE header.
* `webframe.middleware.params`: Adds `request.params`, parsed URL parameters.

In the future, there will be middleware for POST request too.

### webframe.static(root[, before])

Serve static files.

* `app.get("^.*", webframe.static("web"))` will serve all the files in the
`web` directory, so `/index.html` will serve `web/index.html`.
* `app.get("^/static/.*", webframe.static("web", "/static"))` will serve all
files in the `web` directory under `/static`, so `/static/script.js` will
serve `web/script.js`.

+ 0
- 0
client/utils.js View File


+ 17
- 0
example.js View File

@@ -0,0 +1,17 @@
// Replace with require("webframe")
var webframe = require("./index.js");
var mw = webframe.middleware;

var app = new webframe.App();

// Endpoint which uses the "params" middleware to parse URL parameters
app.get("/endpoint", [ mw.params ], (req, res) => {
res.end("Hello, "+req.params.name);
});

// When a an endpoint path starts with a ^, it's interpreted as a
// regular expression pattern. "^.*" matches everything (though endpoints
// with explicit paths, like the "/endpoint" above, are prioritized).
//
// webframe.staic("web") returns a function which serves the file in "web".
app.get("^.*", webframe.static("web"));

+ 16
- 16
index.js View File

@@ -84,20 +84,20 @@ class App {
return;
}

// Run all the before stuff if applicable
// Run all the middleware stuff if applicable
var self = this;
if (route.before) {
var cbs = route.before.length;
if (route.middleware) {
var cbs = route.middleware.length;
function cb() {
if (--cbs === 0)
route.func(req, res, self);
}

for (var i in route.before) {
route.before[i](req, res, cb);
for (var i in route.middleware) {
route.middleware[i](req, res, cb);
}

// Just run the function if there's no before
// Just run the function if there's no middleware
} else {
route.func(req, res, this);
}
@@ -111,7 +111,7 @@ class App {
* path: path,
* func: function
*/
route(method, path, before, func) {
route(method, path, middleware, func) {
if (method !== "GET" && method !== "POST" && method !== "PUT" &&
method !== "DELETE" && method !== "ALL") {
throw new Error("Invalid method.");
@@ -119,8 +119,8 @@ class App {

// Before is optional
if (func === undefined) {
func = before;
before = undefined;
func = middleware;
middleware = undefined;
}

// All necessary arguments must exist
@@ -136,13 +136,13 @@ class App {
method: method,
func: func,
pattern: pat,
before: before
middleware: middleware
});
} else {
this._routeMap[path] = {
method: method,
func: func,
before: before
middleware: middleware
};
}
}
@@ -163,11 +163,11 @@ class App {
*/
template(tmpl, args) { return template(tmpl, args); }

get(path, before, func) { this.route("GET", path, before, func); }
post(path, before, func) { this.route("POST", path, before, func); }
put(path, before, func) { this.route("PUT", path, before, func); }
delete(path, before, func) { this.route("DELETE", path, before, func); }
all(path, before, func) { this.route("ALL", path, before, func); }
get(path, middleware, func) { this.route("GET", path, middleware, func); }
post(path, middleware, func) { this.route("POST", path, middleware, func); }
put(path, middleware, func) { this.route("PUT", path, middleware, func); }
delete(path, middleware, func) { this.route("DELETE", path, middleware, func); }
all(path, middleware, func) { this.route("ALL", path, middleware, func); }

info(str) {
console.log("Info: "+str);

+ 0
- 0
js/middleware.js View File


+ 12
- 3
js/static.js View File

@@ -12,11 +12,21 @@ var mimes = {
zip: "application/zip",
pdf: "application/pdf",

gif: "image/gif",
png: "image/png",
jpeg: "image/jpeg",
jpg: "image/jpeg",
gif: "image/gif",
svg: "image/svg",
svg: "image/svg+xml",
bmp: "image/bmp",
webp: "image/webp",

midi: "audio/midi",
mp3: "audio/mpeg",
ogg: "audio/ogg",

webm: "video/webm",
mkv: "video/mkv",
ogv: "video/ogg",
}

function mimetype(path) {
@@ -52,7 +62,6 @@ function sendfile(path, app, pathname, res) {
}

module.exports = function(root, before) {

return function(req, res, app) {
var pn = req.urlobj.pathname;


+ 1
- 1
package.json View File

@@ -1,6 +1,6 @@
{
"name": "webframe",
"version": "0.1.0",
"version": "0.1.1",
"description": "Web server.",
"main": "index.js",
"scripts": {

+ 14
- 0
web/index.html View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World</title>
</head>
<body>
<p> Hello World! </p>

<form action="/endpoint" method="get">
<label>What's your name? <input type="text" name="name"></label>
</form>
</body>
</html>

Loading…
Cancel
Save