GIN: a JSON-API framework in Lua

GIN: a JSON-API framework in Lua

GIN is a fast, low-latency, low-memory footprint, web JSON-API framework with Test Driven Development helpers and patterns. It is a framework that I open sourced some time ago, as an experiment. 

It all started when I heard so many good things about Lua that I wanted to see it in action and find a project where I could unleash its power. Being an API fan, it came natural for me to build a JSON-API server framework. And GIN was born.

GIN is currently in its early stage, but it already enables fast development, TDD and ease of maintenance. It is helpful when you need an extra-boost in performance and scalability, since it is entirely written in Lua and it runs embedded in a packaged version of nginx called OpenResty. For those not familiar with Lua, don’t let that scare you away: Lua is really easy to use, very fast and simple to get started with.


The syntax of a controller is extremely simple. For instance, a simple controller that returns an application’s version information looks like:

The return statement specifies:

  • The HTTP code 200
  • The body of the response, which gets encoded by GIN into JSON as:
Most of standard JSON-API paradigms are already embedded in GIN.


For instance, Versioning is extremely simple. Major versioning is baked into GIN. Based on directory naming conventions, the controllers that correspond to the versioning specified in the header will be called by GIN automatically. Gin uses the HTTP header Accept to version your API. The header has the format:

So for instance, if your application name (as defined in the file ./config/application.lua) is demo, a client trying to access the version 1 of your API will have to send the header:

Gin only accepts requests that provide JSON in the body, hence the +json portion of the Accept header.


Routing is very easy, too. For instance, this is an example of a routing file that handles multiple versions:


Moreover, Errors are defined globally at application level. This allows to keep track of error numbering and descriptions in a single file. For example, an error file is defined as:

The global variable Errors contains the entries for all possible errors of your application. Every item in this table defines an error, where:

  • The 1000 key is the error number.
  • status (required): is the HTTP status code.
  • message (required): is the error description.
  • headers (optional): are the additional headers to be returned in the response.

When this is defined, then raising these errors from a controller is as simple as calling:

As per this example, this will return a HTTP status 400, with the specified headers and the JSON body:


However, this wouldn’t be a complete framework if it didn’t provide an easy way to test your application. The main testing framework embedded in GIN is Busted, which has an RSpec-like syntax. If you ever used Jasmine you’ll feel right at home. In addition, Gin provides test helpers for you to use.

Controller Tests in Gin are actually integration tests. An instance of OpenResty nginx will be started and a real request will be issued to a test server. The main Gin test helper you’ll need to test Controllers is the method hit, that will perform the integration test for you.

Here’s an example of a controller test (file located in ./spec/controllers/1/info_controller_spec.lua), that is a valid test for the InfoController shown here above:


GIN also has models and support for multiple databases, and includes a migration engine. Furthermore, it is packed with a lot of other features, such as:

  • An API Console (which allows you to try out your API from a web interface).
  • Support for multiple environments.
  • A client console.

Alright, I want to see it!

GIN main website is, where you’ll find full documentation, and even a full tutorial on how to Test Drive your Development with GIN. Full code is available on Github.

Would this be worthy more than a simple experiment?


  1. Just rushed over the APIs – and it really seems to be pretty cool! Which framework would you suggest for implementing views? (handlebars.js maybe?)

    • Hi Jack,
      Gin automatically converts a table to a JSON response, so why would you need views?

      • Sorry, I didn’t get any notification on your answer.

        What I mean is having views for visual data representation on the client side. The overall design of a webpage. To do that I need HTML, CSS and maybe some JavaScript. I can’t feed the user with an endless JSON string – I have to make it look good, you know=)

        So how do you display all the stuff you got from your Model+Controller on a View? Is there any good framework you can recommend? Or is that already integrated?

Leave a Reply