Proxy external JSON calls
You can take an external API and run it through your server instead of letting the client call it directly.
location ^~ /ext_api2/ {
proxy_pass http://api.server.com/;
}
That means a request for
will turn into
Setting up a proxy can yield a number of benefits...
Proxy caching
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=STATIC:64m inactive=60m max_size=128m;
proxy_cache STATIC;
proxy_cache_valid 200 204 302 1d;
Now it won't hit the external API if the same request is called by multiple clients. If it is a pay API this could save you money and it could also just speed up the responsiveness of your site.
Proxy timeouts
proxy_connect_timeout 5;
proxy_read_timeout 5;
proxy_send_timeout 5;
You can set the timeouts per proxy (or globally), thus controlling how long the client will wait for each request. With timeouts in place you can ensure the page doesn't hang on something, eventually loads, and gracefully degrades the way you want it to -- even for components you don't control.
Strip headers
proxy_hide_header Set-Cookie;
Some external APIs like to do things to clients (like set cookies). You can protect your users from that by stripping them (or other headers).
Reset headers
proxy_set_header Referer http://duckduckgo.com/;
Similarly, you can reset your headers. This can protect privacy by zeroing out search terms (in the case of the Referrer), but you can also set custom headers.
Hide private API keys
Many APIs require use of a key, which you generally don't want to expose client-side. You can still allow for client-side calls by proxying them and then having nginx add the key.
location ^~ /ext_api5/ {
rewrite ^/ext_api5/(.*) /api/check/$1/key/e95fad09aa5091b7734d1a268b53cef5 break;
proxy_pass http://api.server.com/;
}
Now a request for
will turn into
Turn JSON into JSONP
JSONP is a slight modification of JSON where the object is wrapped in a callback function usually specified by you. For example, say you grab a JSON object from somewhere that looks like this:
{"Name": "Cheeso", "Id" : 1823, "Rank": 7}
With JSONP you specify a callback function like 'parseResponse' and then it looks like this:
parseResponse({"Name": "Cheeso", "Id" : 1823, "Rank": 7})
This is useful for two reasons. First, the function will be called automatically when it is done loading. Second, it allows you to get around cross-domain errors.If the above API was yours it's easy to call within a client-side script. But if it isn't yours, i.e. on another domain, and you try to call it you'll often get lots of cross-domain errors. The way around this is to use JSONP. Then you can do something like this:
<script type="text/javascript" src="http://other.server.com/api/?q=param&callback=parseResponse"> </script>
You could also do that via JS, e.g.
function add_script(url) {
var script,scripts;
script = document.createElement('script');
script.type='text/javascript';
script.async = true;
script.src = url;
scripts = document.getElementsByTagName('script')[0];
scripts.parentNode.insertBefore(script, scripts);
}
add_script('http://other.server.com/api/?q=param&callback=parseResponse');
Now here's the problem. Most external APIs don't have JSONP capability.
No bother, with nginx you can turn JSON into JSONP.
location ^~ /ext_api3/ {
echo_before_body 'parseResponse(;
proxy_pass http://api.external.com/;
echo_after_body ');';
}
This uses the HTTPEchoModule to wrap the JSON response in the callback for the external API.
Custom logs
The HTTPLogModule allows you to specify log formats within location blocks, which means you can write your API logs to a separate file. It also means if you proxy via a location block as in the examples above, you could give each proxy their own access and error logs with different parameters, e.g. error log level.
Update: good comments on HN.
I'm the CEO and Founder of DuckDuckGo.
More about me.
If this post was useful to you, please share it:
Tweet
Get new posts:
Follow @yegg
Check out the left column for top posts and here are recent posts.
Have a comment? Please let me know.