Go Plugin Development on Kong
Tags: go, docker, kong, api
Published: 2020-02-20 19:29:56

---
title: Go Plugin Development on Kong
published: true
description: We are going to build a plugin by using Go lang on Kong.
tags: #go #docker #kong #api
---

Earlier this year, Kong has announced brilliant features. You check it out the following. 

https://konghq.com/blog/kong-gateway-2-0-0-released/

I was very interested in one of them which is we will be able to develop Go plugins on Kong. I built a plugin to test and as soon as possible I'm writing this blog post eventually. I'm going to demonstrate a plugin that checks the consumer key from query string. 

I used to run DB-less Kong on Docker and I prefer that either. 

```bash
FROM kong/go-plugin-tool:2.0.4-alpine-latest AS builder

RUN mkdir -p /tmp/key-checker/

COPY . /tmp/key-checker/

RUN cd /tmp/key-checker/ && \
    go get github.com/Kong/go-pdk && \
    go mod init kong-go-plugin && \
    go get -d -v github.com/Kong/go-pluginserver && \
    go build github.com/Kong/go-pluginserver && \
    go build -buildmode plugin key-checker.go

FROM kong:2.0.4-alpine

RUN mkdir /tmp/go-plugins
COPY --from=builder  /tmp/key-checker/go-pluginserver /usr/local/bin/go-pluginserver
COPY --from=builder  /tmp/key-checker/key-checker.so /tmp/go-plugins
COPY config.yml /tmp/config.yml

USER root
RUN chmod -R 777 /tmp
RUN /usr/local/bin/go-pluginserver -version && \
    cd /tmp/go-plugins && \
    /usr/local/bin/go-pluginserver -dump-plugin-info key-checker
USER kong
```

In this way, we copy our required files. Let's go into details. Firstly, we create a builder image and I copy my **key-checker.go** file and I build it as a go plugin. After that, I get that file from the builder image and I put it in Kong image. That's straightforward. 

Let's look over the Go file.

```go
package main

import (
	"github.com/Kong/go-pdk"
)

// it represents to config parameters into the config.yml
type Config struct {
	Apikey string
}

func New() interface{} {
	return &Config{}
}

func (conf Config) Access(kong *pdk.PDK) {
	key, err := kong.Request.GetQueryArg("key")
	apiKey := conf.Apikey 

	if err != nil {
		kong.Log.Err(err.Error())
	}

	//it adjusts the header parameters in this way.
	x := make(map[string][]string)
	x["Content-Type"] = append(x["Content-Type"], "application/json")

	//If the key of the consumer is not equal to the claimed key, kong doesn't ensure the proxy
	if apiKey != key {
		kong.Response.Exit(403, "You have no correct consumer key.", x)	
	}
}
```

This file tells us that we check the key from the query string. If it is not equal to the key from the config file, we don't provide proxy service. In another case, it will ensure the proxy well and clearly the claimed URL from the config file. This is the config file. Also, I try to show changing header parameters and I write content type as a parameter for only showing.

```yml
# go.yml
_format_version: "1.1"
services:
- url: https://reqres.in/api/users?page=2
  routes:
  - paths:
    - "/"
  plugins:
  - name: key-checker
    config:
      apikey: mysecretconsumerkey
```

To build the Dockerfile I run this command.

```bash
docker build -t kong-demo .
```

Once it built, I run the following command. I point the related directories by using environment variables.

```bash
docker run -ti --rm --name kong-go-plugins \
  -e "KONG_DATABASE=off" \
  -e "KONG_GO_PLUGINS_DIR=/tmp/go-plugins" \
  -e "KONG_DECLARATIVE_CONFIG=/tmp/config.yml" \
  -e "KONG_PLUGINS=key-checker" \
  -e "KONG_PROXY_LISTEN=0.0.0.0:8000" \
  -p 8000:8000 \
  kong-demo
```

Right, we're able to check the service. As you can see, the key is not equal. Therefore the status code is 403 and proxy service is not working.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3n4vnlwjrqzzdropt90k.png)


When I enter the correct consumer key, as expected Kong ensures the proxy service clearly and URL is requested. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7hqv6q7u8wt4h3blme0l.png)

### Conclusion ###
This feature drastically will be useful for Go developers and you could build pretty cool plugins in this way. I also want to share some practical URLs like the following. I hope the blog post ignites the minds to build awesome Go plugins on Kong. Happy Konging!

https://docs.konghq.com/2.0.x/go

https://godoc.org/github.com/Kong/go-pdk

https://github.com/gszr/kong-2.0-demo