-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Routes entity page, router expressions, proxying #168
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
✅ Deploy Preview for kongdeveloper ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor adjustments - I was working on the "Services" page and realized this section moved to "Routes", so just adding my edits from that.
Co-authored-by: lena-larionova <[email protected]>
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
app/_gateway_entities/route.md
Outdated
When the external application tries to access the Service via {{site.base_gateway}} using `/external`, they're rate limited. | ||
But when the internal application accesses the Service using {{site.base_gateway}} using `/internal`, the internal application isn't limited. | ||
|
||
## How routing works |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reviewers: I added routing here and removed the existing routing standalone page. My thinking, routing made the most sense in context with routes. I think it would be difficult to create something more than a very basic route without understanding routing, so in the spirit of every page is page one, I added it here.
But I did wonder if it should be a standalone page still and this section could be an include.
app/_gateway_entities/route.md
Outdated
* In `expressions` mode, we recommend putting more likely matched Routes before (as in, higher priority) those that are less frequently matched. | ||
* Regular expressions in Routes use more resources to evaluate than simple prefixes. In installations with thousands of Routes, replacing regular expression with simple prefix can improve throughput and latency of {{site.base_gateway}}. If regex must be used because an exact path match must be performed, using the [expressions router](/gateway/routing/expressions/) will significantly improve {{site.base_gateway}}’s performance in this case. | ||
|
||
## Route use cases |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reviewers: should this be bumped up the page?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say yes
app/_how-tos/dynamically-rewrite-simple-request-urls-with-routes.md
Outdated
Show resolved
Hide resolved
app/gateway/traffic-control/proxy.md
Outdated
|
||
{{ page.description }} This page details information about how {{site.base_gateway}} handles proxying. The following diagram shows how proxying is handled by {{site.base_gateway}}: | ||
|
||
{% mermaid %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reviewers: I used ChatGPT help on this diagram, but I revised everything and the input I provided it was the ordered list below this diagram. Still, I'd like a review for tech accuracy, especially the parts about the load balancer. I think ChatGPT got it wrong, so I made some changes to that part and wanted to confirm that I did them correctly.
app/gateway/traffic-control/proxy.md
Outdated
@@ -0,0 +1,191 @@ | |||
--- | |||
title: Proxying with {{site.base_gateway}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reviewers: Is this too much info for the proxying page? Should proxying just contain info about proxying and the connective parts (ex. listeners, routing, plugins, etc) should go on a traffic control landing page with proxying as another card/section instead? This is similar to what we had in the offsite proxy branch: main...proxy-reference#diff-8922116eb8441698da97efe2beeb185fb024118f8add77981f8eeb930867bbc6
I thought listeners, etc. could be helpful on this page to understanding proxying, but wasn't sure if others felt it was out of place.
app/gateway/traffic-control/proxy.md
Outdated
Kong's configuration capabilities: the **Admin API** (`8001` by default). | ||
{:.important} | ||
> **Important**: If you need to expose the `admin_listen` port to the internet in a production environment, | ||
> {% if_version lte:2.8.x %}[secure it with authentication](/gateway/{{include.release}}/admin-api/secure-admin-api/).{% endif_version %}{% if_version gte:3.0.x %}[secure it with authentication](/gateway/{{include.release}}/production/running-kong/secure-admin-api/).{% endif_version %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reviewers: I couldn't find the Admin API in the dev site, does anyone have a link to it?
app/gateway/traffic-control/proxy.md
Outdated
1. If multiple Routes match, the {{site.base_gateway}} router then orders all defined Routes by their priority and uses the highest priority matching Route to handle a request. | ||
1. If a given request matches the rules of a specific route, {{site.base_gateway}} will | ||
run any global, Route, or Service [plugins]() before it proxies the request. They are run in the following order: Route, Service <!--when does the global config get run?--> These configured plugins will run their `access` phase, which you can find more | ||
information about in the [Plugin development guide][plugin-development-guide]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reviewers: I don't think we added the autogenerated PDK yet. How do we want to handle links to autogenerated pages?
Signed-off-by: Diana <[email protected]>
products: | ||
- gateway | ||
|
||
works_on: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it works on both can the platform be agnostic?
app/_how-tos/dynamically-rewrite-simple-request-urls-with-routes.md
Outdated
Show resolved
Hide resolved
app/_how-tos/dynamically-rewrite-simple-request-urls-with-routes.md
Outdated
Show resolved
Hide resolved
app/_how-tos/dynamically-rewrite-simple-request-urls-with-routes.md
Outdated
Show resolved
Hide resolved
app/_how-tos/dynamically-rewrite-simple-request-urls-with-routes.md
Outdated
Show resolved
Hide resolved
app/_how-tos/dynamically-rewrite-simple-request-urls-with-routes.md
Outdated
Show resolved
Hide resolved
app/_how-tos/dynamically-rewrite-simple-request-urls-with-routes.md
Outdated
Show resolved
Hide resolved
app/_how-tos/dynamically-rewrite-simple-request-urls-with-routes.md
Outdated
Show resolved
Hide resolved
Now you can create a Route with your new path, `/new-path`, that points to the new Upstream. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds a second route and associates it to the service. So by this point you have:
1 service pointing to the upstream url http://httpbin.konghq.com/anything
2. routes proxying to it, one at /anything, and one at /new-path.
3. And an optional stray route from the prereq
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, i left this undone, you should remove the original /anything route
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed the original route.
To validate that the URL was successfully rewritten and the request is now being matched to the new Upstream instead of the old one, run the following: | ||
|
||
```bash | ||
curl -i http://localhost:8000/new-path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a better test would be seeing what URL you are getting from the old path, and from the new one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Guaris I like this idea. I think the idea is that traffic is routed away from the old path to the new one, like a redirect (let me know if this is wrong), so if you go to the old path, should it redirect you to the new path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Guaris I think this is working correctly with http://localhost:8000/new-path
as this is the response I get:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 486
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Wed, 18 Dec 2024 21:14:18 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Kong-Upstream-Latency: 352
X-Kong-Proxy-Latency: 488
Via: 1.1 kong/3.9.0.0-enterprise-edition
X-Kong-Request-Id: 0bfd8c4c54274e4ffbbfcd2c5c939c65
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Connection": "keep-alive",
"Host": "httpbin.konghq.com",
"User-Agent": "curl/8.4.0",
"X-Forwarded-Host": "localhost",
"X-Forwarded-Path": "/new-path",
"X-Forwarded-Prefix": "/new-path",
"X-Kong-Request-Id": "0bfd8c4c54274e4ffbbfcd2c5c939c65"
},
"json": null,
"method": "GET",
"origin": "172.27.0.1",
"url": "http://localhost/anything"
}
|
||
tldr: | ||
q: How can I divert traffic from an old URL to a new one with {{site.base_gateway}}? | ||
a: Set up a Gateway Service with the old URL path and create a new a Route with new path.For example, your legacy upstream endpoint may have a base URI like `/api/old/`. However, you want your publicly accessible API endpoint to now be named `/new/api`. To route the Service’s upstream endpoint to the new URL, you can set up a Service with the path `/api/old/` and a Route with the path `/new/api`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thinjk the /api/new and /api/old are good examples of what you are trying to do but because the deck file and steps dont reflect that I got thrown off. I think that the api/old and api/new can be illustrated through the steps better than as the answer int he tld;r
Signed-off-by: Diana <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partial review of the entity pages, ran out of time for the rest.
app/_gateway_entities/route.md
Outdated
* Hosts: Lists of domains that match a route | ||
* Methods: HTTP methods that match a route | ||
* Headers: Lists of values that are expected in the header of a request | ||
* Redirect status codes: HTTPS status codes | ||
* Tags: Optional set of strings to group routes with | ||
When you configure Routes, you can also specify the following: | ||
|
||
## Route and service interaction | ||
* **Protocols:** The protocol used to communicate with the [Upstream](/gateway/entities/upstream/) application. | ||
* **Hosts:** Lists of domains that match a Route | ||
* **Methods:** HTTP methods that match a Route | ||
* **Headers:** Lists of values that are expected in the header of a request | ||
* **Redirect status codes:** HTTPS status codes | ||
* **Tags:** Optional set of strings to group Routes with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this list still useful? We have the Route schema on the page now, so this info is already here. Plus, there are almost definitely more options than this now.
For the Routes entity page: I'm having a hard time seeing the big picture right now. It's a hefty page, and I wonder if all of the content that's been migrated over needs to be there. Is there anything here that's actually covered by having the schema on the page now? I don't have the answer to this at all - but I am curious if there's a better way to organize this content. |
app/_gateway_entities/route.md
Outdated
|
||
Routing a request based on its Host header is the most straightforward way to proxy traffic through Kong Gateway, especially since this is the intended usage of the HTTP Host header. `hosts` accepts multiple values, which must be comma-separated when specifying them via the Admin API, and is represented in a JSON payload. You can also use wildcards in hostnames. Wildcard hostnames must contain only one asterisk at the leftmost or rightmost label of the domain. | ||
|
||
When proxying, Kong Gateway’s default behavior is to set the Upstream request’s Host header to the hostname specified in the Service’s `host`. The `preserve_host` field accepts a boolean flag instructing Kong Gateway not to do so. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When proxying, Kong Gateway’s default behavior is to set the Upstream request’s Host header to the hostname specified in the Service’s `host`. The `preserve_host` field accepts a boolean flag instructing Kong Gateway not to do so. | |
When proxying, {{site.base_gateway}}’s default behavior is to set the Upstream request’s Host header to the hostname specified in the Service’s `host`. The `preserve_host` field accepts a boolean flag instructing Kong Gateway not to do so. |
|
||
## Allowed type and operator combinations | ||
|
||
Here are the allowed combination of field types and constant types with each operator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are the allowed combination of field types and constant types with each operator. | |
Here are the allowed combinations of field types and constant types with each operator. |
Signed-off-by: Diana <[email protected]>
Co-authored-by: Angel <[email protected]>
Signed-off-by: Diana <[email protected]>
Co-authored-by: Lucie Milan <[email protected]> Co-authored-by: lena-larionova <[email protected]>
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
The Request Transformer broken link will be resolved with updating the branch |
… a different PR Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
app/gateway/traffic-control/proxy.md
Outdated
| `X-Forwarded-Port: <port>` | `<port>` is the port of the server which accepted a request. If `$realip_remote_addr` is one of the **trusted** addresses, the request header with the same name gets forwarded if provided. Otherwise, the value of the `$server_port` variable provided by [ngx_http_core_module](https://nginx.org/docs/http/ngx_http_core_module.html#var_server_port) will be used. | | ||
| `X-Forwarded-Prefix: <path>` | `<path>` is the path of the request which was accepted by {{site.base_gateway}}. If `$realip_remote_addr` is one of the **trusted** addresses, the request header with the same name gets forwarded if provided. Otherwise, the value of the `$request_uri` variable (with the query string stripped) provided by [ngx_http_core_module](https://nginx.org/docs/http/ngx_http_core_module.html#var_server_port) will be used. **Note**: {{site.base_gateway}} returns `"/"` for an empty path, but it doesn't do any other normalization on the request path. | | ||
| All other headers | Forwarded as-is by {{site.base_gateway}} | | ||
<!--vale on--> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<!--vale on--> | |
<!--vale on--> |
@cloudjumpercat for some reason adding a new line here fixes the rendering issue 🤷
Signed-off-by: Diana <[email protected]>
Signed-off-by: Diana <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Full review of Route entity page
* Headers: Lists of values that are expected in the header of a request | ||
* Redirect status codes: HTTPS status codes | ||
* Tags: Optional set of strings to group routes with | ||
{% mermaid %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there still plans to remake this diagram? Looks like we're still using the Service image. I still feel that the diagram/approach mentioned here https://github.com/Kong/developer.konghq.com/pull/168/files#r1889390983 is a better illustration of what a Route does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lena-larionova I think I switched to the diagram you're referecing before break but then the Friday before break, got feedback from others that the diagram that's currently here was more helpful? Maybe I should include both with a description about the differences?
flowchart LR | ||
A(External application) | ||
B("`Route (/external)`") | ||
C("`Service (example-service)`") | ||
D(Upstream application) | ||
E(Internal application) | ||
F("`Route (/internal)`") | ||
|
||
subgraph id1 ["` | ||
**KONG GATEWAY**`"] | ||
B <--requests | ||
responses--> C | ||
F <--requests | ||
responses--> C | ||
end | ||
|
||
{{site.base_gateway}} 3.0.x or later ships with a new router. The new router can use regex expression capture groups to describe routes using a domain-specific language called Expressions. Expressions can describe routes or paths as patterns using regular expressions. For more information about how to configure the router using Expressions, see [How to configure routes using expressions](https://docs.konghq.com/gateway/latest/key-concepts/routes/expressions/). | ||
A <--requests | ||
responses--> B | ||
E <--requests | ||
responses--> F | ||
|
||
C <--requests | ||
responses--> D | ||
|
||
B -.->|Rate Limiting plugin| C | ||
|
||
style id1 rx:10,ry:10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite. The requests from /external are passing through the rate limiting advanced plugin. I also wouldn't put "requests/responses" in this diagram, as it confuses the point of the example, which is the rate limiting use case.
I can't add this as a github suggestion because of some "unedited lines", so please copy and paste this as a replacement:
flowchart LR
A(External application)
B("`Route (/external)`")
B2(Rate Limiting
plugin)
C("`Service (example-service)`")
D(Upstream application)
E(Internal application)
F("`Route (/internal)`")
A --request--> B
E --request--> F
subgraph id1 ["`
**KONG GATEWAY**`"]
B --> B2 --"10 requests
per minute"--> C
F ---> C
end
C --transformed
and routed
requests--> D
style id1 rx:10,ry:10
app/_gateway_entities/route.md
Outdated
When two Routes have the same path, {{site.base_gateway}} uses a tiebreaker. For example, if the rule count for the given request is the same in two Routes `A` and `B`, then the following tiebreaker rules will be applied in the order they are listed. Route `A` will be selected over `B` if: | ||
* `A` has only "plain" Host headers and `B` has one or more "wildcard" | ||
host headers | ||
* `A` has more non-Host headers than `B`. | ||
* `A` has at least one "regex" paths and `B` has only "plain" paths. | ||
* `A`'s longest path is longer than `B`'s longest path. | ||
* `A.created_at < B.created_at` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The created_at
rule is missing from the list before this. Looks like that's the final priority rule, aka rule number 5? If all of the above are equal, the router chooses the route that was created first.
|
||
## 1. Set up a Route with the path to the new Upstream | ||
|
||
In the prerequisites, you created the `example-service` pointing to the `/anything` upstream. This path, `/anything`, is your old upstream path. You must create a Route with your new path, `/new-path`, that points to the new Upstream. By doing it this way, traffic can continue to be routed to the old path while you enable the new path. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the prerequisites, you created the `example-service` pointing to the `/anything` upstream. This path, `/anything`, is your old upstream path. You must create a Route with your new path, `/new-path`, that points to the new Upstream. By doing it this way, traffic can continue to be routed to the old path while you enable the new path. | |
Create a Route with your new path, `/new-path`, that points to the upstream established in the `example-service`. By doing it this way, incoming traffic uses the `/new-path` route to access the upstream application, instead of directly accessing the `/anything` path. |
This is a bit difficult to rephrase, because this is essentially the core of what Routes do in Kong.
|
||
## 3. Validate | ||
|
||
To validate that the URL was successfully rewritten and the request is now being matched to the new Upstream instead of the old one, run the following: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To validate that the URL was successfully rewritten and the request is now being matched to the new Upstream instead of the old one, run the following: | |
To validate that the URL was successfully rewritten, run the following: |
The upstream remains the same. They are simply accessing it via a different path. That is, if you go to https://httpbin.org/anything
and compare it to the output of http://localhost:8000/new-path
from this example, they are the same thing.
@@ -1,7 +1,7 @@ | |||
--- | |||
title: Expressions router |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this page and the expressions router reference need to be separate?
| Match by source IP and destination port | `net.src.ip in 192.168.1.0/24 && net.dst.port == 8080` | This matches all clients in the `192.168.1.0/24` subnet and the destination port (which is listened to by {{site.base_gateway}}) is `8080`. IPv6 addresses are also supported. | | ||
| Match by SNI (for TLS routes) | `tls.sni =^ ".example.com"` | This matches all TLS connections with the `.example.com` SNI ending. | | ||
|
||
## Expressions router performance considerations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now this feels like it could be a separate page, if we were doing a grouping of expressions router pages. In that case, I would keep both pages you have now, and do:
- Expressions router behavior
- Expressions router reference
- Expressions router performance considerations
* **Priority:** The priority is a positive integer that defines the order of evaluation of the router. | ||
The bigger the priority, the sooner a route will be evaluated. In the case of duplicate | ||
priority values between two routes in the same router, their order of evaluation is undefined. | ||
## How expressions are formatted in the expressions router |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole section belongs in the reference.
- q: How do I enable the expressions router? | ||
a: | | ||
In your [kong.conf] <!--TODO link to kong.conf--> file, set `router_flavor = expressions` and restart your {{site.base_gateway}}. Once the router is enabled, you can use the `expression` parameter when you're creating a Route to specify the Routes. For example: | ||
```sh | ||
curl --request POST \ | ||
--url http://localhost:8001/services/example-service/routes \ | ||
--header 'Content-Type: multipart/form-data' \ | ||
--form-string name=complex_object \ | ||
--form-string 'expression=(net.protocol == "http" || net.protocol == "https") && | ||
(http.method == "GET" || http.method == "POST") && | ||
(http.host == "example.com" || http.host == "example.test") && | ||
(http.path ^= "/mock" || http.path ^= "/mocking") && | ||
http.headers.x_another_header == "example_header" && (http.headers.x_my_header == "example" || http.headers.x_my_header == "example2")' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be hidden in an FAQ. Also, this is the third time this example is being used again, and it's unnecessary. You've already established that people want to use or test the expressions router; there's no need to show the example yet again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This page doesn't need to exist, please delete it. This is covering the same thing that the basic example does in the Routes reference page.
Co-authored-by: lena-larionova <[email protected]>
TODO
Preview Links
Checklist