REST Interface Design with Nginx Lua – Proper Methods

luarest

I'm a noob at nginx and lua. But I'm trying to design a REST interface.

The plan is to create a location entry that will match URIs like this:

curl -i -X GET 'http://localhost/widgets/widget?name=testname&loc=20000' -H "Accept:application/json"

OR

curl -i -X POST 'http://localhost/widgets/widget?name=testname&loc=20000&price=10.12' -H "Accept:application/json"

I want to return data like this:

HTTP/1.1 201 Created
Server: nginx/1.6.2
Date: Wed, 25 Feb 2015 13:32:24 GMT
Content-Type: application/json; charset=utf-8

{"name":"testname","loc":"20000","price":"10.12","GET":"http:\/\/localhost\/widgets\/\/widget?name=testname&loc=20000"}

What I've come up with so far:

Within the location block / context, I'm going to test what the request method is (GET vs. POST vs. DELETE) and then execute logic inside separate lua files to do all the CRUD operations. So for example, notice the following quasi pseudo code:

  #curl -i -X GET 'http://localhost/widgets/widget?name=testname&loc=20000' -H "Accept:application/json"
    location /widgets/widget {
            default_type "text/pain";
            #ifisEvil... unless done inside lua
            content_by_lua '

                    if ngx.var.request_method == 'GET' then
                            add logic to call "read_widget.lua"
                            somehow save results from read_widget.lua in string
                            response.body = results_string
                            convert results_string to json format.
                            return results_string_as_json 
                    elseif ngx.var.request_method = 'POST' then
                            add logic to call "create_widget.lua"
                            same logic as GET...
                    elseif ngx.var.request_method = 'DELETE' then
                            add logic to call "delete_widget.lua"
                            same logic as GET...
                    end
            ';
    }

Questions

  1. Is this the right approach to take? Specifically, is it possible to call methods in external files and return large amounts of data from them back in the nginx.conf file?
  2. Even if it's possible, is it a good idea? These external files will contain logic to connect to the datasource, massage the data and then prepare the correct HTTP response… like 201 for new resources, 404's etc etc.

Thanks everyone.

Best Answer

Yes, it is a fair architecture - the concept of a web server taking requests and the passing the call on to another server to process is almost certainly best practice in all cases. At least theoretically you could then hosts your logic files on one or more application servers if load gets too great. Even if this doesn't apply to you right now, its still good to have the flexibility, especially if you end up reusing some of this code in the future.

However, write your 'business logic' files so they do not have any understanding of the http request, so they return normal error codes that are translated into something more http-y by the webserver side of things.

You might also like to see some helper code like lua-resty-rack