code7 interactive

Tiny API with Nginx

How to build a tiny REST API using Nginx, Memcached and GeoIP.


As it turns out, Nginx can be configured to act like a full fledged REST API. No web application needed.


We had the need for a tiny API and we figured that the problem was simple enough to be implemented inside of Nginx. The three requirements for the API was;

  1. Responses in JSON (and JSONP)
  2. Client country using GeoIP
  3. Data retrieved from Memcached

I recommend that you use the OpenResty (aka. ngx_openresty) bundle if you want to install Nginx, it contains a few really good third party modules. I’m using five Nginx modules in this project; Echo, GeoIP, Memc, RealIp and XSS.

The complete nginx.conf

worker_processes 4;
events {}

http {
  access_log    off;
  error_log     off;
  geoip_country /path/to/GeoIP.dat;

  server {
    listen            9999;
    real_ip_header    X-Real-IP;

    location /redirect_ip {
      set $memc_key 'redirect';

    location /loadbalancer.json {
      default_type "application/json";

      echo -n "{\"geoip_country_code\":\"$geoip_country_code\",";
      echo -n "\"redirect\":\"";
      echo_location -n /redirect_ip;
      echo -n "\"}";

      xss_get on;
      xss_callback_arg callback;
      xss_output_type 'application/x-javascript';

    location /loadbalancer {
      if ($request_method != POST) { return 405; }

      deny all;

      set $memc_key 'redirect';
      set $memc_cmd 'set';
      set $memc_value $arg_var;

Using the API

I like to use cURL when manually testing API’s:

Updating the “redirect” value in Memcached via the API

curl -X POST

Retrieve the JSON

curl -H "X-Real-IP:" \
#=> {"geoip_country_code":"SE", "redirect":""}

And if we want to use JSONP:

curl -H "X-Real-IP:" \
#=> foo({"geoip_country_code":"SE", "redirect":""});