I'm learning Kong API Gateway, in particular the installation on Kubernetes with the Kong Ingress Controller, and I've completed this tutorial.
TL;DR
The HTTP request I send:
GET 127.0.0.1:80/weather/London
The HTTP request the service receives:
GET 127.0.0.1:3000/London
When sending an HTTP request to a Kong service, how can I route the request, so that the full path of the URL is preserved, without stripping the first part (/weather
)?
Long version
I'm trying to create a Node.js microservice that provides an API to retrieve the weather: the API is called with /weather/:countryName and returns a JSON with weather information (using OpenWeatherAPIs).
Example
Sending the following request
curl -i localhost:3000/weather/London
Return the following JSON:
{
"cityName": "London (GB)",
"temperature": {
"actual": 14.31,
"min": 12.56,
"max": 15.71
},
"humidity": 81,
"windSpeed": 3.09,
"description": "broken clouds",
"iconURL": "http://openweathermap.org/img/wn/[email protected]"
}
Kong
My setup is the one from the tutorial I linked previously:
- local cluster with minikube;
- minikube tunnel (docker driver) running in background;
Service and Deployment resources
File weather.yml
:
apiVersion: v1
kind: Service
metadata:
labels:
app: weather
name: weather
spec:
ports:
- port: 1025
name: tcp
protocol: TCP
targetPort: 1025
- port: 1026
name: udp
protocol: TCP
targetPort: 1026
- port: 3000
name: http
protocol: TCP
targetPort: 3000
selector:
app: weather
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: weather
name: weather
spec:
replicas: 1
selector:
matchLabels:
app: weather
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: weather
spec:
containers:
- image: mikyll/api-weather:v1.0
name: weather
ports:
- containerPort: 3000
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
resources: {}
Applied with cat .\weather.yml | kubectl apply -f -
Routing Configuration
File weather-routing.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: weather-route
annotations:
konghq.com/strip-path: 'false'
spec:
ingressClassName: kong
rules:
- http:
paths:
- path: /weather
pathType: ImplementationSpecific
backend:
service:
name: weather
port:
number: 3000
Applied with cat .\weather-routing.yml | kubectl apply -f -
Problem
When I send a request to the proxy, the first part of the URL is removed when calling the service:
curl -i 127.0.0.1:80/weather/London
Gives the following result:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /London</pre>
</body>
</html>
Question
How can I pass the same path, without stripping the first part (/weather
) to the service?
Turns out the problem was that I had mistakenly created 2 routes: "weather" and "weather-route":
Therefore, when editing "weather-route", even if I set
konghq.com/strip-path
to'false'
, the other route rule had it set to'true'
and was getting applied earlier, causing the request to fail.Removing it fixed the issue:
HTTP request:
A special thanks to Botje for making me notice the first most important issue :)