Skip to content

Instantly share code, notes, and snippets.

@Raynos
Last active August 18, 2022 21:51
Show Gist options
  • Save Raynos/9637439 to your computer and use it in GitHub Desktop.
Save Raynos/9637439 to your computer and use it in GitHub Desktop.

Response

files

var http = require('response/http')

var server = http.createServer(function (req) {
  if (req.url === '/test.js') { 
    return fs.createReadStream('file.js')
  }
})

When returning a readable stream it will lookup the mime type from stream.path and set the proper content-type

html, json, txt

var http = require('response/http')
var response = require('response')

var server = http.createServer(function (req) {
  if (req.url === '/') {
    return response.html('<html>Hello World</html>')
  } else if (req.url === '/sitemap.html') {
    return fs.createReadStream('sitemap').pipe(response.html())
  } else if (req.url === '/something.json') {
    // might be more performant to return thunk instead of stream
    // and have response/http flush thunk efficiently
    return response.json({ test: 1 })
  } else if (req.url === '/something.txt') {
    return response.txt('some test')
  }
})

.error(err[, statusCode])

var http = require('response/http')

var server = http.createServer(function (req) {
  if (req.url === '/uh-oh') {
    return response.error(new Error("Uh Oh"))
  } else if (req.url === '/555') {
    return response.error(555)
  } else if (req.url === '/501') {
    return response.error(new Error('Uh Oh!'), 501)
  }
})

In addition, errors emitted on the stream piped to response will be passed through the same API and are accesssible in views.

gzip and deflate compression

The compress and gzip keys in an options object are used for compression.

var http = require('response/http')

var server = http.createServer(function (req) {
  if (req.url === '/file.js') {
    return fs.createReadStream('file.js')
      .pipe(response({ compress: req }))
  }
})

You can pass an HTTP Request object and the best compression, if any, will be chosen for you. Alternatively you can pass "gzip" or "deflate" to forcce compression of the response stream.

This compression option is compatible with every other feature in response and will work whether you do file streaming, html, json, or even using views. When passing a view, string or buffer to response the second argument is used as the options object.

var http = require('response/http')

var server = http.createServer(function (req) {
  if (req.url === '/') {
    return response.html('<html>Nope</html>', {
      compress: req
    })
  }
})

status codes and headers

response also has an extended version of node core's HTTP Response API.

All headers setting and checking is done caseless while preserving the original casing when first set. This way you never accidentally send two of the same header but can still support broken clients that check for specific caseing.

.statusCode

Set the statusCode property to send the HTTP status code. This is a non-destructive way to send the status code.

var http = require('response/http')

http.createServer(function (req) {
  return response.html('<html>Error</html>', {
    statusCode: 500
  })
})

.headers

Set multiple headers by passing an object.

var http = require('response/http')

http.createServer(function (req) {
  return response.text('foo', {
    headers: {
      'x-blah': 'somehost',
      'x-blah2': 'anotherhost.com',
      'x-some-thing': ['multiple', 'headers']
    }
  })
})

views (very experimental)

var http = require('response/http')
var cons = require('consolidate')

function handleTemplate(err, opts, callback) {
  if (err) {
    return cons.swig('views/error.html', { err: err }, callback)
  }

  cons.swig(opts.fileName, opts, callback)
}

var server = http.createServer(function (req) {
  if (req.url === '/test1') {
    return response.html({
      fileName: 'test.html',
      user: 'mikeal'
    })
  }
// IMPORTANT. configure view globally for server, not
// per response object.
}, {
  view: handleTemplate
})

This is how you would easily support something like a template system. TODO: example.

Credits

Mad props to @marak who handed over the "response" package in npm that he registered way back in the day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment