mach
mach copied to clipboard
HTTP for JavaScript
Mach is an HTTP server and client library that runs in both node.js and the browser. It has the following goals:
- Simplicity: straightforward mapping of HTTP requests to JavaScript function calls
- Asynchronous: responses can be deferred using Promises/A+ promises
- Streaming: request and response bodies can be streamed
- Composability: middleware composes easily using promises
- Robustness: promises propagate errors up the call stack, simplifying error handling
Servers
Writing a "Hello world" HTTP server in Mach is simple.
var mach = require('mach');
mach.serve(function (conn) {
return "Hello world!";
});
All mach applications receive a single argument: a Connection object. This object contains information about both the request and the response, as well as metadata including the method
used in the request, the location of the request, the status
of the response, and some helper methods.
Applications can send responses asynchronously using JavaScript promises. Simply return a promise from your app that resolves when the response is ready.
var app = mach.stack();
app.use(mach.logger);
app.get('/users/:id', function (conn) {
var id = conn.params.id;
return getUser(id).then(function (user) {
conn.json(200, user);
});
});
The call to app.use
above illustrates how middleware is used to compose applications. Mach ships with the following middleware:
-
mach.basicAuth
: Provides authentication using HTTP Basic auth -
mach.catch
: Error handling at any position in the stack -
mach.charset
: Provides a default charset in responses -
mach.contentType
: Provides a defaultContent-Type
-
mach.favicon
: Handles requests for/favicon.ico
-
mach.file
: Efficiently serves static files -
mach.gzip
: Gzip-encodes response content for clients thatAccept: gzip
-
mach.logger
: Logs HTTP requests to the console -
mach.mapper
: Provides virtual host mapping, similar to Apache's Virtual Hosts or nginx server blocks -
mach.methodOverride
: Overrides the HTTP method used in the request, for clients (like HTML forms) that don't support methods other thanGET
andPOST
-
mach.modified
: HTTP caching usingLast-Modified
andETag
-
mach.params
: Multipart request parsing and handling -
mach.proxy
: Proxy request through to an alternate location -
mach.rewrite
: Rewrites request URLs on the fly, similar to Apache's mod_rewrite -
mach.router
: Request routing (ala Sinatra) based on the URL pathname -
mach.session
: HTTP sessions with pluggable storage including memory (for development and testing), cookies, and Redis -
mach.stack
: Provides ause
mechanism for composing applications fronted by middleware -
mach.token
: Cross-site request forgery protection
Please check out the source of a middleware file for detailed documentation on how to use it.
Clients
Writing an HTTP client is similarly straightforward.
var mach = require('mach');
mach.get('http://twitter.com').then(function (conn) {
console.log(conn.status, conn.response.headers, conn.responseText);
});
By default client responses are buffered and stored in the responseText
connection variable for convenience. However, if you'd like to access the raw stream of binary data in the response, you can use the binary
flag.
var fs = require('fs');
mach.get({
url: 'http://twitter.com',
binary: true
}).then(function (conn) {
conn.responseText; // undefined
conn.response.content.pipe(fs.createWriteStream('twitter.html'));
});
Proxies
Because all Mach applications share the same signature, it's easy to combine them in interesting ways. Mach's HTTP proxy implementation illustrates this beautifully: a proxy is simply an application that forwards the request somewhere else.
var proxyApp = mach.createProxy('http://twitter.com');
// In a server environment we can use the mach.proxy middleware
// to proxy all requests to the proxy's location.
app.use(mach.proxy, proxyApp);
// In a client application we can call the proxy directly to
// send a request to the proxy's location.
mach.post(proxyApp, {
params: {
username: 'mjackson'
}
});
Installation
Using npm:
$ npm install mach
Or, include lib/umd/mach.min.js
in a <script>
tag:
<script src="mach.min.js"></script>
Issues
Please file issues on the issue tracker on GitHub.
Tests
To run the tests in node:
$ npm install
$ npm test
The Redis session store tests rely on Redis to run successfully. By default they are skipped, but if you want to run them fire up a Redis server on the default host and port and set the $WITH_REDIS
environment variable.
$ WITH_REDIS=1 npm test
To run the tests in Chrome:
$ npm install
$ npm run test-browser