O tom ako využiť balíček MMLib.SwaggerForOcelot na dokumentovanie vášho systému priamo cez Ocelot gateway som písal v článku Swagger for Ocelot API Gateway.
Teraz by som sa chcel zamerať na jeho relatívne novú feature a to možnosť generovať dokumentáciu pre Ocelot agregácie.


Pokiaľ Ocelot využívate, tak s veľkou pravdepodobnosťou poznáte a aj používate jeho feature Request Aggreations. Request Aggregation vám umožňuje ľahko pridať nový endpoint do gateway-a, ktorý bude agregovať výsledky z viacerích existujúcich endpointov. Pokiaľ tieto agregácie využívate, tak pravdepodobne chcete mať aj tieto endpointy zdokumentované. Aby každý kto konzumuje vaše API vedel, že existujú a ako ich použiť.

Ako na to?

V metóde ConfigurationServices povolte možnosť GenerateDocsForAggregates.

services.AddSwaggerForOcelot(Configuration,
  (o) =>
  {
      o.GenerateDocsForAggregates = true;
  });

Dokumentácia vaších agregácií bude dostupná v samostatnej sekcii Aggregates.

aggregates docs

Vlastný popis

By default je popis endpointu generovaný z downstream dokumentácie. Ak potrebujete pridať vlastný popis, tak to môžete spraviť priamo v definícií agregácie.

"Aggregates": [ 
  {
    "RouteKeys": [
      "user",
      "basket"
    ],
    "Description": "Môj vlastný popis pre túto aggregate route.",
    "Aggregator": "BasketAggregator",
    "UpstreamPathTemplate": "/gateway/api/basketwithuser/{id}"
  }
]

Rozdielne názvy parametrov

Je bežné, že máte rozdielne názvy parametrov v downstream službách a definícií agregácie. Napríklad: v Users službe budete mať parameter {Id}, ale v službe Basket sa ten istý parameter bude volať {BuyerId}. Aby vám fungovali Ocelot agregácie, musíte mať parametre v Ocelot konfigurácií pomenované rovnako. To ale robí nemožné nájsť prislúchajúci parameter v dokumentácií downstream služby.

Pre tieto prípady môžete priamo v konfigurácií nastaviť mapovanie názvov parametrov.

{
  "DownstreamPathTemplate": "/api/basket/{id}",
  "UpstreamPathTemplate": "/gateway/api/basket/{id}",
  "ParametersMap": {
    "id": "buyerId"
  },
  "ServiceName": "basket",
  "SwaggerKey": "basket",
  "Key": "basket"
}

Property ParametersMap je mapa, kde key (prvý parameter) je meno parametra v Ocelot konfigurácií a value (druhý parameter) je názov pod akým sa tento parameter nachádza v downstream službe.

Custom agregátor

Dokumentácia odpovede je generovaná na základe pravidiel, ktoré má Ocelot pri vytváraní výslednej odpovede z viacerých dotazov. Ak používate vlastnú implementáciu IDefinedAggregator, tak vaša odpoveď bude ziavne iná. V tomto prípade môžete využiť atribút AggregateResponseAttibute.

[AggregateResponse("Basket with buyer and busket items.", typeof(CustomResponse))]
public class BasketAggregator : IDefinedAggregator
{
    public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses)
    {
        ...
    }
}

Modifikovanie výslednej dokumentácie

Pokiaľ vám finálna dokumentácia nevyhovuje, máte možnosť modifikovať výsledný dokument pomocou vlastného postprocesu.

services.AddSwaggerForOcelot(Configuration,
  (o) =>
  {
      o.GenerateDocsForAggregates = true;
      o.AggregateDocsGeneratorPostProcess = (aggregateRoute, routesDocs, pathItemDoc, documentation) =>
      {
          if (aggregateRoute.UpstreamPathTemplate == "/gateway/api/basketwithuser/{id}")
          {
              pathItemDoc.Operations[OperationType.Get].Parameters.Add(new OpenApiParameter()
              {
                  Name = "customParameter",
                  Schema = new OpenApiSchema() { Type = "string"},
                  In = ParameterLocation.Header
              });
          }
      };
  });

Dokumentácia samotného Ocelot gateway-a

Keď používate Ocelot gateway aj ako orchestrátor (špecifický typ agregácie), tak pravdepodobne chcete vidieť dokumentáciu aj za gateway samotný.

V týchto scenároch môžete postupovať nasledovne:

  1. Povolte možnosť GenerateDocsForGatewayItSelf v metóde ConfigureServices.
services.AddSwaggerForOcelot(Configuration,
  (o) =>
  {
      o.GenerateDocsForGatewayItSelf = true;
  });
  1. Pridajte Swagger generátor v metóde Configure.
app.UseSwagger();

ocelot docs

Demo príklad

Sample.ApiGatewayOcelot