Non HTTP Protocol
Last updated: 13 minutes read.
Overview
Tyk primarily focuses on the HTTP/HTTPS protocol for handling and modeling traffic. However, with the growing popularity of WebSocket- and gRPC-based APIs, Tyk also supports transparent proxying for both TLS and non-TLS connections.
gRPC Proxy
Using Tyk as a gRPC Proxy
Tyk supports gRPC passthrough proxying when using HTTP/2 as a transport (the most common way to deploy gRPC services).
The gRPC over HTTP2 specification defines the rules on how the gRPC protocol maps to a HTTP request, for more information see. In the context of the API Gateway, we are interested in the following:
- You can target specific methods of the gRPC service using the format:
/{Service-Name}/{method name}
, for example:/google.pubsub.v2.PublisherService/CreateTopic
. You can use this feature to apply standard ACL rules via Keys and Policies, or use URL rewrite plugins in our Endpoint Desiger. - HTTP method is always
POST
. gRPC custom request metadata is added as HTTP headers, where metadata key is directly mapped to the HTTP header with the same name.
You can also perform gRPC load balancing.
Prerequisites
- Enable HTTP/2 support on the Gateway side, for both incoming and upstream connections, by setting
http_server_options.enable_http2
andproxy_enable_http2
to true in yourtyk.conf
Gateway config file. - The
listen path
of the Api should be the same as the gRPC service name, so tyk can route it correctly. - Ensure that
strip_listen_path
is set to false in your API, so the route of the gRPC service method is build correctly following the standard:{service_name}/{service_method}
.
Secure gRPC Proxy
Tyk Supports secure gRPC proxy connections, in order to do so you only need to attach a certificate to the API that you want to expose just as you do for regular APIs, after that you can consume the service via HTTPS.
Insecure gRPC Proxy (H2C)
For scenarios where you want to connect two services calling each other or just need an insecure connection you can use h2c (that is the non-TLS version of HTTP/2). Tyk supports h2c, this can be enabled at api level by setting h2c
as protocol in the address of the gRPC server (target_url
) e.g: h2c://my-grpc-server.com
.
gRPC streaming
Tyk supports all kinds of gRPC streaming (client streaming, server streaming and bidirectional streaming). It requires you to set a low value for flush_interval
, this is required in order to forward data to the downstream target as soon as the upstream target replies. A high flush interval will delay this communication. We recommend the lowest possible value: 1 (1 millisecond). You set this value in your tyk.conf
file in the http_server_options.flush_interval
option.
Mutual Authentication
Tyk supports Mutual Authentication in gRPC. See Mutual TLS to configure Mutual Authentication in Tyk.
Basic Authentication
Tyk supports Basic Authentication in gRPC. See Basic Authentication to configure Basic Authentication in Tyk.
After setting your Tyk configuration, all you need to do is to send credentials with the correct base64 format in an Authorization
header from your gRPC client.
Basic base64Encode(username:password)
Token Based Authentication
Tyk supports Token Based Authentication in gRPC. See Bearer Tokens to configure Token Based Authentication in Tyk.
After setting your Tyk configuration, all you need to do is to send a token in an Authorization
header from your gRPC client.
gRPC load balancing
Tyk is able to perform load balancing on gRPC traffic using an approach similar to our native Load Balancing functionality.
For both secure and insecure gRPC scenarios, the steps above serve as a starting point.
In a secure gRPC scenario
For configuring multiple upstream targets in a secure gRPC scenario, follow these additional steps:
- Check the “Enable round-robin load balancing” flag in the “Core Settings” section of your API.
- Define each target as
https://grpc.test.example.com:10000
,https://grpc.test.example.com:10001
and so on.
In an insecure scenario (H2C)
Use the same approach but use the H2C scheme instead: h2c://grpc.test.example.com:10000
, h2c://grpc.test.example.com:10001
, etc.
Example of gRPC proxy using H2C
This is the simplest way to have a working gRPC proxy setup. You will need:
- A gRPC server. For this example you can use this server
- A gRPC client. You can use grpcurl which is basically curl but for gRPC
- An instance of the Tyk Gateway and Dashboard
Steps for Configuration:
- Execute the gRPC server (for this example you can expose it at port
:50051
) - Create the API via the Tyk dashboard with the following configuration:
- Set HTTP as protocol
- Uncheck
strip listen path
in the api - Set listen path:
/helloworld.Greeter
- Now set the
target_url
. In order for Tyk to detect that you will useh2c
for this API we will need to write the URL with the prefixh2c://
. For this example the URL can beh2c://localhost:50051
- Hit save, and once the Gateway finishes reloading you can test the solution
- From the command line you can consume the service via the Tyk Gateway. To test it, enter
grpcurl -plaintext -proto helloworld.proto -d '{"name": "joe"}' tyk-gateway:8080 helloworld.Greeter/SayHello
and you should get as a response:{"message": "Hello joe"}
which means that everything is working as it should.
Example of gRPC proxy using HTTPS
Prerequisites:
- a gRPC server. For this example you can use this server as this example already supports TLS.
- A gRPC client. You can use grpcurl which is basically curl but for gRPC (or you can use the client application)
- A certificate to expose the API via HTTPS
- An instance of Tyk Gateway and Dashboard
Steps for Configuration:
- Execute the gRPC server (for this example we can expose it at port
:10000
), theroute_guide
application receives a flag to use TLS (go run server.go -tls=true
). It’s exposed ingrpc.test.example.com:10000
- Create the API via dashboard with the next configuration:
- Set HTTPS as protocol
- Uncheck
Strip listen path
in the api - Add the certificate
- Set a custom domain, for this example use
tyk
- Set as listen path:
/routeguide.RouteGuide
- Now in the target URL set the location of the service:
https://grpc.test.example.com:10000
- Click Save
- At this point you’re ready to test the solution, so, from the command line type:
grpcurl -proto route_guide.proto -d '{"latitude": 1, "longitude":2}' tyk:8080 routeguide.RouteGuide/GetFeature
and you should get a successful response. Note that you are not sending the flag-plaintext
as the desire is to connect via HTTPS.
Example of bidirectional data streaming using a gRPC service exposed via HTTPS but communicating Tyk to service via H2C
In this example you will expose a gRPC service via HTTPS using Tyk, but Tyk will consume the upstream via h2c. This situation is very common when using Kubernetes, where the internet traffic going through Tyk are TLS encrypted, but traffic in the inner cluster are in plain HTTP (h2c).
Prerequisites
- a gRPC server. For this example you can use this server.
- a client application. You can use this client.
- A certificate to expose the API via HTTPS
- An instance of the Tyk Gateway and Dashboard.
Steps for Configuration:
- Execute the gRPC server (for this example expose it at port
:10000
), theroute_guide
application receives a flag to enable/disable TLS (go run server.go -tls=false
). It’s available inlocahost:10000
- In the Tyk Gateway config file set
"http_server_options.flush_interval": 1
and run the Gateway (for this example will be running it in port 8000). - Create the API via the Tyk Dashboard with the following configuration:
- Set HTTPS as the protocol
- Add the certificate
- Set a custom domain, for this example
tyk
- Set as listen path:
/routeguide.RouteGuide
. For testing purposes we will use theRouteChat
service as this is a bidirectional service. - Now in the target URL set the location of the service:
h2c://localhost:10000
. This way Tyk will communicate with the upstream using h2c - Click Save
- Ensure that the client application has the server address pointing to Tyk, for this example:
https://tyk.com:8000
. - Now you are ready to test the solution. Run the client application and it should send and receive data simultaneously.
Currently load balancing is not supported for gRPC.
TCP Proxy
Using Tyk as a TCP Proxy
Tyk can be used as a reverse proxy for your TCP services. It means that you can put Tyk not only on top of your APIs but on top of any network application, like databases, services using custom protocols etc.
Set via your API
To enable TCP proxying, set the protocol
field either to tcp
or tls
. In the case of TLS, you can also specify a certificate
field with a certificate ID or path to it.
Similar to the above, the proxy target scheme should be set to tcp://
or tls://
, depending if your upstream is secured by TLS or not.
The simplest TCP API definition looks like this:
{
"listen_port": 30001,
"protocol": "tls",
"certificate": ["<cert-id>"],
"proxy": {
"target_url": "tls://upstream:9191"
}
}
Set via your Dashboard
From the API Designer > Core Settings tab, select the appropriate protocol from the Protocol field drop-down list.
Enter the network port number in the Port field.
If using TLS you can also add a PEM formatted SSL certificate in the Upstream Certificates section from the Advanced Options tab.
Tyk supports multiplexing based on certificate SNI information, which means that you can have multiple TCP services on the same port, served on different domains. Additionally, all services on the same port should share the same protocol: either tcp
, tls
, http
or https
.
If Tyk sits behind another proxy, which has the PROXY protocol enabled, you can set enable_proxy_protocol
to true
.
As for features such as load balancing, service discovery, Mutual TLS (both authorization and communication with upstream), certificate pinning, etc. All work exactly the same way as for your HTTP APIs.
Allowing specific ports
By default, you will not be able to run a service on a custom port, until you allow the required ports.
Since TCP services can be configured via the Dashboard, you should be careful who can create such services, and which ports they can use. Below is an example of allowing ports in tyk.conf
:
{
...
"ports_whitelist": {
"https": {
"ranges": [
{
"from": 8000,
"to": 9000
}
]
},
"tls": {
"ports": [
6000,
6015
]
}
}
...
}
As you can see, you can use either ranges
or ports
directives (or combine them).
You can also disable this behavior and allow any TCP port by setting disable_ports_whitelist
to true
.
Health checks
TCP health checks are configured the same way as HTTP ones. The main difference is that instead of specifying HTTP requests, you should specify a list of commands, which send data or expect some data in response.
A simple health check which verifies only connectivity (e.g. if a port is open), can be:
{
...
"uptime_tests": {
"check_list": [
{ "url": "127.0.0.1:6379" },
"commands": []
]
}
...
}
Complex example
Here is quite a complex example of using health checks, which shows a Redis Sentinel setup. In this configuration, we put a TCP proxy, e.g. Tyk, on top of two or more Redis nodes, and the role of the proxy will always direct the user to Redis master. To do that we will need to perform health checks against each Redis node, to detect if it is a master or not. In other words, Redis clients who communicate with Redis through the proxy will be always directed to the master, even in case of failover.
{
"name": "Redis Sentinel",
"listen_port": 6379,
"protocol": "tcp",
"enable_load_balancing": true,
"proxy": {
"target_list": ["192.168.10.1:6379", "192.168.10.2:6379"]
},
"check_host_against_uptime_tests": true,
"uptime_tests": {
"check_list": [
{
"url": "192.168.10.1:6379",
"commands": [
{ "name": "send", "message": "PING\r\n" },
{ "name": "expect", "message": "+PONG" },
{ "name": "send", "message": "info replication\r\n" },
{ "name": "expect", "message": "role:master" },
{ "name": "send", "message": "QUIT\r\n" },
{ "name": "send", "message": "+OK" }
]
},
{
"url": "192.168.10.2:6379",
"commands": [
{ "name": "send", "message": "PING\r\n" },
{ "name": "expect", "message": "+PONG" },
{ "name": "send", "message": "info replication\r\n" },
{ "name": "expect", "message": "role:master" },
{ "name": "send", "message": "QUIT\r\n" },
{ "name": "send", "message": "+OK" }
]
}
]
}
}
At the moment Tyk supports only 2 commands:
send
send string to serverexpect
expect string from the server
SSE Proxy
Server-Sent Events (SSE) is a server push technology enabling a subscribed client to receive automatic updates from a server via a long running HTTP connection. Unlike WebSockets, SSE is a one-way communication of server to clients (WebSockets is a bidirectional communication between server and client). As such, if you only need clients to receive data from a server, and don’t require them sending messagess back, SSE could be a simpler way to make that happen. An online stock quotes, or notifications and feeds are good examples for applications that use SSE.
Using Tyk as a server-sent events (SSE) Proxy
Tyk Gateway supports SSE proxying over HTTP, and can sit in the middle between the client and the SSE server and support the server sending updates to the client.
Setup
- Enable SSE support on the Gateway: Set
http_server_options.enable_websockets
totrue
in your Tyk Gateway config file. - To maintain an open connection between the API consumer and the Tyk Gateway, set
http_server_options.read_timeout
andhttp_server_options.write_timeout
to appropriately high values (in milliseconds). For example, you could try setting both to2000
, but this is for you to determine in your environment. - Set
http_server_options.flush_interval
to an appropriate value, e.g.1
, to force Tyk to stream the response to the client everyn
seconds.
Example using Tyk as an SSE proxy
For this we will need:
- An SSE server. For this example we will use Golang HTML 5 SSE example
- An instance of the Tyk Gateway and optionally the Tyk Dashboard
Steps for Configuration:
- Ensure the Gateway configurations detailed in the Setup section are set.
- Run the SSE server as per the example instructions. By default this runs on port
8000
.
go run ./server.go
- Publish an API with the following configuration:
- Set an appropriate listen path, e.g.
"listen_path": "/sse"
- Strip the listen path, e.g.
"strip_listen_path": true,
- Set the target url as the SSE server, e.g. the example SSE server:
"target_url": "http://host.docker.internal:8000"
- Click Save, and wait for the Gateway to reload the API before testing it
- Set an appropriate listen path, e.g.
- To test the protected SSE service via the API in the Tyk Gateway run:
curl http://localhost:8080/sse/events/
You should see a stream of updates from the server. In this example, you will see:
Message: 20 - the time is 2013-03-08 21:08:01.260967 -0500 EST
Message: 21 - the time is 2013-03-08 21:08:06.262034 -0500 EST
Message: 22 - the time is 2013-03-08 21:08:11.262608 -0500 EST
WebSockets
As from Tyk gateway v2.2, Tyk supports transparent WebSocket connection upgrades. To enable this feature, set the enable_websockets
value to true
in your tyk.conf
file.
WebSocket proxying is transparent, Tyk will not modify the frames that are sent between client and host, and rate limits are on a per-connection, not per-frame basis.
The WebSocket upgrade is the last middleware to fire in a Tyk request cycle, and so can make use of HA capabilities such as circuit breakers and enforced timeouts.
Tyk needs to decrypt the inbound and re-encrypt the outbound for the copy operations to work, Tyk does not just pass through the WebSocket. When the target is on default SSL port you must explicitly specify the target url for the API:
https://target:443/
WebSocket Example
We are going to set up Tyk with a WebSocket proxy using our Tyk Pro Docker Demo installation.
We will be using the Postman WebSocket Echo Service to test the connection.
Steps for Configuration
-
Setup the API in Tyk
Create a new API in Tyk. For this demo we are going to select Open (Keyless) as the Authentication mode.
Set the Target URL to
wss://ws.postman-echo.com/raw
-
Test the Connection
- From Postman, select File > New > WebSocket Request (or from Workspace > New > WebSocket Request if using the web based version).
- Enter your Tyk API URL in the Enter server URL field (minus the protocol).
- Enter some text in the New Message field and click Send.
- You will see a successful connection.
Note
If your API uses an Authentication mode other than Open (Keyless), add the details in the Header tab.
An example Header configuration for using an Authentication Token with an API:
See the Access an API tutorial for details on adding an Authentication Token to your APIs.