Local Kong API Gateway for Go Web Server

July 26, 2018

This guide will teach you how to run the Kong API gateway locally as a proxy server for a Golang API using Docker.

The Go API

The Golang standard library has a very simple http library that makes it very easy to spin up a web server. For now, we will build the simplest implementation of a web server. Start by creating a new directory in your go/src/.

mkdir go-api && cd $_

Then create a new file main.go.

touch main.go

And copy the following snippet into it:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "This is an endpoint.")
}

func main() {
    http.HandleFunc("/test", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

This simple API has one endpoint and will serve on port 8080.

While we are here, we can go ahead and create a very simple Dockerfile to run our web server in a container:

touch Dockerfile

And the contents:

FROM golang:onbuild
EXPOSE 8080

We will move on to setting up the Kong server, but will come back to this when it is up and running.

The Kong Server

Our next task is setting up the Kong server. We will use Docker to run the Kong image as well as a Cassandra database image. The first step is setting up a Docker network:

docker network create kong-net

Then we can run our Cassandra container:

docker run d --name kong-database /
--network=kong-net /
-p 9042:9042 /
cassandra:3

And apply the database migrations to it:

docker run --rm /
--network=knog-net /
-e "KONG_DATABASE=cassandra" /
-e "KONG_PG_HOST=kong-database" /
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" /
kong:latest kong migrations up

Lastly, we will start the Kong server:

docker run -d --name kong /
--network=kong-net /
-e "KONG_DATABASE=cassandra" /
-e "KONG_PG_HOST=kong-database" /
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" /
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" /
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" /
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" /
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" /
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" /
-p 8080:8080 /
-p 8443:8443 /
-p 8001:8001 /
-p 8444:8444 /
kong:latest

Now, to verify that the Kong server is up and running and has connected to the Cassandra container, we can use curl to query the Kong Admin API:

curl -i http://localhost:8001/

If connection was successful, you should receive an HTTP 200 OK response.

Adding our Web Server as a Kong Service

Now we want to take our web server and use the Kong gateway as a proxy. First, let’s use the Dockerfile we created at the beginning to get the web server running in a container:

docker build -t go-server .
docker run -p 8080:8080 go-server

To check that the web server is running and that the port has been correctly mapped to localhost, go to http://localhost:8080/test and make sure that the response is “This is an endpoint.”

Now that the web server is running, we need to register it as a Kong service. We will use the Kong Admin API to do so (there are many open source GUI’s you can also use if you prefer that method). In order for Kong to find the web server, we must determine our local IP address.

ifconfig | grep inet

Now we can register the service with Kong:

curl -i -X POST --url http://localhost:8001/services/ --date 'name=go-server' --data 'url=http://{yourIP}:8080'

Lastly, we must also add a route for the service:

curl -i -X POST --url http://localhost:8001/services/go-server/routes --data 'hosts[]={yourIP}'

Now we can finally query our API endpoint through Kong!

curl -v 'http://localhost:8000/test' --header 'Host {yourIP}'

You should get an HTTP 200 OK response as well as the response string: “This is an endpoint.”

Kong is a great way to provide authentication, load balancing, and more to your microservice API’s, and as you can see it is very simple to setup. Feel free to contact me on Twitter at @HashedDan with any questions or thoughts!