This tutorial aims to exemplify the construction and implementation of custom policies.
Product versions used:
Custom policies have been introduced to address a heterogeneous environment of information, configurations, and actions to be executed by 3scale API Management, thereby better serving and enhancing the experience for its customers. Currently, 3scale API Management has 38 default policies, including:
- 3scale Auth Caching
- 3scaleBatcher
- 3scaleReferrer
- AnonymousAccess
- CamelService
- and many more.
For most client-managed products, these policies already suffice, but in others, they need to be customized based on an existing policy or even created from scratch. So, here we will address the creation of policies from scratch.
Custom policy
By default, three main files will be created, namely an apicast-policy.json
(layout of the screen to be displayed and its rules in 3scale API Management), init.lua
(where the pointer will be directed to the logic of absorption and implementation of the policy), and example.lua
(where the logic and behavior to handle the policy will be coded).
What are custom policies?
Custom policies are an important support tool for meeting customer needs, as existing policies are often inflexible and may not fully address what the client requires. These custom policies often originate from an existing policy used as a base, with additional rules and requirements added to meet the client’s needs.
Here, we will show how to create one from scratch, explain how they work, how they are implemented, and how they are declared.
Example of the types of files needed for the creation of each policy
Apicast-policy.json
:
{
"$schema": "http://apicast.io/policy-v1/schema#manifest#",
"name": "APIcast Example Policy",
"summary": "This is just an example.",
"description": "This policy is just an example how to write your custom policy.",
"version": "0.1",
"configuration": {
"type": "object",
"properties": { }
}
}
init.lua
:
return require('examplo')
exemplo.lua
:
local setmetatable = setmetatable
local _M = require('apicast.policy').new('Example', '0.1')
local mt = { __index = _M }
function _M.new()
return setmetatable({}, mt)
end
function _M:init()
-- do work when nginx master process starts
end
function _M:init_worker()
-- do work when nginx worker process is forked from master
end
function _M:rewrite()
-- change the request before it reaches upstream
ngx.req.set_header('X-CustomPolicy', 'customValue')
end
function _M:access()
-- ability to deny the request before it is sent upstream
end
function _M:content()
-- can create content instead of connecting to upstream
end
function _M:post_action()
-- do something after the response was sent to the client
end
function _M:header_filter()
-- can change response headers
end
function _M:body_filter()
-- can read and change response body
-- https://github.com/openresty/lua-nginx-module/blob/master/README.markdown#body_filter_by_lua
end
function _M:log()
-- can do extra logging
end
function _M:balancer()
-- use for example require('resty.balancer.round_robin').call to do load balancing
end
return _M
Next, we'll delve into each of these components and how we can code them.