Kong Gateway processes requests in phases. A plugin is a piece of code that gets
activated by Kong Gateway as each phase is executed while the request gets proxied.
Phases are limited in what they can do. For example, the init_worker
phase
doesn’t have access to the config
parameter because that information isn’t
available when Kong Gateway is initializing each worker. On the other hand the configure
function
is passed with all the active configurations for the plugin (or nil
if not configured).
A plugin’s handler.lua
must return a table containing the functions it must
execute on each phase.
Kong Gateway can process HTTP and stream traffic. Some phases are executed
only when processing HTTP traffic, others when processing stream,
and some (like init_worker
and log
) are invoked by both kinds of traffic.
In addition to functions, a plugin must define two fields:
-
VERSION
is an informative field, not used by Kong Gateway directly. It usually
matches the version defined in a plugin’s Rockspec version, when it exists.
-
PRIORITY
is used to sort plugins before executing each of their phases.
Plugins with a higher priority are executed first. See the
plugin execution order section
for more info about this field.
The following example handler.lua
file defines custom functions for all
the possible phases, in both http and stream traffic. It has no functionality
besides writing a message to the log every time a phase is invoked.
A plugin doesn’t need to provide functions for all phases.
local CustomHandler = {
VERSION = "1.0.0",
PRIORITY = 10,
}
function CustomHandler:init_worker()
-- Implement logic for the init_worker phase here (http/stream)
kong.log("init_worker")
end
function CustomHandler:configure(configs)
-- Implement logic for the configure phase here
--(called whenever there is change to any of the plugins)
kong.log("configure")
end
function CustomHandler:preread(config)
-- Implement logic for the preread phase here (stream)
kong.log("preread")
end
function CustomHandler:certificate(config)
-- Implement logic for the certificate phase here (http/stream)
kong.log("certificate")
end
function CustomHandler:rewrite(config)
-- Implement logic for the rewrite phase here (http)
kong.log("rewrite")
end
function CustomHandler:access(config)
-- Implement logic for the access phase here (http)
kong.log("access")
end
function CustomHandler:ws_handshake(config)
-- Implement logic for the WebSocket handshake here
kong.log("ws_handshake")
end
function CustomHandler:header_filter(config)
-- Implement logic for the header_filter phase here (http)
kong.log("header_filter")
end
function CustomHandler:ws_client_frame(config)
-- Implement logic for WebSocket client messages here
kong.log("ws_client_frame")
end
function CustomHandler:ws_upstream_frame(config)
-- Implement logic for WebSocket upstream messages here
kong.log("ws_upstream_frame")
end
function CustomHandler:body_filter(config)
-- Implement logic for the body_filter phase here (http)
kong.log("body_filter")
end
function CustomHandler:log(config)
-- Implement logic for the log phase here (http/stream)
kong.log("log")
end
function CustomHandler:ws_close(config)
-- Implement logic for WebSocket post-connection here
kong.log("ws_close")
end
-- return the created table, so that Kong can execute it
return CustomHandler
In the example above we are using Lua’s :
shorthand syntax for
functions taking self
as a first parameter. An equivalent non-shorthand version
of the access
function would be:
function CustomHandler.access(self, config)
-- Implement logic for the access phase here (http)
kong.log("access")
end
The plugin’s logic doesn’t need to be all defined inside the handler.lua
file.
It can be split into several Lua files, also called modules.
The handler.lua
module can use require
to include other modules in the plugin.
For example, the following plugin splits the functionality into three files.
access.lua
and body_filter.lua
return functions. They are in the same
folder as handler.lua
, which requires and uses them to build the plugin:
-- handler.lua
local access = require "kong.plugins.my-custom-plugin.access"
local body_filter = require "kong.plugins.my-custom-plugin.body_filter"
local CustomHandler = {
VERSION = "1.0.0",
PRIORITY = 10
}
CustomHandler.access = access
CustomHandler.body_filter = body_filter
return CustomHandler
-- access.lua
return function(self, config)
kong.log("access phase")
end
-- body_filter.lua
return function(self, config)
kong.log("body_filter phase")
end
See the source code of the Key-Auth Plugin
for an example of a real-life handler code.
The BasePlugin
module is deprecated and has been removed from
Kong Gateway. If you have an old plugin that uses this module, replace
the following section:
-- DEPRECATED --
local BasePlugin = require "kong.plugins.base_plugin"
local CustomHandler = BasePlugin:extend()
CustomHandler.VERSION = "1.0.0"
CustomHandler.PRIORITY = 10
With the current equivalent:
local CustomHandler = {
VERSION = "1.0.0",
PRIORITY = 10,
}
You don’t need to add a :new()
method or call any of the CustomHandler.super.XXX:(self)
methods.