4

I recently deployed my Node.js blog on AppFog. I plan to use a bucket on Amazon S3 to stream my assets (javascript/stylesheets/images).

How can I make sure that Express.js get static assets to my Amazon S3 bucket instead of the regular /public?

jpmonette
  • 926
  • 1
  • 15
  • 30

2 Answers2

8

I wouldn't stream assets through the node server – it's a waste of resources, and you're going to have to deal with HTTP caching headers.

Instead, your HTML should link directly to the S3 bucket. Instead of:

<script src="/js/script.js"></script>

Do:

<script src="//s3.amazonaws.com/bucket/js/script.js"></script>

Given that you're migrating, just set up a permanent redirect.

app.get(/^\/(js|css|images)\/.*/, function(req, res) {
    res.redirect(301, '//s3.amazonaws.com/bucket' + req.path);
});

This will redirect all requests for things in the js, css, and images folders to a S3 bucket. For example, /js/script.js would redirect to //s3.amazonaws.com/bucket/js/script.js.

This will help ease the transition, but you should still migrate your site's references to the S3 URLs to eliminate the unnecessary HTTP roundtrip cause by having the redirect.

josh3736
  • 139,160
  • 33
  • 216
  • 263
  • So the reason why you wouldn't stream is because it will waste S3 bandwith + my SaaS bandwith, right? Also, is this a good practice, to set every images / js / css there? – jpmonette Feb 07 '13 at 03:54
  • That's one reason. If you didn't employ any caching mechanisms on the Node server (which would be non-trivial to get right), then every request for an asset will go to your server, which you'd then relay to S3. You pay for the bytes transferred from S3 to Node, and then again for Node to client. Another big reason is client cachability: are you prepared to deal with things like the `ETag`, `If-None-Match`, and related headers? These are normally handled for you by `static`, and S3 also takes care of them. Just remember to set `Cache-Control` headers for your S3 objects. – josh3736 Feb 07 '13 at 04:01
  • And yes, I'd say it's good practice to put your static resources on S3. It offloads the burden of delivering static resources from your app servers. It gives you the benefit of having your assets on a separate, cookieless domain, [which is also good practice](http://developer.yahoo.com/performance/rules.html). Additionally, you can upgrade to CloudFront for the added performance boost of using a CDN. – josh3736 Feb 07 '13 at 04:10
  • @josh3736 stumbled upon this and worked great! Wanted to ask you though, what about referencing images? You said that you should just reference the script directly to s3 but in the case of images, should the same practice be done or should the redirect work as an alternative? – Mohamed El Mahallawy Sep 20 '15 at 06:36
  • Reference directly. From a performance perspective, it's always better to avoid a redirect. – josh3736 Sep 20 '15 at 23:02
0

If you really need to do this, use pipe() from the request library: https://github.com/mikeal/request#streaming

7zark7
  • 10,015
  • 5
  • 39
  • 54