schema.lua

Uses: Kong Gateway

Most of the time, it makes sense for your plugin to be configurable to answer all of your users’ needs. Your plugin’s configuration is stored in the data store for Kong Gateway to retrieve it and pass it to your handler.lua methods when the plugin is being executed.

The configuration consists of a Lua table, in what we call a schema. It contains key/value properties that the user will set when enabling the plugin. Kong Gateway provides you with a way of validating the user’s configuration for your plugin.

Your plugin’s configuration is verified against your schema when a user enables or updates a plugin.

For example, when a user performs the following request:

curl -X POST http://localhost:8001/services/{service-name-or-id}/plugins \
  -d "name=my-custom-plugin" \
  -d "config.foo=bar"

If all properties of the config object are valid according to your schema, then the API would return 201 Created and the plugin would be stored in the database along with its configuration:

{
  foo = "bar"
}

If the configuration is not valid, the Admin API would return 400 Bad Request and the appropriate error messages.

schema.lua specification

This module is to return a Lua table with properties that will define how your plugins can later be configured by users. Available properties are:

All the plugins inherit some default fields which are:

In most of the cases you can ignore most of those and use the defaults or let the user specify value when enabling a plugin.

Here is an example of a potential schema.lua file (with some overrides applied):

local typedefs = require "kong.db.schema.typedefs"


return {
  name = "<plugin-name>",
  fields = {
    {
      -- this plugin will only be applied to Services or Routes
      consumer = typedefs.no_consumer
    },
    {
      -- this plugin will only run within Nginx HTTP module
      protocols = typedefs.protocols_http
    },
    {
      config = {
        type = "record",
        fields = {
          -- Describe your plugin's configuration's schema here.        
        },
      },
    },
  },
  entity_checks = {
    -- Describe your plugin's entity validation rules
  },
}

Describe your configuration schema

The config.fields property of your schema.lua file describes the schema of your plugin’s configuration. It’s a flexible array of field definitions where each field is a valid configuration property for your plugin, describing the rules for that property. For example:

{
  name = "<plugin-name>",
  fields = {
    config = {
      type = "record",
      fields = {
        {
          some_string = {
            type = "string",
            required = false,
          },
        },
        {
          some_boolean = {
            type = "boolean",
            default = false,
          },
        },
        {
          some_array = {
            type = "array",
            elements = {
              type = "string",
              one_of = {
                "GET",
                "POST",
                "PUT",
                "DELETE",
              },
            },
          },
        },
      },
    },
  },
}

Here is a list of commonly used rules for a property:

Rule

Description

type The type of a property.
required Whether or not the property is required.
default The default value for the property when not specified.
elements The field definition of array or set elements.
keys The field definition of map keys.
values The field definition of map values.
fields The field definition(s) of record fields.

You can also add field validators, for example:

Rule

Description

between Checks that the input number is between allowed values.
eq Checks the equality of the input to allowed value.
ne Checks the inequality of the input to allowed value.
gt Checks that the number is greater than given value.
len_eq Checks that the input string length is equal to the given value.
len_min Checks that the input string length is at least the given value.
len_max Checks that the input string length is at most the given value.
match Checks that the input string matches the given Lua pattern.
not_match Checks that the input string doesn’t match the given Lua pattern.
match_all Checks that the input string matches all the given Lua patterns.
match_none Checks that the input string doesn’t match any of the given Lua patterns.
match_any Checks that the input string matches any of the given Lua patterns.
starts_with Checks that the input string starts with a given value.
one_of Checks that the input string is one of the accepted values.
contains Checks that the input array contains the given value.
is_regex Checks that the input string is a valid regex pattern.
custom_validator A custom validation function written in Lua.

Examples

This schema.lua file is for the key-auth plugin:

-- schema.lua
local typedefs = require "kong.db.schema.typedefs"


return {
  name = "key-auth",
  fields = {
    {
      consumer = typedefs.no_consumer
    },
    {
      protocols = typedefs.protocols_http
    },
    {
      config = {
        type = "record",
        fields = {
          {
            key_names = {
              type = "array",
              required = true,
              elements = typedefs.header_name,
              default = {
                "apikey",
              },
            },
          },
          {
            hide_credentials = {
              type = "boolean",
              default = false,
            },
          },
          {
            anonymous = {
              type = "string",
              uuid = true,
            },
          },
          {
            key_in_body = {
              type = "boolean",
              default = false,
            },
          },
          {
            run_on_preflight = {
              type = "boolean",
              default = true,
            },
          },
        },
      },
    },
  },
}

When implementing the access() function of your plugin in handler.lua and given that the user enabled the plugin with the default values, you’d have access to:

-- handler.lua

local CustomHandler = {
  VERSION  = "1.0.0",
  PRIORITY = 10,
}

local kong = kong

function CustomHandler:access(config)

  kong.log.inspect(config.key_names)        -- { "apikey" }
  kong.log.inspect(config.hide_credentials) -- false
end


return CustomHandler

The above example uses the kong.log.inspect function of the Plugin Development Kit to print out those values to the Kong Gateway logs.

A more complex example, which could be used for an eventual logging plugin:

-- schema.lua
local typedefs = require "kong.db.schema.typedefs"


return {
  name = "my-custom-plugin",
  fields = {
    {
      config = {
        type = "record",
        fields = {
          {
            environment = {
              type = "string",
              required = true,
              one_of = {
                "production",
                "development",
              },
            },
          },
          {
            server = {
              type = "record",
              fields = {
                {
                  host = typedefs.host {
                    default = "example.com",
                  },
                },
                {
                  port = {
                    type = "number",
                    default = 80,
                    between = {
                      0,
                      65534
                    },
                  },
                },  
              },
            },
          },
        },
      },
    },
  },
}

Such a configuration will allow a user to post the configuration to your plugin as follows:

curl -X POST http://localhost:8001/services/<service-name-or-id>/plugins \
  -d "name=my-custom-plugin" \
  -d "config.environment=development" \
  -d "config.server.host=http://localhost"

And the following will be available in handler.lua:

-- handler.lua

local CustomHandler = {
  VERSION  = "1.0.0",
  PRIORITY = 10,
}

local kong = kong

function CustomHandler:access(config)

  kong.log.inspect(config.environment) -- "development"
  kong.log.inspect(config.server.host) -- "http://localhost"
  kong.log.inspect(config.server.port) -- 80
end


return CustomHandler

You can also see a real-world example of schema in the Key-Auth plugin source code.

Something wrong?

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!