-
Notifications
You must be signed in to change notification settings - Fork 897
Add a Json schema for YARP configuration #2758
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
Conversation
|
If someone wants to try it locally until it's on NuGet, you can stick this into VS: (please do try it and yell at us if you happen to have a complex config file this breaks) |
|
We should likely set |
|
I avoided it in most places (outisde of transforms) to reduce how many people we start giving warnings for things that could be working fine if they had custom logic that read the same config, but maybe there's a better middle ground here where we restrict it in more places. Do you have any specific examples for invalid things that copilot generated for you? |
|
Having no errors editing an invalid json file using a json schema felt unexpected Gut feeling claim: Having a strict format is likely to make copilot / editor etc. provide feedback and solutions for invalid schemas (the initial file generated by copilot was not correct) Alternatively we could generate a lax / strict version of the schemas, letting developers make the choice That said, I would expect teams adding additional metadata into the yarp settings to consider modelling-inheritance to get a stricter json format. For inspiration the DAB team are using a strict json schema dab.draft.schema.json No matter what the outcome, having the yarp json schema will be a great addition 🎁 Copilot blank test{
"$schema": "https://raw.githubusercontent.com/MihaZupan/yarp/refs/heads/json-schema/src/ReverseProxy/ConfigurationSchema.json",
"Clusters": {},
"Routes": {}
}Random test{
"$schema": "https://raw.githubusercontent.com/MihaZupan/yarp/refs/heads/json-schema/src/ReverseProxy/ConfigurationSchema.json",
"foo": "bar",
"Clusters": {},
"Routes": {},
"ReverseProxy": {
"Clusters": {},
"Routes": {
"foo": {
"ClusterId": "bar",
"Path": "/foo",
"Methods": ["GET"],
"Match": {
"Path": "/foo"
}
}
}
}
}Test using the PlatformPlatform settings{
"$schema": "https://raw.githubusercontent.com/MihaZupan/yarp/refs/heads/json-schema/src/ReverseProxy/ConfigurationSchema.json",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"blob-storage": "UseDevelopmentStorage=true"
},
"AllowedHosts": "*",
"ReverseProxy": {
"Routes": {
"account-management-api": {
"ClusterId": "account-management-api",
"Match": {
"Path": "/api/account-management-api/{**catch-all}"
},
"Transforms": [
{
"PathPattern": "/api/{**catch-all}"
}
]
},
"account-management-spa": {
"ClusterId": "account-management-api",
"Match": {
"Path": "/{**catch-all}"
}
},
"account-management-static": {
"ClusterId": "account-management-static",
"Match": {
"Path": "/account-management/{**catch-all}"
},
"Transforms": [
{
"PathPattern": "{**catch-all}"
}
]
},
"back-office-api": {
"ClusterId": "back-office-api",
"Match": {
"Path": "/api/back-office/{**catch-all}"
},
"Transforms": [
{
"PathPattern": "api/{**catch-all}"
}
]
},
"back-office-spa": {
"ClusterId": "back-office-api",
"Match": {
"Path": "/back-office/{**catch-all}"
},
"Transforms": [
{
"PathPattern": "{**catch-all}"
}
]
},
"back-office-static": {
"ClusterId": "back-office-static",
"Match": {
"Path": "/back-office/static/{**catch-all}"
},
"Transforms": [
{
"PathPattern": "static/{**catch-all}"
}
]
},
"avatars": {
"ClusterId": "avatars-storage",
"Match": {
"Path": "/avatars/{**catch-all}"
},
"Transforms": [
{
"PathPattern": "/avatars/{**catch-all}"
},
{
"ResponseHeader": "Cache-Control",
"Set": "public, max-age=2592000, immutable"
}
]
}
},
"Clusters": {
"account-management-api": {
"Destinations": {
"destination": {
"Address": "https://localhost:9100"
}
}
},
"account-management-static": {
"Destinations": {
"destination": {
"Address": "https://localhost:9101"
}
}
},
"back-office-api": {
"Destinations": {
"destination": {
"Address": "https://localhost:9200"
}
}
},
"back-office-static": {
"Destinations": {
"destination": {
"Address": "https://localhost:9201"
}
}
},
"avatars-storage": {
"Destinations": {
"destination": {
"Address": "http://127.0.0.1:10000/devstoreaccount1"
}
}
}
}
}
} |
|
I think we should be strict within the ReverseProxy section and its children apart from the Metadata sections which are listed as name/value pairs, but are where I would expect most customizations to come from. |
|
In the listed examples, we shouldn't warn on empty clusters/routes. We support providing multiple configuration sources, so you're free to e.g. provide just the routes in one. I'll make the YARP-specific sections more strict. |
adityamandaleeka
left a comment
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.
Nice! Let's make sure to add a note in the release notes for what people should do if they run into any incorrect schema behavior.
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.
Copilot reviewed 13 out of 13 changed files in this pull request and generated no comments.

Closes #1350
The intention here is to make editing the config much easier without just copy-pasting everything, it's a non-goal that it will catch every possible validation error that may be raised at runtime.
For example I've added Regex validations to some items that can catch a superset of what's actually allowed.
Initial version created by Sam
Here's the diff since then https://github.com/MihaZupan/yarp/compare/d4f177d3828970f71a48246ee84a62b42ba9c0df..json-schema?w=1#diff-fa5250031a03ad88202dff86f92ad41cc9036352784ccb1b902250d55309b9a7