怎么在Openresty中REST?

2020-09-17 14:28:50 浏览数 (1)

REST究竟指的是什么,如果原意英文缩写来看,REST(Resource Representational State Transfer ), 解释很诗意,很烂漫,但基本看不出一个所以然。

实际干活当中,写的最多就是REST API,实现客户端与服务器之间交互 ,数据传输与功能调用。

简单描述整体过程,是在服务器端口接收由客户端的发送HTTP的GET与POST请求,并携带传递JSON格式协议的数据,返回的数据形式也是JJSON形式, JSON协议有使用只是RESTful API风格的接口设计的一个样式。

状态码与普通HTTP返回状态码类200、500、404等。对URL命名规则约定, 便于人类快速识别您写的的是个RESTful API,更多概念细节大家查阅权威资料,这里只介绍实操基本概念。推荐大家看Graylog项目中的REST API设计,是一个很具体且多样的实用例子。

如何用Openresty实现一个粗放原生态的毛坯RESTful API?

一般在Openresty中可能用两种形式实现, 一种是直接在conf里实现,一种是通过Lua脚本实现。还可以直接用Moonscript实现,用Lua封装简化一个API接口创建的过程。

1.conf文件实现REST API

代码语言:javascript复制
location /json/ {
	    default_type application/json;
	    add_header Content-Type 'text/html; charset=utf-8';
	    return 200 '{"about":"糖果的Lua入门教程,"sites":"https://lua.ren"}';
}

明确在配置中声明返回的是JSON数据。

2.Nginx Lua实现REST API

代码语言:javascript复制
json = require "cjson"
ngx.header['Content-Type'] = 'application/json; charset=utf-8'
ngx.say(json.encode(ret))

三步操作:

a).设置HTTP的响应头信息:

代码语言:javascript复制
ngx.header['Content-Type'] = 'application/json; charset=utf-8'

b).json.encode(“Lua的Table型变量”):

代码语言:javascript复制
json = require "cjson" 
res_json_data = json.encode(ret)

c).用say函数显示,经过encode的JSON数据。

代码语言:javascript复制
ngx.say(res_json_data)

Nginx lua要实现API读取或是返回JSON基本依赖的ngx.header这个API,对JSON数据编码与解码需要依赖cjson库进行encode和decode。

上面的三个步骤只是解决了基本的JSON数据返回的问题,并没有考虑到与路由结合,简单快速的实现方法就是在conf的location设置中直接嵌入lua代码。

代码语言:javascript复制
    location /json/ {
        access_by_lua_block '
            json = require "cjson"
            ngx.header['Content-Type'] = 'application/json; charset=utf-8'
            ngx.say(json.encode(ret))
	';
    }

3.Lua毛坯Web框架

如果我们把接口的Lua代码实现都写到Nginx的conf文件中,就太不方便了,这时候会通过简单的设计,把Lua路由的功能放到纯Lua代码中实现,实现动态的接口增删改,而不需要去修改nginx的conf文件。

因此,我们用Lua实现的了一个路由数组的,进行用户路由的线性配对,如果用户当前请求的URI与路由表中的URI一致,就对应执行与数组下标对应的另一个执行函数,并使用用户请求时传递参数,针对路由URI配对的算法和优化设计可以后续有更丰富的实现。

我们截取了简易Lua Web框架,根据请求中的URI与函数对应执行,并返回JSON数据的一个片段,这个使用Lua语言特有的闭包特性来完成URI到函数过程执行的过程,更多基础可以参考https://lua.ren中的一些Lua基础介绍,如果没有找不到,可能是哥根本没写。

代码语言:javascript复制
        app.run = function()
                fun = Route:run(app.router)
                if fun then
                    local ret = fun(app.req, app.id)
                    local rtype = type(ret)
                    if rtype == "table"  then
                        json = require "cjson"
                        ngx.header['Content-Type'] = 'application/json; charset=utf-8'
                        ngx.say(json.encode(ret))
                    end 
                end 
        end 

关于用Lua实现路由不展开介绍, 我们来展示一下如何不通过修改nginx.conf文件,进行多个路由与函数过程调用的实现。

代码语言:javascript复制
local HiLog = require "HiLog"
local utils = require "utils.utils"
local Application = require "orc"
app = Application.new()
app:get("/json", function(request,id)
    return {k='lua', v='ren'}
end)
app:get("/string", function(request,id)
    return "https//lua.candylab.net"
end)
return app.run()

代码中的/json实现了返回JSON协议数据的功能,但并不属于一个完全正则的Restful API, 只是想通过这3种方式展现一下直接在OR中实现Restful API的可能性。

Moonscirpt是一种比Lua抽象程度要高的语言,可以将Moonscript翻译成Lua脚本,被Openresty理解执行,参见https://lua.ren。

文章大纲

  • 1.conf文件实现REST API
  • 2.Nginx Lua实现REST API
    • a).设置HTTP的响应头信息:
    • b).json.encode(“Lua的Table型变量”):
    • c).用say函数显示,经过encode的JSON数据。
  • 3.Lua毛坯Web框架

0 人点赞