❲Vanilla技巧❳Vanilla(OpenResty)实现的Restful

Posted VanillaOpenResty开发

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了❲Vanilla技巧❳Vanilla(OpenResty)实现的Restful相关的知识,希望对你有一定的参考价值。

来源:idevz
原文地址:http://my.oschina.net/idevz/blog/603657


本文将以一个小例子入手,展示在Vanilla中如何自定义一个路由协议,基于此帮助大家理解Vanilla中路由器、路由协议的用法和实现(确实是我更新了一下昨天的版本)

源起

  • 如何让Vanilla支持Restful(或者Vanilla如何支持xxxx样子的URL访问)?

  • Vanilla的路由器如何使用?

  • Vanilla的请求路由是如何实现的?

  • 综上问题都是一个事儿:如何给Vanilla(OpenResty)添加一个路由协议?

❲Vanilla技巧❳Vanilla(OpenResty)实现的Restful

local restful = {

v1={},

v={}

}


restful.v.GET = {

{pattern = '/user/:user_id', controller = 'test.index', action = 'web_rule'},

{pattern = '/', controller = 'test.index', action = 'web_root'},

}

restful.v1.GET = {

{pattern = '/user/:user_id', controller = 'test.index', action = 'api_v1_rule'},

{pattern = '/', controller = 'test.index', action = 'api_root'},

{pattern = '/test/index/index', controller = 'test.index', action = 'index'},

}


return restful


  • Github:https://github.com/idevz/vanilla

  • GitOSC:http://git.oschina.net/idevz/vanilla


如果vanilla.v.routes.restful和vanilla.v.routes.simple(默认为simple如果需要使用restful路由协议,则需要在bootstrap中打开Bootstrap:initRoute())不能满足你的需求,你想在自己的项目中DIY自己的路由协议,请继续往下:


如何给Vanilla(OpenResty)添加一个路由协议?

先看例子,再学原理(例子:给APP添加一个跟功能与simple_route一样的路由协议routes.idevz)

实现步骤

  • 在项目中添加application/library/routes/idevz.lua

  • 定义一个表,包含route_name属性,并实现__tostring元方法(路由器基于此管理路由协议栈)

  • idevz.lua中实现match方法(功能:根据当前请求URI返回对应的controlleraction


关键两点

  • route_name属性,并实现__tostring元方法

  • match方法

相关代码实现如下:


❲Vanilla技巧❳Vanilla(OpenResty)实现的Restful

-- perf

local error = error

local ngxmatch=ngx.re.gmatch


-- init iDevz and set routes

local iDevz = {}


function iDevz:new(request)

local instance = {

route_name = 'routes.idevz',

request = request

}


setmetatable(instance, {

__index = self,

__tostring = function(self) return self.route_name end

})

return instance

end


function iDevz:match()

local uri = self.request.uri

if uri == '/' then

return 'index', 'index'

end

--在此实现URI路由逻辑,并返回contrllor_name, action_name

return contrllor_name, action_name

end


return iDevz


原理

Vanilla运行在OpenResty的content Phase,由content_by_lua_file驱动,当用户请求过来时会初始化当前APP请求实例,并做相关配置解析、视图引擎配置、插件装载、路由设置等初始化工作,紧接着就是请求路由分发、处理... 也就是run的指令一下就开始进入请求路由。


Vanilla实现了一个路由器vanilla.v.router(注意这里是router,是er路由器,区别于后面的路由协议route)和由这个路由协器管理的一个路由协议栈(self.routes),这个栈管理着一序列路由协议,默认使用vanilla.v.routes.simple,Vanilla通过遍历这个路由协议栈里面各个route的match方法来完成请求的路由。这个match方法只做一件事“根据当前请求的URI告诉每个请求该去哪个controller和哪个action”。

❲Vanilla技巧❳Vanilla(OpenResty)实现的Restful

下面是router目前提供的相关方法:

❲Vanilla技巧❳Vanilla(OpenResty)实现的Restful

function Router:new(request) --传入request实例初始化路由器,默认已经启用:vanilla.v.routes.simple

function Router:addRoute(route, only_one) --添加路由协议

function Router:removeRoute(route_name) --传入路由协议名称删除路由协议

function Router:getRoutes() --获取当前的路由协议栈

function Router:getCurrentRoute() --获取当前请求所使用的路由协议实例

function Router:getCurrentRouteName() --获取当前请求所使用的路由协议名称

function Router:route() --路由当前请求


所以给Vanilla(OpenResty)添加一个路由协议的关键就在于实现这个match方法欢迎大家各自按需DIY


bootstrap中使用实例

function Bootstrap:initRoute()

local router = self.dispatcher:getRouter()

local simple_route = require('vanilla.v.routes.simple'):new(self.dispatcher:getRequest())

local restful_route = require('vanilla.v.routes.restful'):new(self.dispatcher:getRequest())

local idevz_route = require('routes.idevz'):new(self.dispatcher:getRequest())

router:addRoute(restful_route, true)

router:addRoute(idevz_route, true)

router:addRoute(simple_route)

router:removeRoute('vanilla.v.routes.restful')

router:removeRoute('vanilla.v.routes.simple')


-- print_r(router:getRoutes())

end


感谢

Vanilla开源以来的很长一段时间里一直只支持一种单一的简单路由协议simple_route,这让很多朋友意犹未尽,甚至批评Vanilla不是框架,而是骨架:),首先感谢各位群友、Vanilla用户...感谢大家对Vanilla的支持与关注,我想象中的Vanilla是一个保持很好的扩展性、易用性,让OpenResty开发更简单方便,性能强劲的同时又不失优雅小巧的OpenResty开发框架,虽然现在的vanilla-0.1.0.rc4离这个目标还有一段距离,但至少方向是这样的。Vanilla是已知的第一款国产OpenResty MVC Web框架,所以它离你更近:)。感谢持续关注,我们在努力完善中。




以上是关于❲Vanilla技巧❳Vanilla(OpenResty)实现的Restful的主要内容,如果未能解决你的问题,请参考以下文章

Openresty+YII2.0下开发RestfulAPI系列4:vanilla香草框架简介

nginx 无法访问 Vanilla 论坛 sitemapindex.xml 文件

ClearDb + Azure:Vanilla 论坛安装真的很慢

css Vanilla CSS来自http://www.cssreset.com/scripts/vanilla-css-un-reset/,在CSS重置后使用,为所有人定义“默认”样式。

nodejs/vanilla 中的 Apollo-client 未触发订阅

javascript AJAX与Vanilla JS