Skip to content

Instantly share code, notes, and snippets.

@Raynos
Created September 18, 2012 20:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Raynos/be6206d14e8911188d04 to your computer and use it in GitHub Desktop.
Save Raynos/be6206d14e8911188d04 to your computer and use it in GitHub Desktop.

Streams as Middleware

Imagine a "middleware framework" that is based purely of streams

The main idea is route

route(uri, FunctionThatReturnsStream, FunctionThatReturnsADifferentStream, ...)

Which ends up adding a route to the router

router.addRoute(uri, function (req, res) {
    req
        .pipe(FunFunctionThatReturnsStream(req, res))
        .pipe(FunctionThatReturnsADifferentStream(req, res))
        .pipe(res)
})

Example

var streams = require("middleware-streams")
    // partial function application
    , partial = streams.partial
    // returns a function which calls the first argument with no arguments
    , call = streams.call
    // read-stream
    , from = streams.from
    // through-stream
    , through = streams.through
    , filed = require("filed")
    , path = require("path")
    , es = require("event-stream")

var handler = streams({ /* config???? */ })
    // route(static, function () { return filed(path.join(__dirname, "static") }
    .route("/static/*", function () {
        return filed(path.join(__dirname, "static"))
    })
    .route("/proxypass", function (req) {
        return request("http://otherserver.com" + req.url)
    })
    .route("/hello.json"
        , function () {
            return from([{ msg: "hello" }])
        }
        , function () {
            return es.mapSync(JSON.stringify)
        }
        , contentType("application/json")
    )
    .route("/plaintext"
        , function () {
            return from(["I like text/plain"])
        }
        , contentType("text/plain")
    )
    .route("/")
        .method("GET"
            , function () {
                return request("http://me.iriscouch.com/db", {
                    json: true
                })
            }
            , function () { return es.wait() }
            , function () {
                return es.mapSync(function(chunk) {
                    return "<html><head>cool</head><body>" + chunk.index +
                        "</body></html>"
                })
            }
            , contentType("text/html")
        )
    ;

http.createServer(handler, 8080)

function contentType(type) {
    return function (req, res) {
        return through(through.write, function () {
            res.setHeader("Content-Type", type)
        })
    }
}
var to = require("write-stream")
, partial = require("ap").partial
, from = require("read-stream")
, es = require("event-stream")
, through = require("through-stream")
streams.to = to
streams.from = from
streams.partial = partial
streams.call = call
streams.through = through
module.exports = streams
function streams() {
// TODO
handler.route = route
return handler
function handler(req, res) { /* route requests */ }
function addRoute(uri, handler) { /* add the route to the router */ }
function route(uri) {
var streams = [].slice.call(arguments, 1)
addRoute(uri, handler)
function handler(req, res) {
return es.pipeline.apply(null, streams.map(function (f) {
return f(req, res)
}))
}
}
}
function call(f) {
return function () { f() }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment