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框架