When migrate from Ocelet to yarp, by default, an separate yarp.json file is added. When I use yarp file and code has .AddYarp() statement, I noticed that public gateway micro service swagger would only expose those APIs I defined in yarp, however, because of our existing CI/CD, I put yarp.json content to appsettings.json, I noticed that gateway swagger can see all APIs from all micro-service.
Did I miss anything?
9 Answer(s)
-
0
You didn’t miss anything: in ABP’s microservice gateway setup, Gateway Swagger UI is driven by the gateway’s own Swagger configuration, which (by design) typically points to the swagger-json endpoints that you route through YARP. So what the gateway swagger can “see” depends on what you proxy.
With YARP, ABP’s recommended approach is to define reverse proxy config under the
ReverseProxysection (routes/clusters). This can live inappsettings.json(or any configuration source). ABP docs explicitly show configuring YARP viaappsettings.json, so moving fromyarp.json→appsettings.jsonis fine as long as the structure is the same.- If, after moving, the gateway swagger suddenly shows “all APIs from all microservices”, the usual reason is:
- you unintentionally stopped filtering swagger endpoints (or stopped using the gateway’s “aggregated swagger through gateway routes” approach), and/or
- the gateway is now able to reach additional swagger endpoints because your configuration now includes (directly or indirectly) more routes (e.g., a broad catch-all), so the swagger UI can successfully load more swagger.json documents.
- If, after moving, the gateway swagger suddenly shows “all APIs from all microservices”, the usual reason is:
What to do (definitive):
- Ensure your gateway is only exposing the swagger-json routes you intend. In ABP’s YARP gateway style, you usually add explicit routes like:
/swagger-json/Administration/swagger/v1/swagger.json/swagger-json/ProductService/swagger/v1/swagger.json(each with aPathRemovePrefixtransform) If you add a too-broad route (for example routing/swagger/{**catch-all}or a very generic/{**catch-all}), the gateway swagger UI (or the browser) may be able to resolve more swagger docs than you expect.
- Verify you didn’t end up with two configurations merged:
- In .NET configuration,
appsettings.json,appsettings.{Environment}.json, environment variables, configmaps, etc. can merge. Ifyarp.jsonis still being loaded somehow (custom code or host builder), you may effectively have more proxy routes/clusters than you think.
- In .NET configuration,
- If your goal is to hide ABP/framework endpoints (or generally filter what appears in Swagger UI), use ABP’s built-in Swagger filtering such as
HideAbpEndpoints()in your swagger setup.
- Ensure your gateway is only exposing the swagger-json routes you intend. In ABP’s YARP gateway style, you usually add explicit routes like:
Putting YARP config in
appsettings.jsonis supported; the key is keeping yourReverseProxyroutes tightly scoped so the gateway swagger can only load the intended swagger documents.
Links (verified):
- ABP microservice gateway YARP configuration via
appsettings.json(ReverseProxysection): https://abp.io/docs/latest/solution-templates/microservice/adding-new-api-gateways - YARP (Reverse Proxy) official site: https://microsoft.github.io/reverse-proxy/
- ABP Swagger option to hide ABP endpoints (
HideAbpEndpoints): https://abp.io/docs/latest/API/Swagger-Integration#hide-abp-endpoints-on-swagger-ui
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
-
0
Before upgrade, our public gateway only expose controller end with '-public', during upgrade process, I see it keep the same. But I not sure, when it shows all APIs, it might because I 1) replace Ocelot with yarp 2) move yarp.json to appsettings.json 3) replace AddAbpSwaggerGenWithOAuth with AddAbpSwaggerGenWithOidc
Do I still need to AddYarp() call after I move yarp.json content to appsettings? I deleted the yarp file after content merge.
-
0
Yes, you still need the YARP registration call (whatever your template/module uses, e.g.
services.AddYarpReverseProxy()/AddReverseProxy()etc.).
Movingyarp.jsoncontent intoappsettings.jsononly changes the configuration source; it does not register YARP services or map the reverse proxy endpoint. If you remove the YARP registration, the gateway won’t actually behave as a reverse proxy (and ABP’s YARP-based swagger aggregation logic won’t behave as expected either).In the ABP YARP migration guide, the expected change is to change the config loader from Ocelot to YARP:
builder.Host .AddAppSettingsSecretsJson() - .AddOcelotJson() + .AddYarpJson() .UseAutofac() .UseSerilog();That
AddYarpJson()is about loadingyarp.json(a separate file). If you merged the content intoappsettings.json, you typically don’t needAddYarpJson()anymore, becauseappsettings.jsonis already loaded by default. But you still need the YARP service registration andMapReverseProxy().Why your Swagger suddenly shows “all APIs”:
- In ABP’s YARP gateway approach, Swagger UI endpoints are usually added by iterating clusters from
IProxyConfigProviderand callingoptions.SwaggerEndpoint(...)for each cluster (see the migration guide’sConfigureSwaggerUI(proxyConfig, ...)sample). That means if your effective YARP config now contains more clusters than before (because of config merging from multiple sources, or you accidentally broadened routes/clusters), Swagger UI will list more services/APIs. - Switching from
AddAbpSwaggerGenWithOAuthtoAddAbpSwaggerGenWithOidcgenerally affects authentication method in Swagger UI, not which endpoints are included. The “shows all APIs” symptom is much more consistent with the gateway’s swagger endpoints being generated for more clusters (or the proxy now allowing access to more swagger-json endpoints).
- In ABP’s YARP gateway approach, Swagger UI endpoints are usually added by iterating clusters from
Definitive setup guidance when
ReverseProxyis insideappsettings.json:- Keep
ReverseProxysection inappsettings.json. - Remove
AddYarpJson()(optional) if you deletedyarp.jsonand don’t want that custom provider anymore. - Keep YARP registration + mapping (required): the gateway must still register YARP and call
endpoints.MapReverseProxy()(as shown in the migration guide).
- Keep
References (validated):
- ABP migration guide (Ocelot → YARP) showing
AddYarpJson(),IProxyConfigProvider-based Swagger endpoints, andMapReverseProxy(): https://abp.io/docs/latest/release-info/migration-guides/pro/migrating-to-yarp - ABP “Adding new API gateways” (YARP config in
appsettings.json/ReverseProxy): https://abp.io/docs/latest/solution-templates/microservice/adding-new-api-gateways - Swagger integration (hide ABP endpoints if needed): https://abp.io/docs/latest/API/Swagger-Integration#hide-abp-endpoints-on-swagger-ui
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
-
0
- All yarp cofnig are within "ReverseProxy": {} section in appsettings.config 2)Gateway has app.UseEndpoints(endpoints => endpoints.MapReverseProxy());
-
0
hi
Could you check the
Routessection in your oldyarp.jsonvs the currentappsettings.json?If your original routes were matching specific paths (e.g. only
-publiccontrollers), but the new config uses broader catch-all patterns, that would explain why more APIs are visible now — the Swagger UI reflects what's actually routed through YARP.Also, you can create a new microservice template project with ABP Studio and compare the gateway configuration with yours. That should make it easier to spot any differences.
Thanks.
-
0
Here is our settings:
"ReverseProxy": { "Routes": { "ClientServicePublic": { "ClusterId": "ClientService", "Match": { "Path": "/api/client-service-public/{**catch-all}" } }, "ClientServiceSwagger": { "ClusterId": "ClientService", "Match": { "Path": "/swagger-json/ClientService/swagger/v1/swagger.json" }, "Transforms": [ { "PathRemovePrefix": "/swagger-json/ClientService" } ] }, "IdentityPublic": { "ClusterId": "Identity", "Match": { "Path": "/api/identity-public/{**catch-all}" } }, "IdentitySwagger": { "ClusterId": "Identity", "Match": { "Path": "/swagger-json/Identity/swagger/v1/swagger.json" }, "Transforms": [ { "PathRemovePrefix": "/swagger-json/Identity" } ] }, "SignalRNegotiate": { "ClusterId": "ClientServiceSignalR", "Match": { "Path": "/signalr/negotiate", "Methods": [ "POST", "OPTIONS" ] } }, "SignalRHub": { "ClusterId": "ClientServiceSignalR", "Match": { "Path": "/signalr/{**catch-all}", "Methods": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ] } } }, "Clusters": { "ClientService": { "Destinations": { "ClientService": { "Address": "https://localhost:44368/" } } }, "ClientServiceSignalR": { "Destinations": { "ClientService": { "Address": "https://localhost:44368/" } }, "SessionAffinity": { "Enabled": true, "Policy": "Cookie", "AffinityKeyName": "ASP.NET_SessionId", "Cookie": { "Expiration": "00:30:00" } } }, "Identity": { "Destinations": { "Identity": { "Address": "https://localhost:44388/" } } } } } -
0
hi
Can you share your Gateway project source code to liming.ma@volosoft.com?
Thanks.
-
0
Figured out the reason, We have same micro service, controllers end with "-public", we want to available to public gateway. Here is AI's answer:
Ocelot uses MMLib.SwaggerForOcelot which downloads all downstream swagger.json files and merges them into the gateway's own swagger.json. So when Swagger UI requests /swagger/v1/swagger.json, it gets a locally generated document that goes through the full SwaggerGen pipeline — including DocInclusionPredicate and DocumentFilter. Swagger UI → /swagger/v1/swagger.json (gateway's OWN doc) ↓ SwaggerGen pipeline runs ↓ DocInclusionPredicate ✅ fires DocumentFilter ✅ fires ↓ Merged & filtered result
YARP simply forwards the request to the downstream service and returns the raw response. The gateway's SwaggerGen pipeline is never involved. Swagger UI → /swagger-json/ClientService/swagger/v1/swagger.json ↓ YARP proxies request to https://localhost:44368/swagger/v1/swagger.json ↓ Raw downstream swagger.json returned directly ↓ DocInclusionPredicate ❌ never fires DocumentFilter ❌ never fires
The solution is add a SwaggerDoc to this MicroSerivce with name "public" and at public gateway yarp setting using: "Transforms": [ { "PathSet": "/swagger/public/swagger.json" } ]
-
0
Hi,
The key difference is that Ocelot processes and filters the downstream
swagger.jsonthrough the gateway's SwaggerGen pipeline (DocInclusionPredicate,DocumentFilter), while YARP simply proxies the raw response from downstream services without any filtering.Using a separate SwaggerDoc (e.g.,
"public") in your microservices and pointing the YARP transform to it viaPathSetis a clean solution.For reference, the ABP microservice template takes a different approach — it uses
PathRemovePrefixto proxy the defaultswagger.jsonfrom each downstream service, assuming each microservice is already split by responsibility and all its APIs should be exposed through the gateway. Your approach with separate SwaggerDoc groups works well when a single microservice needs to expose only a subset of its APIs through the gateway.Thanks.