摘要:處理函數(shù)的返回值用于渲染輸出。例如,如果不滿足某些條件,我們可以取消操作并重定向到另一個(gè)頁(yè)面是處理一個(gè)常規(guī)動(dòng)作的返回值,所以同樣的事情你可以返回一個(gè)動(dòng)作,可以傳遞給請(qǐng)求對(duì)象每個(gè)操作在調(diào)用時(shí)會(huì)請(qǐng)求對(duì)象作為其第一個(gè)參數(shù)傳遞。
lapis請(qǐng)求處理
每個(gè)被Lapis處理的HTTP請(qǐng)求在被Nginx處理后都遵循相同的基本流程。第一步是路由。路由是 url 必須匹配的模式。當(dāng)你定義一個(gè)路由時(shí),你也得包括一個(gè)處理函數(shù)。這個(gè)處理函數(shù)是一個(gè)常規(guī)的Lua/MoonScript函數(shù),如果相關(guān)聯(lián)的路由匹配,則將調(diào)用該函數(shù)。
所有被調(diào)用的處理函數(shù)都具有一個(gè)參數(shù)(一個(gè)請(qǐng)求對(duì)象)。請(qǐng)求對(duì)象將存儲(chǔ)您希望在處理函數(shù)和視圖之間共享的所有數(shù)據(jù)。此外,請(qǐng)求對(duì)象是您向Web服務(wù)器了解如何將結(jié)果發(fā)送到客戶端的接口。
處理函數(shù)的返回值用于渲染輸出。字符串返回值將直接呈現(xiàn)給瀏覽器。table 的返回值將用作[渲染選項(xiàng)]()。如果有多個(gè)返回值,則所有這些返回值都合并到最終結(jié)果中。您可以返回字符串和table以控制輸出。
如果沒(méi)有匹配請(qǐng)求的路由,則執(zhí)行默認(rèn)路由處理程序,在[application callbacks]()了解更多。
Routes 和 URL 模式路由模式 使用特殊語(yǔ)法來(lái)定義URL的動(dòng)態(tài)參數(shù) 并為其分配一個(gè)名字。最簡(jiǎn)單的路由沒(méi)有參數(shù):
local lapis = require("lapis") local app = lapis.Application() app:match("/", function(self) end) app:match("/hello", function(self) end) app:match("/users/all", function(self) end)
這些路由與URL逐字匹配。 / 路由是必需的。路由必須匹配請(qǐng)求的整個(gè)路徑。這意味著對(duì) /hello/world 的請(qǐng)求將不匹配 /hello。
您可以在:后面理解跟上一個(gè)名稱來(lái)指定一個(gè)命名參數(shù)。該參數(shù)將匹配除/的所有字符(在一般情況下):
app:match("/page/:page", function(self) print(self.params.page) end) app:match("/post/:post_id/:post_name", function(self) end)
在上面的例子中,我們調(diào)用 print 函數(shù)來(lái)調(diào)試,當(dāng)在openresty中運(yùn)行時(shí),print的輸出是被發(fā)送到nginx的notice級(jí)別的日志中去的
捕獲的路由參數(shù)的值按其名稱保存在請(qǐng)求對(duì)象的 params 字段中。命名參數(shù)必須至少包含1個(gè)字符,否則將無(wú)法匹配。
splat是另一種類型的模式,將盡可能匹配,包括任何/字符。 splat存儲(chǔ)在請(qǐng)求對(duì)象的 params 表中的 splat 命名參數(shù)中。它只是一個(gè)單一 *
app:match("/browse/*", function(self) print(self.params.splat) end) app:match("/user/:name/file/*", function(self) print(self.params.name, self.params.splat) end)
如果將任何文本直接放在splat或命名參數(shù)之后,它將不會(huì)包含在命名參數(shù)中。例如,您可以將以.zip結(jié)尾的網(wǎng)址與/files/:filename.zip進(jìn)行匹配(那么.zip就不會(huì)包含在命名參數(shù) filename 中)
可選路由組件圓括號(hào)可用于使路由的一部分可選:
/projects/:username(/:project)
以上將匹配 /projects/leafo 或 /projects/leafo/lapis 。可選組件中不匹配的任何參數(shù)在處理函數(shù)中的值將為nil。
這些可選組件可以根據(jù)需要嵌套和鏈接:
/settings(/:username(/:page))(.:format)參數(shù)字符類
字符類可以應(yīng)用于命名參數(shù),以限制可以匹配的字符。語(yǔ)法建模在 Lua 的模式字符類之后。此路由將確保該 user_id 命名參數(shù)只包含數(shù)字:
/color/:hex[a-fA-F%d]
這個(gè)路由只匹配十六進(jìn)制參數(shù)的十六進(jìn)制字符串。
/color/:hex[a-fA-F%d]路由優(yōu)先級(jí)
首先按優(yōu)先順序搜索路由,然后按它們定義的順序搜索。從最高到最低的路由優(yōu)先級(jí)為:
精確匹配的路由 /hello/world 變化參數(shù)的路由 /hello/:variable 貪婪匹配的路由 /hello/*命名路由
為您的路由命名是有用的,所以只要知道網(wǎng)頁(yè)的名稱就可以生成到其他網(wǎng)頁(yè)的鏈接,而不是硬編碼 URL 的結(jié)構(gòu)。
應(yīng)用程序上定義新路由的每個(gè)方法都有第二個(gè)形式,它將路由的名稱作為第一個(gè)參數(shù):
local lapis = require("lapis") local app = lapis.Application() app:match("index", "/", function(self) return self:url_for("user_profile", { name = "leaf" }) end) app:match("user_profile", "/user/:name", function(self) return "Hello " .. self.params.name .. ", go home: " .. self:url_for("index") end)
我們可以使用self:url_for()生成各種操作的路徑。第一個(gè)參數(shù)是要調(diào)用的路由的名稱,第二個(gè)可選參數(shù)是用于填充 參數(shù)化路由 的值的表。
點(diǎn)擊[url_for]() 去查看不同方式去生成 URL 的方法。
處理HTTP動(dòng)詞根據(jù)請(qǐng)求的 HTTP 動(dòng)詞,進(jìn)行不同的處理操作是很常見(jiàn)的。 Lapis 有一些小幫手,讓寫(xiě)這些處理操作很簡(jiǎn)單。 respond_to 接收由 HTTP 動(dòng)詞索引的表,當(dāng)匹配對(duì)應(yīng)的動(dòng)詞執(zhí)行相應(yīng)的函數(shù)處理
local lapis = require("lapis") local respond_to = require("lapis.application").respond_to local app = lapis.Application() app:match("create_account", "/create-account", respond_to({ GET = function(self) return { render = true } end, POST = function(self) do_something(self.params) return { redirect_to = self:url_for("index") } end }))
respond_to 也可以采用自己的 before 過(guò)濾器,它將在相應(yīng)的 HTTP 動(dòng)詞操作之前運(yùn)行。我們通過(guò)指定一個(gè) before 函數(shù)來(lái)做到這一點(diǎn)。與過(guò)濾器相同的語(yǔ)義適用,所以如果你調(diào)用 self:write(),那么其余的動(dòng)作將不會(huì)運(yùn)行.
local lapis = require("lapis") local respond_to = require("lapis.application").respond_to local app = lapis.Application() app:match("edit_user", "/edit-user/:id", respond_to({ before = function(self) self.user = Users:find(self.params.id) if not self.user then self:write({"Not Found", status = 404}) end end, GET = function(self) return "Edit account " .. self.user.name end, POST = function(self) self.user:update(self.params.user) return { redirect_to = self:url_for("index") } end }))
在任何 POST 請(qǐng)求,無(wú)論是否使用 respond_to,如果 Content-type 頭設(shè)置為 application/x-www-form-urlencoded,那么請(qǐng)求的主體將被解析,所有參數(shù)將被放入 self.params。
您可能還看到了 app:get() 和 app:post() 方法在前面的示例中被調(diào)用。這些都是封裝了 respond_to 方法,可讓您快速為特定 HTTP 動(dòng)詞定義操作。你會(huì)發(fā)現(xiàn)這些包裝器最常見(jiàn)的動(dòng)詞:get,post,delete,put。對(duì)于任何其他動(dòng)詞,你需要使用respond_to。
app:get("/test", function(self) return "I only render for GET requests" end) app:delete("/delete-account", function(self) -- do something destructive end)Before Filters
有時(shí)你想要一段代碼在每個(gè)操作之前運(yùn)行。一個(gè)很好的例子是設(shè)置用戶會(huì)話。我們可以聲明一個(gè) before 過(guò)濾器,或者一個(gè)在每個(gè)操作之前運(yùn)行的函數(shù),像這樣:
local app = lapis.Application() app:before_filter(function(self) if self.session.user then self.current_user = load_user(self.session.user) end end) app:match("/", function(self) return "current user is: " .. tostring(self.current_user) end)
你可以通過(guò)多次調(diào)用 app:before_filter 來(lái)隨意添加。它們將按照注冊(cè)的順序運(yùn)行。
如果一個(gè) before_filter 調(diào)用 self:write()方法,那么操作將被取消。例如,如果不滿足某些條件,我們可以取消操作并重定向到另一個(gè)頁(yè)面:
local app = lapis.Application() app:before_filter(function(self) if not user_meets_requirements() then self:write({redirect_to = self:url_for("login")}) end end) app:match("login", "/login", function(self) -- ... end)
self:write() 是處理一個(gè)常規(guī)動(dòng)作的返回值,所以同樣的事情你可以返回一個(gè)動(dòng)作,可以傳遞給 self:write()
請(qǐng)求對(duì)象每個(gè)操作在調(diào)用時(shí)會(huì)請(qǐng)求對(duì)象作為其第一個(gè)參數(shù)傳遞。由于調(diào)用第一個(gè)參數(shù) self 的約定,我們?cè)谝粋€(gè)操作的上下文中將請(qǐng)求對(duì)象稱為 self。
請(qǐng)求對(duì)象具有以下參數(shù):
self.params 一個(gè)包含所有GET,POST 和 URL 參數(shù)的表
self.req 原始請(qǐng)求表(從ngx狀態(tài)生成)
self.res 原始響應(yīng)表(從ngx狀態(tài)生成)
self.app 應(yīng)用程序的實(shí)例
self.cookies cookie 表,可以分配設(shè)置新的cookie。 只支持字符串作為值
self.session session表, 可以存儲(chǔ)任何能夠 被JSON encode 的值。 由Cookie支持
self.route_name 匹配請(qǐng)求的路由的名稱(如果有)
self.options 控制請(qǐng)求如何呈現(xiàn)的選項(xiàng)集,通過(guò)write設(shè)置
self.buffer 輸出緩沖區(qū),通常你不需要手動(dòng)設(shè)置,通過(guò)write設(shè)置
此外,請(qǐng)求對(duì)象具有以下方法:
write(options, ...) 指示請(qǐng)求如何呈現(xiàn)結(jié)果
url_for(route, params, ...) 根據(jù)命名路由或?qū)ο髞?lái)獲取 URL
build_url(path, params) 根據(jù) path 和 params 構(gòu)建一個(gè)完整的URL
html(fn) 使用HTML構(gòu)建語(yǔ)法生成字符串
@req原始請(qǐng)求表 self.req 封裝了 ngx 提供的一些數(shù)據(jù)。 以下是可用屬性的列表。
self.req.headers 請(qǐng)求頭的表
self.req.parsed_url 解析請(qǐng)求的url,這是一個(gè)包含scheme, path, host, port 和 query 屬性的表
self.req.params_post POST請(qǐng)求的參數(shù)表
self.req.params_get GET請(qǐng)求的參數(shù)表
Cookies請(qǐng)求中的 self.cookies 表允許您讀取和寫(xiě)入Cookie。 如果您嘗試遍歷表以打印 Cookie,您可能會(huì)注意到它是空的:
app:match("/my-cookies", function(self) for k,v in pairs(self.cookies) do print(k, v) end end)
現(xiàn)有的 Cookie 存儲(chǔ)在元表的 __index 中。 之這樣做,是因?yàn)槲覀兛梢灾涝诓僮髌陂g分配了哪些 Cookie,因?yàn)樗鼈儗⒅苯釉?self.cookies 表中。
因此,要設(shè)置一個(gè) cookie,我們只需要分配到 self.cookies 表:
app:match("/sets-cookie", function(self) self.cookies.foo = "bar" end)
默認(rèn)情況下,所有 Cookie 都有額外的屬性 Path = /; HttpOnly (創(chuàng)建一個(gè)session cookie )。 您可以通過(guò)重寫(xiě) app.cookie_attributes 函數(shù)來(lái)配置 cookie 的設(shè)置。 以下是一個(gè)向 cookies 添加過(guò)期時(shí)間以使其持久化的示例:
local date = require("date") local app = lapis.Application() app.cookie_attributes = function(self) local expires = date(true):affffdays(365):fmt("${http}") return "Expires=" .. expires .. "; Path=/; HttpOnly" end
cookie_attributes 方法將請(qǐng)求對(duì)象作為第一個(gè)參數(shù)(self),然后是要處理的 cookie 的名稱和值。
Sessionself.session 是一種更先進(jìn)的方法,通過(guò)請(qǐng)求來(lái)持久化數(shù)據(jù)。 會(huì)話的內(nèi)容被序列化為 JSON 并存儲(chǔ)在特定名稱的 cookie 中。 序列化的 Cookie 使用您的應(yīng)用程序密鑰簽名,因此不會(huì)被篡改。 因?yàn)樗怯?JSON 序列化的,你可以存儲(chǔ)嵌套表和其他原始值。
session 可以像 Cookie 一樣設(shè)置和讀取:
app.match("/", function(self) if not self.session.current_user then self.session.current_user = "Adam" end end)
默認(rèn)情況下,session 存儲(chǔ)在名為 lapis_session 的 cookie 中。 您可以使用配置變量session_name 覆蓋 session 的名稱。 session 使用您的應(yīng)用程序密鑰(存儲(chǔ)在配置的secret 中)進(jìn)行簽名。 強(qiáng)烈建議更改它的默認(rèn)值。
-- config.lua local config = require("lapis.config").config config("development", { session_name = "my_app_session", secret = "this is my secret string 123456" })請(qǐng)求對(duì)象的方法 write(things...)
一下列出它的所有參數(shù)。 根據(jù)每個(gè)參數(shù)的類型執(zhí)行不同的操作。
string 字符串追加到輸出緩沖區(qū)
function (或者是可調(diào)用表) 函數(shù)被輸出緩沖區(qū)調(diào)用,結(jié)果遞歸傳遞給write
table 鍵/值對(duì)將會(huì)被分配到 self.options中 ,所有其他值遞歸傳遞給write
在大多數(shù)情況下,沒(méi)有必要調(diào)用 write ,因?yàn)樘幚砗瘮?shù)的返回值會(huì)自動(dòng)傳遞給 write 。 在before filter中 ,write具有寫(xiě)入輸出和取消任何進(jìn)一步操作的雙重目的。
url_for(name_or_obj, params, query_params=nil, ...)依據(jù) 路由的name或一個(gè)對(duì)象生成 url
url_for 有點(diǎn)用詞不當(dāng),因?yàn)樗ǔI傻秸?qǐng)求的頁(yè)面的路徑。 如果你想得到整個(gè) URL,你可以與build_url函數(shù)和一起使用。
如果 name_or_obj 是一個(gè)字符串,那么使用 params中的值來(lái)查找和填充該名稱的路由。 如果路由不存在,則拋出錯(cuò)誤。
給定以下路由:
app:match("index", "/", function() -- ... end) app:match("user_data", "/data/:user_id/:data_field", function() -- ... end)
到頁(yè)面的 URL 可以這樣生成:
-- returns: / self:url_for("index") -- returns: /data/123/height self:url_for("user_data", { user_id = 123, data_field = "height"})
如果提供了第三個(gè)參數(shù) query_params ,它將被轉(zhuǎn)換為查詢參數(shù)并附加到生成的 URL 的末尾。 如果路由不接受任何參數(shù),則第二個(gè)參數(shù)必須被設(shè)置為 nil 或 空對(duì)象 :
-- returns: /data/123/height?sort=asc self:url_for("user_data", { user_id = 123, data_field = "height"}, { sort = "asc" }) -- returns: /?layout=new self:url_for("index", nil, {layout = "new"})
如果提供了所有封閉的參數(shù),則只包括路由的任何可選組件。 如果 optinal 組件沒(méi)有任何參數(shù),那么它將永遠(yuǎn)不會(huì)被包括。
給定以下路由:
app:match("user_page", "/user/:username(/:page)(.:format)", function(self) -- ... end)
可以生成以下 URL:
-- returns: /user/leafo self:url_for("user_page", { username = "leafo" }) -- returns: /user/leafo/projects self:url_for("user_page", { username = "leafo", page = "projects" }) -- returns: /user/leafo.json self:url_for("user_page", { username = "leafo", format = "json" }) -- returns: /user/leafo/code.json self:url_for("user_page", { username = "leafo", page = "code", format = "json" })
如果路由包含了 splat,則可以通過(guò)名為 splat 的參數(shù)提供該值:
app:match("browse", "/browse(/*)", function(self) -- ... end)
-- returns: /browse self:url_for("browse") -- returns: /browse/games/recent self:url_for("browse", { splat = "games/recent" })將對(duì)象傳遞給 url_for
如果 name_or_obj 是一個(gè) table ,那么在該 table 上調(diào)用 此table的url_params 方法,并將返回值傳遞給 url_for 。
url_params 方法接受請(qǐng)求對(duì)象作為參數(shù),其次是任何傳遞給 url_for 的東西。
通常在 model 上實(shí)現(xiàn) url_params,讓他們能夠定義它們代表的頁(yè)面。 例如,為User model定義了一個(gè) url_params 方法,該方法轉(zhuǎn)到用戶的配置文件頁(yè)面:
local Users = Model:extend("users", { url_params = function(self, req, ...) return "user_profile", { id = self.id }, ... end })
我們現(xiàn)在可以將User實(shí)例直接傳遞給 url_for,并返回 user_profile 路徑的l路由:
local user = Users:find(100) self:url_for(user) -- could return: /user-profile/100
你可能會(huì)注意到我們將 ... 傳遞給 url_params方法返回值。 這允許第三個(gè) query_params 參數(shù)仍然起作用:
local user = Users:find(1) self:url_for(user, { page = "likes" }) -- could return: /user-profile/100?page=likes使用 url_key 方法
如果 params 中參數(shù)的值是一個(gè)字符串,那么它會(huì)被直接插入到生成的路徑中。 如果它的值是一個(gè) table,那么將在此 table 上面調(diào)用url_key 方法,并將此方法的返回值插入到路徑中。
例如,我們?yōu)?User 模型定義一個(gè)我們的 url_key 方法:
local Users = Model:extend("users", { url_key = function(self, route_name) return self.id end })
如果我們想生成一個(gè)user_profile文件的路徑,我們通??梢赃@樣寫(xiě):
local user = Users:find(1) self:url_for("user_profile", {id = user.id})
我們定義的 url_key 方法讓我們直接傳遞 User 對(duì)象作為 id 參數(shù),它將被轉(zhuǎn)換為 id :
local user = Users:find(1) self:url_for("user_profile", {id = user})
url_key 方法將路由的名稱作為第一個(gè)參數(shù),因此我們可以根據(jù)正在處理的路由更改我們返回的內(nèi)容。
build_url(path,[options])依據(jù) path 構(gòu)建一個(gè)絕對(duì) URL 。 當(dāng)前請(qǐng)求的URIb被用于構(gòu)建URL。
例如,如果我們?cè)?localhost:8080 上運(yùn)行我們的服務(wù)器:
self:build_url() --> http://localhost:8080 self:build_url("hello") --> http://localhost:8080/hello渲染選項(xiàng)
每當(dāng)寫(xiě)一個(gè)表時(shí),鍵/值對(duì)(對(duì)于是字符串的鍵)被復(fù)制到 self.options。 例如,在以下操作中,將復(fù)制render和 status 屬性。 在請(qǐng)求處理的生命周期結(jié)束時(shí)使用options表來(lái)創(chuàng)建適當(dāng)?shù)捻憫?yīng)。
app:match("/", function(self) return { render = "error", status = 404} end)
以下是可以寫(xiě)入的 options的字段列表
status 設(shè)置 http 狀態(tài)碼 (eg. 200,404,500)
render 導(dǎo)致一個(gè)視圖被請(qǐng)求渲染。 如果值為 true,則使用路由的名稱作為視圖名稱。 否則,該值必須是字符串或視圖類。
content_type 設(shè)置Content-type頭
header 要添加到響應(yīng)的響應(yīng)頭
json 導(dǎo)致此請(qǐng)求返回 JSON encode的值。 content-type被設(shè)置為 application / json 。
layout 更改app默認(rèn)定義layout
redirect_to 將狀態(tài)碼設(shè)置為 302,并設(shè)置Location頭。 支持相對(duì)和絕對(duì)URL。 (結(jié)合status執(zhí)行 301 重定向)
當(dāng)渲染 JSON 時(shí),確保使用 json 渲染選項(xiàng)。 它將自動(dòng)設(shè)置正確的content-type并禁用 layout:
app:match("/hello", function(self) return { json = { hello = "world" } } end)應(yīng)用程序回調(diào)
應(yīng)用程序回調(diào)是一種特殊方法,它可以在需要處理某些類型的請(qǐng)求時(shí)調(diào)用。可以被應(yīng)用程序覆蓋, 雖然它們是存儲(chǔ)在應(yīng)用程序上的函數(shù),但它們被稱為是常規(guī)操作,這意味著函數(shù)的第一個(gè)參數(shù)是請(qǐng)求對(duì)象的實(shí)例。
默認(rèn)操作當(dāng)請(qǐng)求與您定義的任何路由不匹配時(shí),它將運(yùn)行默認(rèn)處理函數(shù)。 Lapis附帶了一個(gè)默認(rèn)操作,預(yù)定義如下:
app.default_route = function(self) -- strip trailing / if self.req.parsed_url.path:match("./$") then local stripped = self.req.parsed_url:match("^(.+)/+$") return { redirect_to = self:build_url(stripped, { status = 301, query = self.req.parsed_url.query, }) } else self.app.handle_404(self) end end
如果它注意到URL尾部跟隨 一個(gè)/,它將嘗試重定向到尾部沒(méi)有/的版本。 否則它將調(diào)用app上的handle_404方法。
這個(gè)方法default_route只是 app 的一個(gè)普通方法。 你可以覆蓋它來(lái)做任何你喜歡的。 例如,添加個(gè)日志記錄:
app.default_route = function(self) ngx.log(ngx.NOTICE, "User hit unknown path " .. self.req.parsed_url.path) -- call the original implementaiton to preserve the functionality it provides return lapis.Application.default_route(self) end
你會(huì)注意到在default_route的預(yù)定義版本中,另一個(gè)方法handle_404被引用。 這也是預(yù)定義的,如下所示:
app.handle_404 = function(self) error("Failed to find route: " .. self.req.cmd_url) end
這將在每個(gè)無(wú)效請(qǐng)求上觸發(fā) 500 錯(cuò)誤和 stack trance。 如果你想做一個(gè) 404 頁(yè)面,這b便是你能實(shí)現(xiàn)的地方。
覆蓋handle_404方法而不是default_route允許我們創(chuàng)建一個(gè)自定義的404頁(yè)面,同時(shí)仍然保留上面的尾部/刪除代碼。
這里有一個(gè)簡(jiǎn)單的404處理程序,只打印文本Not Found!
app.handle_404 = function(self) return { status = 404, layout = false, "Not Found!" } end錯(cuò)誤處理
Lapis 執(zhí)行的每個(gè)處理函數(shù)都被 xpcall 包裝。 這確保可以捕獲到致命錯(cuò)誤,并且可以生成有意義的錯(cuò)誤頁(yè)面,而不是 Nginx默認(rèn)錯(cuò)誤信息。
錯(cuò)誤處理程序應(yīng)該僅用于捕獲致命和意外錯(cuò)誤,預(yù)期錯(cuò)誤在[異常處理指南]()中討論
Lapis 自帶一個(gè)預(yù)定義的錯(cuò)誤處理程序,提取錯(cuò)誤信息并渲染模板 lapis.views.error。 此錯(cuò)誤頁(yè)面包含報(bào)錯(cuò)的堆棧和錯(cuò)誤消息。
如果你想有自己的錯(cuò)誤處理邏輯,你可以重寫(xiě)方法handle_error:
-- config.custom_error_page is made up for this example app.handle_error = function(self, err, trace) if config.custom_error_page then return { render = "my_custom_error_page" } else return lapis.Application.handle_error(self, err, trace) end end
傳遞給錯(cuò)誤處理程序的請(qǐng)求對(duì)象或 self 不是失敗了的請(qǐng)求創(chuàng)建的請(qǐng)求對(duì)象。 Lapis 提供了一個(gè)新的,因?yàn)橹暗目赡芤呀?jīng)寫(xiě)入失敗了。
您可以使用self.original_request訪問(wèn)原始請(qǐng)求對(duì)象
Lapis 的默認(rèn)錯(cuò)誤頁(yè)面顯示整個(gè)錯(cuò)誤堆棧,因此在生產(chǎn)環(huán)境中建議將其替換自定義堆棧跟蹤,并在后臺(tái)記錄異常。
lapis-exceptions 模塊增加了錯(cuò)誤處理程序以在數(shù)據(jù)庫(kù)中記錄錯(cuò)誤。 它也可以當(dāng)有異常時(shí)向您發(fā)送電子郵件。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/39495.html
摘要:入門(mén)是為和編寫(xiě)的框架。使用來(lái)安裝創(chuàng)建一個(gè)應(yīng)用命令行工具附帶了一個(gè)命令行工具,可幫助您創(chuàng)建新項(xiàng)目和啟動(dòng)服務(wù)器。在生產(chǎn)環(huán)境中,應(yīng)當(dāng)啟用緩存以獲得最佳性能。指令指定一個(gè)代碼塊,它將處理與其他不匹配的任何請(qǐng)求。將忽略常規(guī)的二進(jìn)制文件。 lapis入門(mén) Lapis 是為 Lua 和 MoonScript 編寫(xiě)的 Web 框架。 Lapis 很有趣,因?yàn)樗⒃贜ginx 發(fā)行的 OpenRest...
摘要:配置及環(huán)境被設(shè)計(jì)于依據(jù)不同環(huán)境載入不同的配置來(lái)運(yùn)行服務(wù)器。環(huán)境名稱僅影響加載的配置。例如,這里有一個(gè)的配置塊編譯時(shí),首先檢查環(huán)境變量。默認(rèn)日志記錄位置設(shè)置為,在默認(rèn)的配置中指定。 配置及環(huán)境 Lapis 被設(shè)計(jì)于依據(jù)不同環(huán)境載入不同的配置來(lái)運(yùn)行服務(wù)器。例如,可能您開(kāi)發(fā)環(huán)境的配置設(shè)置為本地?cái)?shù)據(jù)庫(kù)的URL,禁用代碼緩存和單個(gè)worker。然后,您生產(chǎn)環(huán)境的配置可能設(shè)定為遠(yuǎn)程數(shù)據(jù)庫(kù)的 URL...
摘要:使用創(chuàng)建應(yīng)用程序生成一個(gè)新項(xiàng)目如果您尚未閱讀,請(qǐng)閱讀入門(mén)指南,了解有關(guān)創(chuàng)建新項(xiàng)目骨架的信息以及,配置和命令的詳細(xì)信息。是包含應(yīng)用程序的常規(guī)模塊。 使用Lua創(chuàng)建Lapis應(yīng)用程序 生成一個(gè)新項(xiàng)目 如果您尚未閱讀,請(qǐng)閱讀入門(mén)指南,了解有關(guān)創(chuàng)建新項(xiàng)目骨架的信息以及OpenResty,Nginx配置和lapis命令的詳細(xì)信息。 您可以在當(dāng)前目錄中通過(guò)運(yùn)行以下命令啟動(dòng)一個(gè)新的Lua項(xiàng)目: la...
摘要:的異常處理錯(cuò)誤的種類區(qū)分兩種錯(cuò)誤可恢復(fù)和不可恢復(fù)錯(cuò)誤。捕獲可恢復(fù)的錯(cuò)誤幫助程序用于包裝一個(gè)操作,以便它可以捕獲錯(cuò)誤并運(yùn)行錯(cuò)誤處理程序。相反,使用協(xié)同程序創(chuàng)建一個(gè)異常處理系統(tǒng)。 lapis的異常處理 錯(cuò)誤的種類 Lapis 區(qū)分兩種錯(cuò)誤:可恢復(fù)和不可恢復(fù)錯(cuò)誤。 Lua 的運(yùn)行時(shí)在執(zhí)行期間拋出的錯(cuò)誤或調(diào)用錯(cuò)誤被認(rèn)為是不可恢復(fù)的。 (這也包括 Lua 內(nèi)置函數(shù) assert ) 因?yàn)椴豢苫謴?fù)...
摘要:配置語(yǔ)法配置示例的配置模塊提供了對(duì)遞歸合并的支持。例如,我們可以定義一個(gè)基本配置,然后覆蓋更多具體的配置聲明中的一些值這將產(chǎn)生以下兩個(gè)配置結(jié)果默認(rèn)值省略您可以在相同的配置名稱上調(diào)用函數(shù)多次,每次將傳入的表合并到配置中。 Lua 配置語(yǔ)法 配置示例 Lapis 的配置模塊提供了對(duì)遞歸合并 table 的支持。 例如,我們可以定義一個(gè)基本配置,然后覆蓋更多具體的配置聲明中的一些值: --...
閱讀 2039·2023-04-26 00:16
閱讀 3487·2021-11-15 11:38
閱讀 3181·2019-08-30 12:50
閱讀 3191·2019-08-29 13:59
閱讀 762·2019-08-29 13:54
閱讀 2512·2019-08-29 13:42
閱讀 3315·2019-08-26 11:45
閱讀 2196·2019-08-26 11:36