spring-cloud / spring-cloud/spring-cloud-gateway
Add new routes by group instead of independent routes
@spencergibb is already working on this.
Since Mar 23, 2023.
- Dominant language
- Java
- Stars
- 4.9k
- Forks
- 3.5k
- Avg merge
- 20h 57m
- Merged PRs (30d)
- 8
Description
Is your feature request related to a problem? Please describe.
Related to how SCG persists (add + refresh) routes dynamically via Actuator endpoints
Currently, the routes are added one by one using /actuator/gateway/routes/{id}. In order to get changes applied, we need also to call /actuator/gateway/refresh endpoint which iterates over all the RouteDefinitions to refresh the Route instances.
For example, adding two routes requires the next requests
- POST
/actuator/gateway/routes/my-route-1-> add my-route-1 into RouteDefinitions - POST
/actuator/gateway/routes/my-route-2-> add my-route-2 into RouteDefinitions - POST
/actuator/gateway/routes/refresh-> convert my-route-1 and my-route-2 to Routes
When a route cannot be instantiated (for example, a predicate with wrong arguments), there are some issues depending on the spring.cloud.gateway.failOnRouteDefinitionError flag
When spring.cloud.gateway.failOnRouteDefinitionError=true
- The wrong route remains in the RouteDefinitions, preventing new routes to be applied because the /refresh will fail silently when the wrong routeDefinition is again processed
When spring.cloud.gateway.failOnRouteDefinitionError=false
- There is no feedback about the wrong route and the only way to figure out which route is wrong is by sending a request for getting all the routes and checking which wasn’t applied
Additionally, it also has the following issues
- The
/actuator/gateway/routes/refreshreplies 200 OK even if the route failed - It cannot treat routes as a whole group. If one route is wrong, I don’t want to get routes available yet
It is extremely worth having feedback about which routes are wrong and refreshing them as independent groups. Then, I can update SCG routes incrementally without breaking the current RouteDefinitions I have.
Describe the solution you'd like
To use a metadata label for identifying groups of routes in SCG
- If one route fails during /refresh, the whole group shouldn’t be applied
- If no group, the route is treated as “default” group, having the same behaviour as in the past
Describe alternatives you've considered
I considered other options
A. Adding a query parameter to the /refresh endpoint so I can refresh specific route groups
- But it doesn’t work because CachingRouteLocator rebuilds all the routeDefinitions, so I cannot incrementally refresh new routes
B. To implement a new endpoint that receives N routeDefinitions and validate them
- The routeDefinitions are converted to Routes
- Any error is returned in the response with the proper error code
- If routeDefinitions are valid, the routes are stored in the RouteDefinitions so the next /refresh will apply them as usual
Additional context
Example expected behaviour having SCG running with management port 8090 I would like to get the next response after running the script below
Routes persisted:
"route-1-1"
"route-1-2"
"route-3-1"
Only group-1 and group-3 have a valid configuration.
add_route() {
# ... it depends on the solution, I can share my implementation using groupBy metadata approach
}
add_route "group-1" "route-1-1"
add_route "group-1" "route-1-2"
add_route "group-2" "route-2-1"
add_route "group-2" "route-2-2"
add_route "group-2" "route-2-3" "wrong-uri"
add_route "group-2" "route-2-4"
add_route "group-3" "route-3-1"
curl --location --request POST 'http://localhost:8090/actuator/gateway/refresh'
echo "Routes persisted: "
curl -s "http://localhost:8090/actuator/gateway/routes" | jq '.[].route_id'
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.