2

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: 2015年2月25日 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.

asked Feb 25, 2015 at 14:16

2 Answers 2

2

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

answered Feb 25, 2015 at 14:58
0

If I were you, I would definitely check out Lapis. It's a very lightweight and fast Lua framework for OpenResty. I've really been enjoying it and predict it will have a bright future!

http://leafo.net/lapis/

With it you can easily write a REST API that returns json with code as simple as:

app:get("list_users", "/users", function(self)
 local users = Users:select() 
 return { json = { users } }
end)

A post can be done like this:

app:post("/user/new", json_params(function(self)
 self.user = Users:create({
 email = self.params.email,
 password = self.params.password,
 fname = self.params.fname,
 lname = self.params.lname
 })
 return { json = { self.user } }
end))

The other HTTP verbs can all be handled with similar ease.

Also, as you might expect with anything built to leverage OpenResty, Lapis benchmarks are insanely good: https://www.techempower.com/benchmarks/#section=data-r12&hw=peak&test=query

To boot, the author of Lapis also wrote a CoffeeScript-like language for Lua called MoonScript which is quite nice @ moonscript dot org

answered Mar 10, 2016 at 20:32

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.