开源软件名称(OpenSource Name):horan-geeker/nana开源软件地址(OpenSource Url):https://github.com/horan-geeker/nana开源编程语言(OpenSource Language):Lua 100.0%开源软件介绍(OpenSource Introduction):Nana
目录 ==== 快速上手
route:get('/index', 'index_controller', 'index')
local response = require("lib.response")
local _M = {}
function _M:index(request)
return response:json(0, 'request args', request.params) -- return response 200 and parse request params to json output
end
return _M
curl https://api.lua-china.com/index?id=1&foo=bar
{
"msg": "request args",
"status": 0,
"data": {
"foo": "bar",
"id": "1"
}
} 压力测试绑定一个 CPUwrk -t1 -c 100 -d10s http://localhost:60000/ Running 10s test @ http://localhost:60000/
1 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 3.70ms 4.23ms 29.84ms 82.74%
Req/Sec 43.31k 2.63k 48.61k 82.00%
431043 requests in 10.02s, 97.01MB read
Requests/sec: 43024.54
Transfer/sec: 9.68MB 内存基本没有变化,单 CPU 打满 对比 lor 框架wrk -t1 -c 100 -d10s http://localhost:60004/hello
对比 golang gin 框架wrk -t1 -c 100 -d10s http://localhost:60002/ping
Running 10s test @ http://localhost:60002/ping
1 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 8.05ms 10.04ms 78.14ms 85.71%
Req/Sec 20.39k 3.19k 26.53k 68.00%
203091 requests in 10.02s, 27.31MB read
Requests/sec: 20260.14
Transfer/sec: 2.72MB 安装手动安装
文档项目配置
路由
route:post('/login', 'auth_controller', 'login')
支持 http 请求类型
路由参数当需要使用 url 来获取参数时,你可以这样写路由配置,id 会传到对应的 show() 方法里 route:get('/users/{id}', 'user_controller', 'show') 多个参数使用花括号来代表传递的参数,如: route:get("/users/{user_id}/comments/{comment_id}", 'user_controller', 'comments') 可匹配 function _M:comments(user_id, comment_id)
...
end 路由群组路由群组主要用来定义一群 uri 的公共属性,目前支持群组中间件,比如下边需要在 route:group({
middleware = {'authenticate'},
}, function()
route:post('/logout', 'auth_controller', 'logout') -- route:http_method(uri, controller, action)
route:post('/reset-password', 'user_controller', 'resetPassword')
end) 中间件
function _M:handle()
if not auth_service:check() then
return false, response:json(4,'no authorized in authenticate')
end
end 当返回 false 的时候会直接返回 控制器在路由匹配的 Requestlocal request = require("lib.request")
local request = require("lib.request")
local args = request:all() -- get all params,not only uri args but also post json body
args.username -- get username prop 参数获取local request = require("lib.request")
local args = request:all() -- 拿到所有参数,同时支持 get post 以及其他 http 请求
args.username -- 拿到username参数 Response框架使用的
return response:json(0x000000, 'success message', data, 200)
--[[
{
"msg": "success message",
"status": 0,
"data": {}
}
--]] 或者返回错误信息 return response:json(0x000001)
--[[
{
"msg": "验证错误",
"status": 1,
"data": {}
}
--]] 当然你可以在 定义 response json 协议在 验证数据local validator = require('lib.validator')
local request = require("lib.request")
local args = request:all() -- 拿到所有参数
local ok,msg = validator:check(args, {
name = {max=6,min=4}, -- 验证 name 参数长度为4-6位
'password', -- 验证 password 参数需要携带
id = {included={1,2,3}} -- 验证 id 参数需要携带且是 1, 2, 3 中的某一个
}) Cookie在 helpers.set_cookie(key, value, expire) -- expire 是可选参数,单位是时间戳,精确到秒
helpers.get_cookie(key) 数据库操作 ORM
-- 在 models 文件夹里,定义一个表名为 users 的模型, user.lua
local Model = require("lib.model")
local User = Model:new('users')
return User 检索-- 拿到 users 表 `id` 为 1 的用户
local user = User:find(1)
-- 获取表中所有数据
local users = User:all()
-- 返回 users 表中 username 字段的值是 `cgreen` 的,`password` 字段的值是 `xxxxxx` 的多条数据,注意此处返回是 table 数组,`first()` 方法返回的是单条数据
local user = User:where('username','=','cgreen'):where('password','=','xxxxxxx'):get()
-- 返回 `name` 为 `xxx` 或者 `yyy` 的所有用户 table 数组
local users = User:where('name','=','xxx'):orwhere('name','=','yyy'):get() 新增-- 创建一个用户
User:create({
id=3,
password='xxxxxx',
name='hejunwei',
email='heunweimake@gmail.com',
}) 更新-- 更新 id = 1 的 user 的 name 为 test, avatar 为� NULL
local ok, err = User:where('id', '=', 1):update({
name='test',
avatar='null'
})
if not ok then
ngx.log(ngx.ERR, err)
end 删除-- 删除 id = 1 的用户
local ok, err = User:where('id','=','1'):delete()
if not ok then
ngx.log(ngx.ERR, err)
end
-- 软删除
local ok, err = User:where('id','=','1'):soft_delete()
if not ok then
ngx.log(ngx.ERR, err)
end
排序
分页local userPages = User:paginate(1)
-- 返回如下结构:
{
"prev_page": null,
"total": 64,
"data": [
{user1_obj},
{user2_obj},
...
],
"next_page": 2
} 当不存在上一页(下一页)时, 使用原生 sql
模型间关系
一对多以 user 关联 post 为例,在 user 模型中定义关系
-- user.lua
local Model = require("models.model")
local Post = require('models.post')
local User = Model:new('users')
function User:posts()
return User:has_many(Post, 'user_id', 'id')
end
return User
-- post.lua
local Model = require("models.model")
local Post = Model:new('posts')
return Post
-- controller 调用
local user_and_post = User:where('id', '=', user_id):with('posts'):get()
--[[
[
{
"name":"horan",
// 返回值会带上 post 为 key 的对象
"posts":{
"id":67,
"user_id":1,
"title":"article title",
"content":"article content"
},
"email":"hejunweimake@gmail.com"
}
]
--]] 多对一如一个用户可以拥有多篇文章,以 post 关联 user,在 post 模型中定义关系
-- post.lua
local Model = require("models.model")
local User = require('models.user')
local Post = Model:new('posts')
function Post:user()
return Post:belongs_to(User, 'id', 'user_id')
end
return Post
-- user.lua
local Model = require("models.model")
local User = Model:new('users')
return User
-- controller 调用
local posts_with_user = Post:where('id', '=', 1):with('user'):first()
--[[
{
"id":1,
"user_id":1,
"title":"article title",
"user":{
"id":1,
"name":"openresty"
},
"content":"article content"
}
--]] 读写分离通过配置
|