Understand the main functional features of API gateway through examples

2023.12.06

Understand the main functional features of API gateway through examples

This article reviews the relatively mature API gateway technology, briefly explains the evolution stage, mainstream features of API gateways, and the mainstream API gateways currently on the market, and takes the Tyk Gateway community open source version implemented in Go as an example. The method introduces the main functions of API gateway.

In today's technology field, the concept of "going to the cloud" is gradually rising. People like David Heinemeier Hansson [1] (co-founder of 37signals, Creator of Ruby on Rails) directly moved all the company's business from the public cloud. In the self-built data center [2] . Although most enterprises will not be so "extreme", as enterprises adopt cloud native architecture extensively and deeply, they will inevitably face dependence on cloud services. Cloud services have been widely used in the past few years to build flexible and scalable applications and infrastructure, providing enterprises with many conveniences and innovation opportunities. However, as business scale grows and data volume increases, the cost of cloud services also rises. Enterprises are beginning to realize that dependence on cloud services has become an issue worthy of re-evaluation. The cost of cloud services can take up a significant portion of a business's available budget. To stay competitive and better control costs, enterprises need to look for ways to reduce their reliance on cloud services and find more economical solutions while ensuring they still get the performance, security and scalability they need.

In this context, our focus is to select a suitable API gateway and evaluate the candidate's support from the perspective of mainstream functional features. As a key component in modern cloud-native application architecture, API gateway plays the role of the middle layer connecting front-end applications and back-end services, and is responsible for managing, controlling, and protecting API access. Its functional features are critical to ensuring the security, reliability, and scalability of the API.

Although API gateways are not a new thing, they seem to have become a bit "unfamiliar" to those who have relied on the services of cloud providers for a long time. Therefore, this article aims to help us re-understand the main characteristics of API gateways and gain the ability to select API gateways so that we can find a suitable replacement before stopping using cloud provider services^_^.

1. API Gateway Review

API gateway is one of the key components in modern application architecture. Its existence simplifies the application architecture and provides a single access entrance for clients, as well as related control, optimization and management. API gateway can help enterprises implement microservice architecture, improve system scalability and security, and provide better developer experience and user experience.

1.1 Evolution of API Gateway

With the rapid development of the Internet and the growing demand for APIs from enterprises, API gateways have gradually emerged as a key middle-tier technology and have experienced a series of evolutions and developments. The evolution history of API gateway is roughly divided into the following stages:

  • The early days before API Gateway

In the early stages of the development of the Internet, most applications existed in the form of single applications [3] . Later, as the application scale expanded and business complexity increased, the architecture of single applications became inflexible and scalable. Service-Oriented Architecture (SOA) gradually emerged, and enterprises began to split applications into a set of Independent service. During this period, each service independently exposed APIs to the outside world, and clients directly accessed services through these APIs. However, this would lead to some security, operation and maintenance, and scalability issues. After that, enterprises also began to realize that a middle layer was needed to manage and control this client-to-service communication behavior and ensure the reliability and security of the service, so the concept of API gateway began to emerge.

  • The rise of API gateways

The main function of early API gateways was simple routing and forwarding. The API gateway forwards the request from the client to the backend service and returns the response from the backend service to the client. At this stage, the function of the API gateway is very simple and is mainly used to solve communication problems between clients and back-end services.

  • The maturity of API gateway

With the rise of microservice architecture and the continuous development of API applications, enterprises have begun to further split applications into smaller, independently deployed microservices. Each externally exposed microservice has its own API, which is uniformly managed and accessed through the API gateway. The role of API gateway in microservice architecture has become more important, and its functions have gradually become richer.

At this stage, it is not only responsible for routing and forwarding requests, the API gateway also adds security and governance functions to meet the needs of microservices in several different areas. For example: API gateway can protect the security of API through identity authentication, authorization, access control and other functions; manage API access through fault-tolerant mechanisms based on retry, timeout, circuit breaker, etc.; manage API access through logging, indicator-based collection and tracing Observe and monitor API access; support real-time service discovery, etc.

API gateway (picture from the Internet)API gateway (picture from the Internet)

  • Cloud nativeization of API gateway

With the development of cloud native technologies, such as containerization and service mesh, API gateways are constantly evolving and adapting to new environments. In a cloud-native environment, the API gateway integrates with container orchestration systems (such as Kubernetes) and service meshes, and can itself be deployed as a cloud-native service to achieve higher scalability, elasticity, and automation. At the same time, new technologies and standards are constantly emerging, such as GraphQL and gRPC , and API gateways have also added integration and support for these new technologies.

1.2 Main functional features of API gateway

From the above evolutionary history, we can see that the evolution of API gateway has made it from the initial simple request forwarding role to gradually becoming a key component in the entire API management and microservice architecture. It not only acts as an adapter between the API management layer and the back-end service layer, but is also an indispensable infrastructure in the cloud native architecture, making microservice management more intelligent and automated. The following are the main functional features of modern API gateways. We will also provide examples based on these features in the future:

  • Request forwarding and routing
  • Authentication and authorization
  • Traffic control and rate limiting
  • High availability and fault tolerance
  • Monitoring and Observability

2. Those mainstream API gateways

The following is a collection of mainstream API gateways from CNCF Landscape [4] (as of November 2023). The figure shows some details about each gateway, including the number of stars and the company or organization behind the development:

picturepicture

Mainstream API gateways are also implemented by major public cloud providers, such as: Amazon's API Gateway [5] , Google Cloud's API Gateway [6] , and Azure API Management in the picture above, etc., but they are not within our selection range. Although included in CNCF, most API gateways have not received much attention, with less than 30% exceeding 1k stars. These projects that are not very popular or whose dev is not so active cannot play a key role in the production environment; and like APISIX [7] and Kong [8] , two gateways that have attracted much attention, are built on Nginx and their technology stacks are not suitable for us; while EMISSARY INGRESS [9] , Gloo, etc. are completely cloud-based. Native, or Kubernetes Native, cannot be deployed and run in a VM-based or bare metal environment without Kubernetes.

Well, there are only a few API Gateways implemented in Go. Among them, we choose to use Tyk API Gateway [10] as an example for subsequent API function demonstration.

Note: This does not mean that the Tyk API Gateway is better than other Go-implemented API Gateways [11] , but its information is relatively complete and suitable for demonstration in this article.

3. Examples of main functional features of API gateway (Tyk API gateway version)

3.1 Introduction to Tyk API Gateway

I remember knowing the existence of Tyk API gateway [12] at least 5 years ago . I have the impression that it is one of the early batch of API gateways developed using Go language. Tyk has maintained an active dev status from its initial pure open source project to a gateway that is now supported by the commercial company behind it and open sourced in the Open Core model [13] . After years of evolution, it has become a powerful open source and commercial API management and gateway solution [14] , providing comprehensive functions and tools to help developers effectively manage, protect and monitor APIs. At the same time, Tyk API gateway supports multiple installation and deployment methods, that is, it can be run as a single program on a physical machine or VM, it can also support container deployment, and can be launched through docker-compose [15] , or through Kubernetes Operator [16 ] Deploy it in Kubernetes, which also gives Tyk API gateway the ability to migrate smoothly on major public clouds.

picturepicture

For details on the functions of the open source version of Tyk API gateway [17] , you can click on the hyperlink on the left to go to its official website, and will not go into details here.

3.2 Install Tyk API gateway

Next we will install the Tyk API gateway. We install it directly on the VM. The environment on the VM is CentOS 7.9. Tyk API provides many installation methods. Here, CentOS’s yum package management tool is used to install the Tyk API gateway [18] . The general steps are as follows (the demonstrations are all operated with root permissions).

3.2.1 Create tyk gateway software source

The default yum repo does not contain tyk gateway. We need to create a new source under /etc/yum.repos.d, that is, create a new tyk_tyk-gateway.repo file with the following content:

[tyk_tyk-gateway]
name=tyk_tyk-gateway
baseurl=https://packagecloud.io/tyk/tyk-gateway/el/7/$basearch
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/tyk/tyk-gateway/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300

[tyk_tyk-gateway-source]
name=tyk_tyk-gateway-source
baseurl=https://packagecloud.io/tyk/tyk-gateway/el/7/SRPMS
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/tyk/tyk-gateway/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • twenty one.

Next, we execute the following command to create the YUM cache of the tyk_tyk-gateway repo:

$yum -q makecache -y --disablerepo='*' --enablerepo='tyk_tyk-gateway'
导入 GPG key 0x5FB83118:
 用户ID     : "https://packagecloud.io/tyk/tyk-gateway (https://packagecloud.io/docs#gpg_signing) <support@packagecloud.io>"
 指纹       : 9179 6215 a875 8c40 ab57 5f03 87be 71bd 5fb8 3118
 来自       : https://packagecloud.io/tyk/tyk-gateway/gpgkey
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

After the repo is configured and cached, we can install Tyk API Gateway:

$yum install -y tyk-gateway
  • 1.

After installation, tky-gateway will exist on the host as a systemd daemon service [19] . After the program unexpectedly exits or the virtual machine is restarted, the service will also be automatically started by systemd. You can check the running status of the service through the systemctl status command:

# systemctl status tyk-gateway
● tyk-gateway.service - Tyk API Gateway
   Loaded: loaded (/usr/lib/systemd/system/tyk-gateway.service; enabled; vendor preset: disabled)
   Active: active (running) since 日 2023-11-19 20:22:44 CST; 12min ago
 Main PID: 29306 (tyk)
    Tasks: 13
   Memory: 19.6M
   CGroup: /system.slice/tyk-gateway.service
           └─29306 /opt/tyk-gateway/tyk --conf /opt/tyk-gateway/tyk.conf

11月 19 20:34:54 iZ2ze18rmx2avqb5xgb4omZ tyk[29306]: time="Nov 19 20:34:54" level=error msg="Connection to Redis faile...b-sub
11月 19 20:35:04 iZ2ze18rmx2avqb5xgb4omZ tyk[29306]: time="Nov 19 20:35:04" level=error msg="cannot set key in pollerC...ured"
11月 19 20:35:04 iZ2ze18rmx2avqb5xgb4omZ tyk[29306]: time="Nov 19 20:35:04" level=error msg="Redis health check failed...=main
Hint: Some lines were ellipsized, use -l to show in full.
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

3.2.2 Install redis

We see that tyk-gateway has been started successfully, but judging from its service log, it reports an error when connecting to redis! Tyk gateway stores data in redis by default. In order for tyk gateway to operate normally, we also need to install redis! Here we use containers to install and run a redis service:

$docker pull redis:6.2.14-alpine3.18
$docker run -d --name my-redis -p 6379:6379 redis:6.2.14-alpine3.18 
e5d1ec8d5f5c09023d1a4dd7d31d293b2d7147f1d9a01cff8eff077c93a9dab7
  • 1.
  • 2.
  • 3.

After pulling and running redis, we verify the connection to the redis server through redis-cli:

# docker run -it --rm redis:6.2.14-alpine3.18  redis-cli -h 192.168.0.24
192.168.0.24:6379>
  • 1.
  • 2.

We see that we can connect normally! But at this time, Tyk Gateway still cannot connect to redis normally. We still need to make some configuration adjustments to Tyk Gateway!

3.2.3 Configuring Tyk Gateway

By default, yum installs Tyk Gateway under /opt/tyk-gateway. The file layout under this path is as follows:

$tree -F -L 2 .
.
├── apps/
│   └── app_sample.json
├── coprocess/
│   ├── api.h
│   ├── bindings/
│   ├── coprocess_common.pb.go
│   ├── coprocess_mini_request_object.pb.go
│   ├── coprocess_object_grpc.pb.go
│   ├── coprocess_object.pb.go
│   ├── coprocess_response_object.pb.go
│   ├── coprocess_return_overrides.pb.go
│   ├── coprocess_session_state.pb.go
│   ├── coprocess_test.go
│   ├── dispatcher.go
│   ├── grpc/
│   ├── lua/
│   ├── proto/
│   ├── python/
│   └── README.md
├── event_handlers/
│   └── sample/
├── install/
│   ├── before_install.sh*
│   ├── data/
│   ├── init_local.sh
│   ├── inits/
│   ├── post_install.sh*
│   ├── post_remove.sh*
│   ├── post_trans.sh
│   └── setup.sh*
├── middleware/
│   ├── ottoAuthExample.js
│   ├── sampleMiddleware.js
│   ├── samplePostProcessMiddleware.js
│   ├── samplePreProcessMiddleware.js
│   ├── testPostVirtual.js
│   ├── testVirtual.js
│   └── waf.js
├── policies/
│   └── policies.json
├── templates/
│   ├── breaker_webhook.json
│   ├── default_webhook.json
│   ├── error.json
│   ├── monitor_template.json
│   └── playground/
├── tyk*
└── tyk.conf
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • twenty one.
  • twenty two.
  • twenty three.
  • twenty four.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.

Among them, tyk.conf is the configuration file of tyk gateway. Let’s take a look at its default content first:

$cat /opt/tyk-gateway/tyk.conf
{
  "listen_address": "",
  "listen_port": 8080,
  "secret": "xxxxxx",
  "template_path": "/opt/tyk-gateway/templates",
  "use_db_app_configs": false,
  "app_path": "/opt/tyk-gateway/apps",
  "middleware_path": "/opt/tyk-gateway/middleware",
  "storage": {
    "type": "redis",
    "host": "redis",
    "port": 6379,
    "username": "",
    "password": "",
    "database": 0,
    "optimisation_max_idle": 2000,
    "optimisation_max_active": 4000
  },
  "enable_analytics": false,
  "analytics_config": {
    "type": "",
    "ignored_ips": []
  },
  "dns_cache": {
    "enabled": false,
    "ttl": 3600,
    "check_interval": 60
  },
  "allow_master_keys": false,
  "policies": {
    "policy_source": "file"
  },
  "hash_keys": true,
  "hash_key_function": "murmur64",
  "suppress_redis_signal_reload": false,
  "force_global_session_lifetime": false,
  "max_idle_connections_per_host": 500
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • twenty one.
  • twenty two.
  • twenty three.
  • twenty four.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.

We see that the redis configuration information is stored under storage. We need to modify the redis host configuration to our VM address:

"host": "192.168.0.24",
  • 1.

Then restart the Tyk Gateway service:

$systemctl daemon-reload
$systemctl restart tyk-gateway
  • 1.
  • 2.

After that, we check the running status of tyk gateway:

systemctl status tyk-gateway
● tyk-gateway.service - Tyk API Gateway
   Loaded: loaded (/usr/lib/systemd/system/tyk-gateway.service; enabled; vendor preset: disabled)
   Active: active (running) since 一 2023-11-20 06:54:07 CST; 41s ago
 Main PID: 20827 (tyk)
    Tasks: 15
   Memory: 24.8M
   CGroup: /system.slice/tyk-gateway.service
           └─20827 /opt/tyk-gateway/tyk --conf /opt/tyk-gateway/tyk.conf

11月 20 06:54:07 iZ2ze18rmx2avqb5xgb4omZ tyk[20827]: time="Nov 20 06:54:07" level=info msg="Loading API configurations...=main
11月 20 06:54:07 iZ2ze18rmx2avqb5xgb4omZ tyk[20827]: time="Nov 20 06:54:07" level=info msg="Tracking hostname" api_nam...=main
11月 20 06:54:07 iZ2ze18rmx2avqb5xgb4omZ tyk[20827]: time="Nov 20 06:54:07" level=info msg="Initialising Tyk REST API ...=main
11月 20 06:54:07 iZ2ze18rmx2avqb5xgb4omZ tyk[20827]: time="Nov 20 06:54:07" level=info msg="API bind on custom port:0"...=main
11月 20 06:54:07 iZ2ze18rmx2avqb5xgb4omZ tyk[20827]: time="Nov 20 06:54:07" level=info msg="Checking security policy: ...fault
11月 20 06:54:07 iZ2ze18rmx2avqb5xgb4omZ tyk[20827]: time="Nov 20 06:54:07" level=info msg="API Loaded" api_id=1 api_n...ip=--
11月 20 06:54:07 iZ2ze18rmx2avqb5xgb4omZ tyk[20827]: time="Nov 20 06:54:07" level=info msg="Loading uptime tests..." p...k-mgr
11月 20 06:54:07 iZ2ze18rmx2avqb5xgb4omZ tyk[20827]: time="Nov 20 06:54:07" level=info msg="Initialised API Definition...=main
11月 20 06:54:07 iZ2ze18rmx2avqb5xgb4omZ tyk[20827]: time="Nov 20 06:54:07" level=warning msg="All APIs are protected ...=main
11月 20 06:54:07 iZ2ze18rmx2avqb5xgb4omZ tyk[20827]: time="Nov 20 06:54:07" level=info msg="API reload complete" prefix=main
Hint: Some lines were ellipsized, use -l to show in full.
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • twenty one.

Judging from the service log, Tyk Gateway can now connect to redis normally and provide services! We can also verify the running status of the gateway through the following command:

$curl localhost:8080/hello
{"status":"pass","version":"5.2.1","description":"Tyk GW","details":{"redis":{"status":"pass","componentType":"datastore","time":"2023-11-20T06:58:57+08:00"}}}
  • 1.
  • 2.

"/hello" is the built-in route of Tyk Gateway, which is provided by Tyk Gateway itself.

The installation and simple configuration of Tyk Gateway is over here. Next, let’s take a look at the main features of API Gateway and use Tyk Gateway to demonstrate these features.

Note: To view the running log of Tyk Gateway, you can use the journalctl -u tyk-gateway -f command to follow the latest log output in real time.

3.3 Functional features: Request forwarding and routing

Request forwarding and routing are one of the main functional features of API Gateway. API Gateway can forward requests to the corresponding back-end service based on the requested path, method, query parameters and other information. Its core is similar to a reverse proxy, but the difference is that API Gateway adds the "API" layer of abstraction and focuses more on building, managing, and enhancing APIs.

Let's take a look at how Tyk configures API routing. We first create a new API.

3.3.1 Create a new API

Tyk open source version supports two ways to create APIs, one is by calling Tyk's control API [20] , and the other is through traditional configuration files and placed in a specific directory [21] . No matter which method is used to add the API, it will eventually take effect through hot reloading (hot reload) or restarting Tyk Gateway.

Note: The commercial version of Tyk Gateway provides Dashboard, which can manage APIs graphically, and the API definitions of the commercial version will be placed in Postgres or MongoDB. We use the open source version here, which can only be managed manually, and the API definition can only be Put it in the file.

Next, we will create a new API route on Tyk. The schematic diagram of the routing example is as follows:

picturepicture

Before adding a new API, we use curl to access the API path:

$curl localhost:8080/api/v1/no-authn
Not Found
  • 1.
  • 2.

Tyk Gateway returns Not Found because it cannot find the API route. Next, we add routes by calling the tyk gateway API:

$curl -v -H "x-tyk-authorization: {tyk gateway secret}" \
  -s \
  -H "Content-Type: application/json" \
  -X POST \
  -d '{
    "name": "no-authn-v1",
    "slug": "no-authn-v1",
    "api_id": "no-authn-v1",
    "org_id": "1",   
    "use_keyless": true,
    "auth": {         
      "auth_header_name": "Authorization"
    },                
    "definition": {   
      "location": "header",
      "key": "x-api-version"
    },                
    "version_data": { 
      "not_versioned": true,    
      "versions": {             
        "Default": {            
          "name": "Default",    
          "use_extended_paths": true
        }                       
      }                         
    },                          
    "proxy": {                  
      "listen_path": "/api/v1/no-authn",
      "target_url": "http://localhost:18081/",
      "strip_listen_path": true
    },   
    "active": true
}' http://localhost:8080/tyk/apis | python -mjson.tool 

* About to connect() to localhost port 8080 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> POST /tyk/apis HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:8080
> Accept: */*
> x-tyk-authorization: {tyk gateway secret}
> Content-Type: application/json
> Content-Length: 797
> 
} [data not shown]
* upload completely sent off: 797 out of 797 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Wed, 22 Nov 2023 05:38:40 GMT
< Content-Length: 53
< 
{ [data not shown]
* Connection #0 to host localhost left intact
{
    "action": "added",
    "key": "no-authn-v1",
    "status": "ok"
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • twenty one.
  • twenty two.
  • twenty three.
  • twenty four.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.

From the curl return result, we see that the API has been successfully added. At this time, a configuration file named no-authn-v1.json will be added under the apps subdirectory of the tyk gateway installation directory /opt/tyk-gateway. This file has a lot of content, with 300 lines, and will not be posted here. , this file is the newly added no-authn  API definition file [22] .

However, at this moment, Tyk Gateway still needs to be hot-loaded before it can provide services for the new API. Calling the following API can trigger the hot-loading of Tyk Gateway:

$curl -H "x-tyk-authorization: {tyk gateway secret}" -s http://localhost:8080/tyk/reload/group | python -mjson.tool
{
    "message": "",
    "status": "ok"
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

Note: Even if hot loading is triggered successfully, if the json format in the body is wrong, such as an extra trailing comma, Tyk Gateway will not report an error!

After the API route is created and takes effect, let's access the API again:

$ curl localhost:8080/api/v1/no-authn
{
    "error": "There was a problem proxying the request"
}
  • 1.
  • 2.
  • 3.
  • 4.

We see: What Tyk Gateway returns is no longer "Not Found"! Now let's create the no-authn API service. Considering that it can be adapted to more subsequent examples, here is an http server like this:

// api-gateway-examples/httpserver

func main() {    
    // 解析命令行参数   
    port := flag.Int("p", 8080, "Port number")  
    apiVersion := flag.String("v", "v1", "API version")  
    apiName := flag.String("n", "example", "API name")   
    flag.Parse()                                         
                                                         
    // 注册处理程序                                     
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {  
        fmt.Println(*r)                                                  
        fmt.Fprintf(w, "Welcome api: localhost:%d/%s/%s\n", *port, *apiVersion, *apiName)  
    })                                                                                     
                                                                                           
    // 启动HTTP服务器                                                                      
    addr := fmt.Sprintf(":%d", *port)  
    log.Printf("Server listening on port %d\n", *port)  
    log.Fatal(http.ListenAndServe(addr, nil))           
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

We start an instance of the http server:

$go run main.go -p 18081 -v v1 -n no-authn
2023/11/22 22:02:42 Server listening on port 18081
  • 1.
  • 2.

Now we call the no-authn API through tyk gateway:

$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18081/v1/no-authn
  • 1.
  • 2.

We see that the route is connected this time! The no-authn API returned the expected results!

3.3.2 Load balancing

If there are multiple service instances of the no-authn API, Tyk Gateway can also load balance the request traffic to multiple no-authn service instances. The following figure is a schematic diagram of Tyk Gateway load balancing the request traffic [23] :


To achieve responsible balancing, we need to adjust the definition of no-authn API. This time we directly modify /opt/tyk-gateway/apps/no-authn-v1.json. There are three main configuration changes:

// /opt/tyk-gateway/apps/no-authn-v1.json

  "proxy": {
    "preserve_host_header": false,
    "listen_path": "/api/v1/no-authn",
    "target_url": "",                  // (1) 改为""
    "disable_strip_slash": false,
    "strip_listen_path": true,
    "enable_load_balancing": true,     // (2) 改为true
    "target_list": [                   // (3) 填写no-authn服务实例列表
      "http://localhost:18081/",
      "http://localhost:18082/",
      "http://localhost:18083/"
    ],
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

After modifying the configuration, call Tyk's control API to make it effective, and then we start three no-authn API instances:

$go run main.go -p 18081 -v v1 -n no-authn
$go run main.go -p 18082 -v v1 -n no-authn
$go run main.go -p 18083 -v v1 -n no-authn
  • 1.
  • 2.
  • 3.

Next, we call curl multiple times to access the no-authn API:

$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18081/v1/no-authn
$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18082/v1/no-authn
$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18083/v1/no-authn

$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18081/v1/no-authn
$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18082/v1/no-authn
$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18083/v1/no-authn
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

We see that Tyk Gateway performs equal-weighted polling between each instance of the no-authn API. If we stop instance 3 and access the API again, we will get the following results:

$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18081/v1/no-authn
$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18082/v1/no-authn
$curl localhost:8080/api/v1/no-authn
Bad Request

$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18081/v1/no-authn
$curl localhost:8080/api/v1/no-authn
Welcome api: localhost:18082/v1/no-authn
$curl localhost:8080/api/v1/no-authn
Bad Request
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

Note: Tyk Gateway commercial version supports configuring the weighted RR load balancing algorithm through Dashboard [24] .

We see that instance 3 has been offline, but Tyk Gateway will not skip the offline instance, which will bring inconsistent responses to the client in the production environment.

3.3.3 Service instance survival test (uptime test)

When turning on load balancing, Tyk Gateway also provides a survival detection mechanism for back-end service instances. When a service instance goes down, the load balancing mechanism will bypass the instance and send the request to the next alive instance. ; When the down machine instance is restored, Tyk Gateway can also promptly detect that the service instance comes online and add it to traffic load scheduling.

The API definition configuration that supports uptime test is as follows:

// /opt/tyk-gateway/apps/no-authn-v1.json

"uptime_tests": {
    "disable": false,
    "poller_group":"",
    "check_list": [
      {
        "url": "http://localhost:18081/"
      },
      {
        "url": "http://localhost:18082/"
      },
      {
        "url": "http://localhost:18083/"
      }
    ],
    "config": {
      "enable_uptime_analytics": true,
      "failure_trigger_sample_size": 3,
      "time_wait": 300,
      "checker_pool_size": 50,
      "expire_utime_after": 0,
      "service_discovery": {
        "use_discovery_service": false,
        "query_endpoint": "",
        "use_nested_query": false,
        "parent_data_path": "",
        "data_path": "",
        "port_data_path": "",
        "target_path": "",
        "use_target_list": false,
        "cache_disabled": false,
        "cache_timeout": 0,
        "endpoint_returns_list": false
      },
      "recheck_wait": 0
    }
}

"proxy": {
    ... ...
    "enable_load_balancing": true,
    "target_list": [
      "http://localhost:18081/",
      "http://localhost:18082/",
      "http://localhost:18083/"
    ],
    "check_host_against_uptime_tests": true,
    ... ...
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • twenty one.
  • twenty two.
  • twenty three.
  • twenty four.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.

We have added the configuration of uptime_tests. The value of the url in the check_list of uptime_tests must be exactly the same as the value in the target_list of the proxy, so that Tyk Gateway can match the two. In addition, the proxy's check_host_against_uptime_tests must be set to true.

After this configuration takes effect, after we stop service instance 3, subsequent requests to no-authn will only be forwarded to instance 1 and instance 2. When instance 3 is restored, Tyk Gateway will allocate traffic to instance 3.

3.3.4 Dynamic load balancing

In the above load balancing example, the IP and port of the target instance in the target_list are manually configured. In the cloud native era, we often host API service instances based on containers. When the container exits for some reason and restarts a new container, the IP Changes may occur, so that the above manual configuration cannot meet the requirements, which puts forward the requirement for API Gateway to integrate with the service discovery component: dynamically obtain the access list of service instances through the service discovery component, thereby achieving dynamic load balancing [25] .

Tyk Gateway has built-in docking capabilities for mainstream service discovery components (such as Etcd, Consul, ZooKeeper, etc.). In view of the limitations of the environment, we will not give examples here. You can find different services on the service discovery example document page of Tyk Gateway [26] Discover configuration examples when connecting components.

3.3.5 IP access restrictions

For each API, the API gateway also provides IP access restriction features. For example, Tyk Gateway provides IP whitelist [27] and IP blacklist [28] functions. Usually, you can choose one of the two to enable one restriction.

Take the whitelist as an example, that is, only IPs in the whitelist are allowed to access the API. The following is a sample whitelist configuration:

// /opt/tyk-gateway/apps/no-authn-v1.json

  "enable_ip_whitelisting": true,
  "allowed_ips": ["12.12.12.12", "12.12.12.13", "12.12.12.14"],
  • 1.
  • 2.
  • 3.
  • 4.

After taking effect, when we access the no-authn API, we will get the following error:

$curl localhost:8080/api/v1/no-authn
{
    "error": "access from this IP has been disallowed"
}
  • 1.
  • 2.
  • 3.
  • 4.

If the blacklist is enabled, all IPs in the blacklist will be prohibited from accessing the API. The following is a blacklist configuration example:

// /opt/tyk-gateway/apps/no-authn-v1.json

  "enable_ip_blacklisting": true,
  "blacklisted_ips": ["12.12.12.12", "12.12.12.13", "12.12.12.14", "127.0.0.1"],
  • 1.
  • 2.
  • 3.
  • 4.

After taking effect, when we access the no-authn API, we will get the following results:

$curl 127.0.0.1:8080/api/v1/no-authn
{
    "error": "access from this IP has been disallowed"
}
  • 1.
  • 2.
  • 3.
  • 4.

So far, our API gateway and defined APIs are in a "streaking" state, because there is no authentication of the client, and any client can access our API. Obviously this is not what we expect. Next, we Let’s take a look at an important feature of API gateway: identity authentication and authorization.

3.4 Functional features: identity authentication and authorization

In the article " Understanding Several Methods of Go Web Identity Authentication through Examples [29] ", we mentioned that establishing a global secure channel is the prerequisite for any identity authentication method .

3.4.1 Establish a secure channel and uninstall the TLS certificate

Tyk Gateway supports unified configuration of TLS certificates at the Gateway level [30] , and also plays the role of uninstalling TLS certificates at the Gateway:

picturepicture

This time we need to configure it in tyk.conf to take effect at the Gateway level. Here we borrow several certificates generated in the article " Understanding Several Methods of Go Web Identity Authentication through Examples [31] " (you can download it at https://github.com/bigwhite/experiments/tree/master/authn-examples/ tls-authn/make_certs download) and put them under /opt/tyk-gateway/certs/:

$ls /opt/tyk-gateway/certs/
server-cert.pem  server-key.pem
  • 1.
  • 2.

Then, we add the following configuration to the /opt/tyk-gateway/tyk.conf file:

// /opt/tyk-gateway/tyk.conf 

  "http_server_options": {
    "use_ssl": true,
    "certificates": [
      {
        "domain_name": "server.com",
        "cert_file": "./certs/server-cert.pem",
        "key_file": "./certs/server-key.pem"
      }
    ]
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

After that, restart the tyk gateway service to make the configuration changes in tyk.conf take effect.

Note: Set server.com to 127.0.0.1 in /etc/hosts.

Now we use the previous http method to access the no-authn API:

$curl server.com:8080/api/v1/no-authn
Client sent an HTTP request to an HTTPS server.
  • 1.
  • 2.

Since HTTPS is enabled globally, requests using http will be rejected. Let’s switch to https access:

// 不验证服务端证书
$curl -k https://server.com:8080/api/v1/no-authn
Welcome api: localhost:18081/v1/no-authn

// 验证服务端的自签证书
$curl --cacert ./inter-cert.pem https://server.com:8080/api/v1/no-authn
Welcome api: localhost:18081/v1/no-authn
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

3.4.2 Mutual TLS two-way authentication

In the article " Understanding Several Methods of Go Web Identity Authentication through Examples [32] ", the first identity authentication method we introduced is TLS two-way authentication. So how does Tyk Gateway support MTLS? Tyk official documentation [33] mentions that it supports both client mTLS [34] and upstream mTLS [35] .

What we are more concerned about is client mTLS, that is, after the client establishes a connection with Gateway, Gateway will use Client CA to verify the client's certificate! I initially thought that the Client CA configuration was in tyk.conf, but after searching for a long time, I couldn't find the place to configure the Client CA.

In the no-authn API definition file (no-authn-v1.json), we make the following configuration changes:

"use_mutual_tls_auth": true,
  "client_certificates": [
      "/opt/tyk-gateway/certs/inter-cert.pem"
  ],
  • 1.
  • 2.
  • 3.
  • 4.

But when I use the following command to access the API, I get an error:

$curl --key ./client-key.pem --cert ./client-cert.pem --cacert ./inter-cert.pem https://server.com:8080/api/v1/no-authn
{
    "error": "Certificate with SHA256 bc8717c0f2ea5a0b81813abb3ec42ef8f9bf60da251b87243627d65fb0e3887b not allowed"
}
  • 1.
  • 2.
  • 3.
  • 4.

If you change the inter-cert.pem in the "client_certificates" configuration to client-cert.pem, it is ok, but personally I feel this is strange and illogical. I have read the tyk gateway documents, issues and even codes over and over again. I looked through it and couldn't find a reasonable location to configure the client CA.

Tyk Gateway supports multiple identity authentication methods [36] . Let’s look at one of the more widely used methods: JWT Auth.

For the principles and details of the main JWT identity authentication method, you can refer to my previous article " Understanding Several Methods of Go Web Identity Authentication through Examples [37] ".

3.4.3 JWT Token Auth

Here's a diagram I made for this example:

picturepicture

This is a scenario we often encounter in daily development. That is, after logging in with a username and password through the portal, you can get a jwt token, and then subsequent requests to access the functional API only carry the jwt token. API Gateway does not perform any identity authentication for the portal/login API; for subsequent functional API requests, the jwt token carried in the request is signed and verified through the shared secret (also called static secret).

Since the portal/login API does not perform authn, its configuration is almost the same as the previous no-authn API, except that the API name, path and target_list are different:

// apps/portal-login-v1.json

{
  "name": "portal-login-v1",
  "slug": "portal-login-v1",
  "listen_port": 0,
  "protocol": "",
  "enable_proxy_protocol": false,
  "api_id": "portal-login-v1",
  "org_id": "1",
  "use_keyless": true,
  ... ...
  "proxy": {
    "preserve_host_header": false,
    "listen_path": "/api/v1/portal/login",
    "target_url": "",
    "disable_strip_slash": false,
    "strip_listen_path": true,
    "enable_load_balancing": true,
    "target_list": [
      "http://localhost:28084"
    ],
    "check_host_against_uptime_tests": true,
  ... ... 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • twenty one.
  • twenty two.
  • twenty three.
  • twenty four.
  • 25.

The corresponding portal login API is not complicated either:

// api-gateway-examples/portal-login/main.go

package main

import (
 "log"
 "net/http"
 "time"

 "github.com/golang-jwt/jwt/v5"
)

func main() {
 // 创建一个基本的HTTP服务器
 mux := http.NewServeMux()

 username := "admin"
 password := "123456"
 key := "iamtonybai"

 // for uptime test
 mux.HandleFunc("/health", func(w http.ResponseWriter, req *http.Request) {
  w.WriteHeader(http.StatusOK)
 })

 // login handler
 mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
  // 从请求头中获取Basic Auth认证信息
  user, pass, ok := req.BasicAuth()
  if !ok {
   // 认证失败
   w.WriteHeader(http.StatusUnauthorized)
   return
  }

  // 验证用户名密码
  if user == username && pass == password {
   // 认证成功,生成token
   token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
    "username": username,
    "iat":      jwt.NewNumericDate(time.Now()),
   })
   signedToken, _ := token.SignedString([]byte(key))
   w.Write([]byte(signedToken))
  } else {
   // 认证失败
   http.Error(w, "Invalid username or password", http.StatusUnauthorized)
  }
 })

 // 监听28084端口
 err := http.ListenAndServe(":28084", mux)
 if err != nil {
  log.Fatal(err)
 }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • twenty one.
  • twenty two.
  • twenty three.
  • twenty four.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.

After running the login API service, we use the curl command to obtain the jwt token:

$curl -u 'admin:123456' -k https://server.com:8080/api/v1/portal/login
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MDA3NTEyODEsInVzZXJuYW1lIjoiYWRtaW4ifQ.-wC8uPsLHDxSXcEMxIxJ8O2l3aWtWtWKvhtmuHmgIMA
  • 1.
  • 2.

Now let's create a protected API:

// apps/protected-v1.json

{
  "name": "protected-v1",
  "slug": "protected-v1",
  "listen_port": 0,
  "protocol": "",
  "enable_proxy_protocol": false,
  "api_id": "protected-v1",
  "org_id": "1",
  "use_keyless": false,    // 设置为false, gateway才会进行jwt的验证
  ... ...
  "enable_jwt": true,      // 开启jwt
  "use_standard_auth": false,
  "use_go_plugin_auth": false,
  "enable_coprocess_auth": false,
  "custom_plugin_auth_enabled": false,
  "jwt_signing_method": "hmac",        // 设置alg为hs256
  "jwt_source": "aWFtdG9ueWJhaQ==",    // 设置共享secret: base64("iamtonybai")
  "jwt_identity_base_field": "username", // 设置代表请求中的用户身份的字段,这里我们用username
  "jwt_client_base_field": "",
  "jwt_policy_field_name": "",
  "jwt_default_policies": [
     "5e189590801287e42a6cf5ce"        // 设置security policy,这个似乎是jwt auth必须的
  ],
  "jwt_issued_at_validation_skew": 0,
  "jwt_expires_at_validation_skew": 0,
  "jwt_not_before_validation_skew": 0,
  "jwt_skip_kid": false,
  ... ...
  "version_data": {
    "not_versioned": true,
    "default_version": "",
    "versions": {
      "Default": {
        "name": "Default",
        "expires": "",
        "paths": {
          "ignored": null,
          "white_list": null,
          "black_list": null
        },
        "use_extended_paths": true,
        "extended_paths": {
          "persist_graphql": null
        },
        "global_headers": {
          "username": "$tyk_context.jwt_claims_username" // 设置转发到upstream的请求中的header字段username
        },
        "global_headers_remove": null,
        "global_response_headers": null,
        "global_response_headers_remove": null,
        "ignore_endpoint_case": false,
        "global_size_limit": 0,
        "override_target": ""
      }
    }
  },
  ... ...
  "enable_context_vars": true, // 开启上下文变量
  "config_data": null,
  "config_data_disabled": false,
  "tag_headers": ["username"], // 设置header
  ... ...
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • twenty one.
  • twenty two.
  • twenty three.
  • twenty four.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.

This configuration is relatively complex, and it took a long time to review the information before verifying it. JWT Auth must have associated policy settings. If we want to set the policy in the tyk gateway open source version, we need to make the following settings in tyk.conf:

// /opt/tyk-gateway/tyk.conf

  "policies": {
    "policy_source": "file",
    "policy_record_name": "./policies/policies.json"
  },
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

The contents of policies/policies.json are as follows:

// /opt/tyk-gateway/policies/policies.json
{
 "5e189590801287e42a6cf5ce": {
  "rate": 1000,
  "per": 1,
  "quota_max": 100,
  "quota_renewal_rate": 60,
  "access_rights": {
   "protected-v1": {
    "api_name": "protected-v1",
    "api_id": "protected-v1",
    "versions": [
     "Default"
    ]
   }
  },
  "org_id": "1",
  "hmac_enabled": false
 }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

After the above settings are completed and the tyk gateway is restarted to take effect, and the protected api service has been started, we access the API service:

$curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MDA3NTEyODEsInVzZXJuYW1lIjoiYWRtaW4ifQ.-wC8uPsLHDxSXcEMxIxJ8O2l3aWtWtWKvhtmuHmgIMA" -k https://server.com:8080/api/v1/protected
invoke protected api ok
  • 1.
  • 2.

We see that the request sent by curl successfully passed Gateway verification! And judging from the request information output by the protected API, Gateway successfully parsed the username and passed it to the protected API service instance as a field in the Header:

http.Request{Method:"GET", URL:(*url.URL)(0xc0002f6240), Proto:"HTTP/1.1", ProtoMajor:1, ProtoMinor:1, Header:http.Header{"Accept":[]string{"*/*"}, "Accept-Encoding":[]string{"gzip"}, "Authorization":[]string{"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MDA3NTEyODEsInVzZXJuYW1lIjoiYWRtaW4ifQ.-wC8uPsLHDxSXcEMxIxJ8O2l3aWtWtWKvhtmuHmgIMA"}, "User-Agent":[]string{"curl/7.29.0"}, "Username":[]string{"admin"}, "X-Forwarded-For":[]string{"127.0.0.1"}}, Body:http.noBody{}, GetBody:(func() (io.ReadCloser, error))(nil), ContentLength:0, TransferEncoding:[]string(nil), Close:false, Host:"localhost:28085", Form:url.Values(nil), PostForm:url.Values(nil), MultipartForm:(*multipart.Form)(nil), Trailer:http.Header(nil), RemoteAddr:"[::1]:55583", RequestURI:"/", TLS:(*tls.ConnectionState)(nil), Cancel:(<-chan struct {})(nil), Response:(*http.Response)(nil), ctx:(*context.cancelCtx)(0xc0002e34f0)}
  • 1.

If the token that does not carry the Authorization header field or jwt is an error, the result will be as follows:

$ curl -k https://server.com:8080/api/v1/protected
{
    "error": "Authorization field missing"
}

$ curl -k -H "Authorization: Bearer xxx" https://server.com:8080/api/v1/protected
{
    "error": "Key not authorized"
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

Once the identity authentication of API Gateway is passed, the upstream API service will obtain the client identity. With the unique identity, authorization operations can be performed [38] . In fact, the policy setting itself is also a kind of authorized access control. Tyk Gateway itself also supports RBAC and other models [39] , and also supports integration with OPA (open policy agent), etc., but it is mostly completed under the commercial version of tyk dashboard, so I will not focus on it here.

Due to the limited test environment and the length of the article, I will not explain the following main functional features of Gateway in as much detail as the above examples, but will only briefly explain them.

3.5 Functional features: flow control and speed limit

Tyk Gateway provides powerful built-in traffic control functions, which can manage request traffic through global-level and API-level rate limits [40] . In addition, Tyk Gateway also supports request quota [41] to limit the number of requests for each user or application within a time period.

Traffic is not only related to the request speed and quantity, but also to the size of the request. Tyk Gateway also supports setting the Request size limit [42] at the global level and API level to avoid adverse effects of oversized packets on the gateway operation.

3.6 Functional Features: High Availability and Fault Tolerance

In many cases, we need to ensure service levels for customers, such as maximum round-trip time, maximum response delay, etc. Tyk Gateway provides a series of features that help us ensure high-availability operation and SLA service levels of the gateway.

Tyk supports health check [43] , which is extremely important for determining the status of Tyk Gateway. Without health check, it is difficult to know the actual operating status of the gateway.

Tyk Gateway also has a built-in circuit breaker (circuit breaker) [44] . This circuit breaker is based on proportion, so if x requests out of y requests fail, the circuit breaker will trip. For example, if x = 10, y = 100, then the threshold percentage is 10%. When the failure rate reaches 10%, the circuit breaker will cut off the flow, and the trip will also trigger an event, which we can record and process.

When the upstream service response is delayed, Tyk Gateway can also set a mandatory timeout [45] to ensure that the service always responds within a given time. This is important in high-availability systems, where responsiveness is critical so that errors can be handled cleanly.

3.7 Features: Monitoring and Observability

In the era of microservices, the importance of observability to operation and maintenance and system high availability is self-evident. In the course of many years of evolution, Tyk Gateway has gradually added support for observability.

Observables are mainly divided into three parts:

  • log

Tyk Gateway supports setting the output log level (log level), and the default is info level. Tyk outputs structured logs, which makes it well integrated with other log collection and query systems. Tyk supports docking with mainstream log collection tools [46] , including: logstash, sentry, Graylog, Syslog, etc.

  • metrics

Metrics data are an important reference for hardware resource data reflecting gateway system health, error counts and types, IT infrastructure (servers, virtual machines, containers, databases and other back-end components) and other processes. Operations teams can leverage real-time measured data through the use of monitoring tools [47] to identify operational trends, set alerts in the event of system failures, determine the root cause of problems, and mitigate problems.

Tyk Gateway has built-in support for the mainstream metrics collection solution Prometheus+Grafana [48] , which can collect and display real-time metric data at the gateway level and API.


  • tracing

Starting from version 5.2, Tyk Gateway supports integration with the standard in the service tracing industry: OpenTelemetry [49] , so that you can use a variety of Tracing backends that support OpenTelemetry, such as Jaeger, Datadog, etc. Tracing can be enabled at the Gateway level or extended to the API level.

4. Summary

This article reviews the relatively mature API gateway technology, briefly explains the evolution stage, mainstream features of API gateways, and the mainstream API gateways currently on the market, and takes the Tyk Gateway community open source version implemented in Go as an example. The method introduces the main functions of API gateway.

Overall, Tyk Gateway is a product with powerful functions, a relatively active community and support from commercial companies. The documentation is very rich, but in terms of actual use, these documents are not friendly and instructive for users of the Tyk community version. Shortcomings (more explanations are given using the commercial version of the Dashboard, which is difficult to correspond to the configuration files). Just like in the example in this article, in order to get the JWT authentication, the author really spent a lot of time checking the information and even reading the source code.

The configuration design of Tyk Gateway is flat, without hierarchy and logic, and it feels like it has been "stacked" randomly over time. And when the configuration file is updated, if there is a format problem, Tyk Gateway does not report an error, making it difficult to determine whether the configuration has actually taken effect. You can only use Tyk Gateway's control API [50] to query the results for verification, which is very cumbersome and inefficient.

The source code involved in this article can be downloaded here [51] , and some of the tyk gateway api and security policy configurations involved in the article can also be viewed there.

5. References

  • Leaving the Cloud [52]  - https://37signals.com/podcast/leaving-the-cloud/
  • The Past, Present, and Future of API Gateways [53]  - https://www.infoq.com/articles/past-present-future-api-gateways/
  • How moving from AWS to Bare-Metal saved us 230,000/yr [54]  - https://blog.oneuptime.com/moving-from-aws-to-bare-metal/
  • A Comprehensive Guide to API Gateways, Kubernetes Gateways, and Service Meshes [55]  - https://navendu.me/posts/gateway-and-mesh/
  • Use API gateways in microservices [56]  - https://learn.microsoft.com/en-us/azure/architecture/microservices/design/gateway
  • The Tyk API Gateway and Postman [57]  - https://blog.postman.com/the-tyk-api-gateway-and-postman/
  • Getting Started with Tyk API Gateway with Keycloak [58]  - https://javascript.plainenglish.io/getting-started-to-tyk-api-gateway-with-keycloak-16307435584a
  • Observing your API traffic with Tyk, Elasticsearch & Kibana [59]  - https://medium.com/@asoorm/observing-your-api-metrics-with-tyk-elasticsearch-kibana-74e8fd946c39
  • Set up JWT token in tyk gateway [60]  - https://community.tyk.io/t/set-up-jwt-token-in-tyk-gateway/6572/9


References

[1]  David Heinemeier Hansson: https://dhh.dk/ 

[2] Moved all the company’s business from public cloud to self-built data center: https://37signals.com/podcast/leaving-the-cloud/  

[3] Exists in the form of a monolithic application: https://tonybai.com/2023/10/09/service-weaver-coding-in-monolithic-deploy-in-microservices/  

[4] CNCF Landscape: https://https://landscape.cncf.io  

[5] Amazon’s API Gateway: https://aws.amazon.com/cn/api-gateway/  

[6] Google Cloud’s API Gateway: https://cloud.google.com/api-gateway  

[7] APISIX: https://apisix.apache.org/  

[8] Kong: https://konghq.com/  

[9] EMISSARY INGRESS: https://github.com/emissary-ingress/emissary  

[10] Tyk API Gateway: https://tyk.io/blog/res-api-management-vendor-comparisons/  

[11] It does not mean that Tyk API Gateway is better than other API Gateways implemented in Go: https://tyk.io/blog/enter-the-leader-tyk-recognised-as-a-leader-in-gartners-2023 -magic-quadrant-for-api-management/  

[12] Tyk API Gateway: https://github.com/TykTechnologies/tyk  

[13] Open Core mode open source: https://opensource.com/article/21/11/open-core-vs-open-source  

[14] Open source and commercial API management and gateway solution: https://tyk.io/docs/tyk-oss-gateway/  

[15] docker-compose: https://tonybai.com/2021/11/26/build-all-in-one-runtime-environment-with-docker-compose  

[16] Kubernetes Operator: https://tonybai.com/2022/08/15/developing-kubernetes-operators-in-go-part1  

[17] Function details of the open source version of Tyk API Gateway: https://tyk.io/docs/tyk-oss-gateway/  

[18] Use CentOS’s yum package management tool to install Tyk API gateway: https://tyk.io/docs/tyk-oss/ce-redhat-rhel-centos/  

[19] systemd daemon service: https://tonybai.com/2016/12/27/when-docker-meets-systemd/  

[20] Call Tyk’s control API: https://tyk.io/docs/getting-started/create-api/#tutorial-create-an-api-with-the-tyk-gateway-api  

[21] Through traditional configuration files, put them in a specific directory: https://tyk.io/docs/getting-started/create-api/#tutorial-create-an-api-in-file-based-mode  

[22] API definition file: https://tyk.io/docs/tyk-gateway-api/api-definition-objects/  

[23] Request traffic load balancing: https://tyk.io/docs/planning-for-production/ensure-high-availability/load-balancing/  

[24] Supports configuring weighted RR load balancing algorithm: https://tyk.io/docs/planning-for-production/ensure-high-availability/load-balancing/  

[25] Dynamic load balancing: https://tyk.io/docs/planning-for-production/ensure-high-availability/service-discovery/  

[26] Service discovery example documentation page: https://tyk.io/docs/planning-for-production/ensure-high-availability/service-discovery/examples/  

[27] IP whitelisting: https://tyk.io/docs/tyk-apis/tyk-gateway-api/api-definition-objects/ip-whitelisting/  

[28] IP blacklist: https://tyk.io/docs/tyk-apis/tyk-gateway-api/api-definition-objects/ip-blacklisting/  

[29] Understand several methods of Go Web identity authentication through examples: https://tonybai.com/2023/10/23/understand-go-web-authn-by-example  

[30] Unified configuration of TLS certificates: https://tyk.io/docs/basic-config-and-security/security/tls-and-ssl/  

[31] Understand several methods of Go Web identity authentication through examples: https://tonybai.com/2023/10/23/understand-go-web-authn-by-example/  

[32] Understand several methods of Go Web identity authentication through examples: https://tonybai.com/2023/10/23/understand-go-web-authn-by-example  

[33] Tyk official documentation: https://tyk.io/docs/basic-config-and-security/security/mutual-tls/  

[34] client mTLS: https://tyk.io/docs/basic-config-and-security/security/mutual-tls/client-mtls  

[35] upstream mTLS: https://tyk.io/docs/basic-config-and-security/security/mutual-tls/upstream-mtls  

[36] Tyk Gateway supports multiple identity authentication methods: https://tyk.io/docs/apim-best-practice/api-security-best-practice/authentication/  

[37] Understand several methods of Go Web identity authentication through examples: https://tonybai.com/2023/10/23/understand-go-web-authn-by-example/  

[38] Authorization operation: https://tonybai.com/2023/11/04/understand-go-web-authz-by-example/  

[39] Support models such as RBAC: https://tyk.io/docs/tyk-dashboard/rbac/#understanding-the-concept-of-users-and-permissions  

[40] Global level and API level rate limiting: https://tyk.io/docs/basic-config-and-security/control-limit-traffic/rate-limiting/  

[41] Support request quota: https://tyk.io/docs/basic-config-and-security/control-limit-traffic/request-quotas/  

[42] Set Request size limit: https://tyk.io/docs/basic-config-and-security/control-limit-traffic/request-size-limits/  

[43] Tyk supports health check: https://tyk.io/docs/planning-for-production/ensure-high-availability/health-check/  

[44] Built-in circuit breaker: https://tyk.io/docs/planning-for-production/ensure-high-availability/circuit-breakers/  

[45] Set enforced timeouts: https://tyk.io/docs/planning-for-production/ensure-high-availability/enforced-timeouts/  

[46] Tyk supports docking with mainstream log collection tools: https://tyk.io/docs/log-data/#logging  

[47] Use monitoring tools to leverage real-time metric data: https://tyk.io/docs/planning-for-production/monitoring/  

[48] ​​Support for mainstream metrics collection solution Prometheus+Grafana: https://tyk.io/blog/service-level-objectives-for-your-apis-with-tyk-prometheus-and-grafana/  

[49] Supports integration with OpenTelemetry, a standard in the service tracing community: https://tyk.io/docs/product-stack/tyk-gateway/advanced-configurations/distributed-tracing/open-telemetry/open-telemetry- overview/  

[50] Tyk Gateway control API: https://tyk.io/docs/tyk-gateway-api/  

[51] Here: https://github.com/bigwhite/experiments/tree/master/api-gateway-examples  

[52] Leaving the Cloud: https://37signals.com/podcast/leaving-the-cloud/  

[53] The Past, Present, and Future of API Gateways: https://www.infoq.com/articles/past-present-future-api-gateways/  

[54] How moving from AWS to Bare-Metal saved us 230,000/yr: https://blog.oneuptime.com/moving-from-aws-to-bare-metal/  

[55] A Comprehensive Guide to API Gateways, Kubernetes Gateways, and Service Meshes: https://navendu.me/posts/gateway-and-mesh/  

[56] Use API gateways in microservices: https://learn.microsoft.com/en-us/azure/architecture/microservices/design/gateway  

[57] The Tyk API Gateway and Postman: https://blog.postman.com/the-tyk-api-gateway-and-postman/  

[58] Getting Started with Tyk API Gateway with Keycloak: https://javascript.plainenglish.io/getting-started-to-tyk-api-gateway-with-keycloak-16307435584a  

[59] Observing your API traffic with Tyk, Elasticsearch & Kibana: https://medium.com/@asoorm/observing-your-api-metrics-with-tyk-elasticsearch-kibana-74e8fd946c39  

[60] Set up JWT token in tyk gateway: https://community.tyk.io/t/set-up-jwt-token-in-tyk-gateway/6572/9  

[61] “Gopher Tribe” Knowledge Planet: https://public.zsxq.com/groups/51284458844544  

[62] Link address: https://m.do.co/c/bff6eed92687