Kong Plugin Development: Local Development and Installation on Your Laptop/VM
Tags: kong, lua, kongplugin, kongapigateway
Published: 2024-06-10 07:47:51

By **Venkata Reddy Bhavanam**
Author LinkedIn:https://www.linkedin.com/in/venkatareddybhavanam/


Kong is a popular, lightweight, fast, and flexible cloud-native API gateway. One of the key benefits of using Kong is its ability to extend the core functionality with the help of plugins. Kong provides many inbuilt plugins out of the box, but we are not limited to them. One can develop a custom plugin for their use case and inject it into the request/response life cycle.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/78wfr1vodx70se7pk7qo.png)

**Kong API Gateway (image Credits — KongHQ):**

Kong is a Lua application running on top of **Nginx** and **OpenResty**. So, it allows building custom plugins natively using Lua. Writing custom plugins in other languages like **Go**, **Javascript**, and **Python** is also possible.

Kong can be installed in several ways. You can install Kong in a VM, Docker, or Kubernetes cluster.

This blog doesn’t aim to teach you how to write a custom plugin but how to install a custom plugin in a VM-based mode of Kong installation. If you are interested in how to write a custom plugin, please check out the **Kong guides on plugin development**.

Ideally, you’d use **Pongo for custom plugin development**. Once the development is complete, you can use one of the following methods to deploy the plugin based on your mode of Kong installation.

**At a high level, a Kong plugin will have two files:**

1.**handler.lua:** This is where we write Lua functions that get called during different phases of the request/response life cycle. These are maps to Nginx worker life cycle methods.

2.**schema.lua:** This is where we define the plugin configuration as schema(A Lua table), add some validations, provide default values, etc.

For this example, we’ll take a simple plugin that returns the version of the plugin as a response header. Below is the code for handler.lua

```
local plugin = {
  PRIORITY = 1000, -- set the plugin priority, which determines plugin execution order
  VERSION = "0.1", -- version in X.Y.Z format. Check hybrid-mode compatibility requirements.
}

function plugin:init_worker()
  kong.log.debug("saying hi from the 'init_worker' handler")
end

-- runs in the 'access_by_lua_block'
function plugin:access(plugin_conf)
  kong.service.request.set_header(plugin_conf.request_header, "this is on a request")
end

-- runs in the 'header_filter_by_lua_block'
function plugin:header_filter(plugin_conf)
  kong.response.set_header(plugin_conf.response_header, plugin.VERSION)
end

return plugin
```
and the schema.lua

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

local PLUGIN_NAME = "api-version"

local schema = {
  name = "api-version",
  fields = {
    { consumer = typedefs.no_consumer },  -- this plugin cannot be configured on a consumer (typical for auth plugins)
    { protocols = typedefs.protocols_http },
    { config = {
        type = "record",
        fields = {
          { request_header = typedefs.header_name {
              required = true,
              default = "Hello-World" } },
          { response_header = typedefs.header_name {
              required = true,
              default = "Bye-World" } },
        },
        entity_checks = {
          { at_least_one_of = { "request_header", "response_header" }, },
          { distinct = { "request_header", "response_header"} },
        },
      },
    },
  },
}

return schema
```
**Deploying a custom plugin on a VM:**

Please check this out to **install the Kong gateway on Ubuntu**. Once the installation is complete, ensure you can access the gateway at **http://localhost:8000**

**Install the API-version plugin:**

From the plugin folder, hit `luarocks make`

The default location for the Kong configuration is located at `/etc/kong/kong.conf` To tell Kong we want to install a custom plugin, add the plugin name to `plugins` config variable so that it looks like `plugins=bundled,custom-plugin-name` . In our case, it will be: `plugins=bundled,api-version`

And then restart Kong, `kong restart -c /etc/kong/kong.conf`
Once Kong is reloaded, the plugin should appear in the list of available plugins.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2xutxq61c3wnbycwmzy.png)

Installed custom plugin
We can enable the plugin globally or on a particular service/route.
Let’s create a service, route, and apply the plugin to the service to see it in action. We can create all these through the Kong manager UI, but we’ll use HTTPie to create these through the terminal.

```
http :8001/services name=mockbin url=https://mockbin.org Kong-Admin-Token:password
http -f :8001/services/mockbin/routes name=mock-route paths=/echo Kong-Admin-Token:password
http -f :8001/services/mockbin/plugins name=api-version Kong-Admin-Token:password
```


Now, if we request the /echo route, we can see the custom header that returns the plugin version in the response

```
http :8000/echo --headers
HTTP/1.1 200 OK
Bye-World: 0.1
...
```
That’s how a custom plugin can be installed in a VM-based Kong installation. In the next post, we’ll see how to **install a custom plugin through Docker and Kubernetes**.

**For more information:** https://zelarsoft.com/