openresty front-end development lightweight MVC framework package one (controller)

#### Through the previous chapters, we have mastered some basic development knowledge, but the code structure is relatively simple, lacking unified standards, modularization, and unified exception handling. In this chapter, we mainly learn how to encapsulate a A lightweight MVC framework that standardizes and simplifies development, and provides capabilities similar to php WYSIWYG

## Unified entry

Generally speaking, an MVC framework will have a unified entry point, similar to Spring MVC's DispatcherServlet, which will intercept all request, which is /, so we can derive our entry point

conf/nginx.conf
```
worker_processes 1;

error_log logs/error.log notice;

events {
    worker_connections 1024;
}

http {
    lua_package_path "/Users/john/ opensource/openresty-web-dev/demo8/lua/?.lua;/Users/john/opensource/openresty-web-dev/demo8/lualib/?.lua;/usr/local/openresty/lualib/?.lua" ;
    server {
        listen 80;
        server_name localhost;
        lua_code_cache off;

        location / {
        content_by_lua_file lua/mvc.lua;
        }

        location ~ ^/js/|^/css/|\.html {
        root html;
        }
    }
}
```

Except static files js/css/html files, other requests will be processed by our mvc.lua handles.

## Default page

When the request uri is empty, the index.html page will be returned by default. Of course, you can define it yourself. It is very simple to achieve this

effect.```
local uri = ngx.var.uri
-- default home page
if uri == "" or uri == "/" then
    local res = ngx.location.capture("/index.html", {})
    ngx.say(res.body)
    return
end
```

## url parsing

Here is a simple parsing of the url A module method into a module name, divided according to /, if there is only a module name and no method name, the default is the index method

```
local m, err = ngx.re.match(uri, "([a-zA-Z0-9-]+)/*([a-zA-Z0-9-]+)*")

local moduleName = m[ 1] -- module name
local method = m[2] -- method name

if not method then
    method = "index" -- default access to index method
else
    method = ngx.re.gsub(method, "-", "_" )   
end
```

## Dynamic Controller module After

getting the module name, you need to dynamically import the module, pass pcall, and then call the module's method

```
-- the controller is under the web package by default
local prefix = "web."      
local path = prefix .. moduleName

-- try to import the module, if it does not exist, an error will be reported
local ret, ctrl, err = pcall(require, path)

local is_debug = true -- in the debugging phase, the error message will be output to the page

if ret == false then
    if is_debug then
        ngx.status = 404
        ngx.say("")
    end
    ngx.exit(404)
end

-- try to get the module method, if it does not exist, an error will be reported
local req_method = ctrl[method]

if req_method == nil then
    if is_debug then
        ngx.status = 404
        ngx.say("<p style='font-size: 50px'>Error: <span style='color:red'>" .. method .. "()</span> method not found in <span style='color:red'>" .. moduleName .. "</span> lua module !")
    end
    ngx.exit(404)
end

-- execute the module method, if an error is reported, an error message will be displayed, what you see is what you get, you can Track the number of error lines reported by lua
ret, err = pcall(req_method)

if ret == false then
    if is_debug then
        ngx.status = 404
        ngx.say("")
    else
        ngx.exit(500)
    end
end
````

## Exception handling

It can be seen that from the introduction of the module, to the acquisition of the module method, and the executed method, there may be errors. Here, the call is made through pcall, which is safe Calling the lua code will not cause abnormal interruption, and then define a variable to distinguish whether it is in the development and debugging stage, if so, output the error message to the browser, otherwise report 404 or 500 directly to avoid outputting the error message to the client, resulting in code leaks.

So far, a simple mvc framework can be used, but it can only do front-end rendering. In the next chapter, I will introduce how to do server-side rendering.

[Sample code](https://github.com/362228416/openresty-web-dev) See demo8 section

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326992677&siteId=291194637