Ocelot: Support for Swagger to generate and expose API documentation?

Created on 23 Nov 2017  路  15Comments  路  Source: ThreeMammals/Ocelot

Hi,

I found this project and it looks really promising, however in my case it is really important to have Swagger / Swagger explorer on the gateway.
Is there any plan for supporting that? You can easily add swagger to each microservice using: https://github.com/domaindrivendev/Swashbuckle.AspNetCore

All what Ocelot would have to do is to consume the swagger.json from each microservice and expose it as one?

enhancement help wanted large effort

Most helpful comment

@TomPallister thank you for a great project.
For our is very important to have a documentation for our API.

I've created a package that covers our scenarios MMLib.SwaggerForOcelot.
The idea is as follows:
In the first step, it is necessary to define a Swagger generator in downstream services. Next, in the API Gateway project, we define SwaggerUI to display interactive Swagger documentation.
SwaggerForOcelot
This package also adds middleware that modifies swagger.json from downstream services under ocelot.json.

I currently support our use case, where Ocelot is mainly used as a reverse proxy. So, in ocelot.json we have projects/{everything}.

I would also like to support other scenarios. I would like to ask if anyone can provide a more comprehensive ocelot.json configuration for inspiration?

Thanks.

All 15 comments

@murbanowicz swagger support would be great! This is an open source project so you can fork and build it yourself! I will happily merge into master!! I will do this myself eventually but it鈥檚 quite complicated because Ocelot can change its configuration will running which means swagger would also need updating!

How to work on it?
I have never developed Nuget package so don't know how to start and test it as I would need some simple service/s connected to develop it and test.

@murbanowicz I'm not sure :)

It's quite hard. I don't know much about swagger but I think you create a swagger.json file and then swagger uses that to load the documentation.

This means ocelot would need to generate that file based on the users configuration which could be done on init from either the configuration.json or consul (if using that feature). However whenever the configuration changed either via the administration api or directly in consul then we would need to regenerate the swagger.json file.

Questions..

  1. Does swagger looks at the swagger.json file each time it loads of the docs or only the first time. If it is the first time then we might be screwed because changes wouldn't work.
  2. Do I even know what i am talking about!?!

@TomPallister @murbanowicz
This sounds like an interesting feature.
The way swagger works is, on the application's start it scans the controllers and their methods and creates the swagger.json file.
When you access the swagger UI, its just a javascript app that retrieves that swagger.json and creates UI elements according to instructions in that json. It recreates the UI each time you load the page, or hit the explore button.

In order for this to work, Ocelot would need to fetch and merge swagger.json files from various downstream services on demand, at a specific endpoint, but it would also need to tamper them if the upstream template differs from the downstream template. The swagger spec of the downstream service would not work on Ocelot's swagger UI if there is some different mapping in the Ocelot reroute.

ohh I've misunderstood this. I thought the issue was to create swagger.json from the Ocelot configuration in configuration.json or consul.

Looking at downstream services and making one is quite complicated! I think that might be a feature for long term future!

I think this feature is to complicated to implement in a non crappy way.

The best thing to do is probably have a user make their own swagger.json (however they want) and then use the MapWhen functionality of the app builder to direct people to the swagger endpoint using the swashbuckle package.

It's not a simple parse from configuration.json to swagger.json?

@jefferson yes if all of your routes are defined! What if you have /{everything} :(

Any suggestions would be appreciated! Maybe we could just do a best effort!

Ive had another look at it this morning on the train to work...I think I can get something working low effort so will do that and see how it is!

OK so I have looked multiple times at building swagger.json out of the Ocelot configuration.json but it doesnt fit into the vision I have for Ocelot. If you would like to have Swagger in Ocelot then you can roll your own swagger.json and do the following in your Startup.cs or Program.cs. The code sample below registers a piece of middleware that loads your hand rolled swagger.json and returns it on /swagger/v1/swagger.json. It then registers the SwaggerUI middleware from Swashbuckle.AspNetCore

    app.Map("/swagger/v1/swagger.json", b =>
    {
        b.Run(async x => {
            var json = File.ReadAllText("swagger.json");
            await x.Response.WriteAsync(json);
        });
    });   
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "Ocelot");
    });

    app.UseOcelot().Wait();

The main reasons why I don't think Swagger makes sense is we already hand roll our definition in configuration.json. If we want people developing against Ocelot to be able to see what routes are available then either share the configuration.json with them (This should be as easy as granting access to a repo etc) or use the Ocelot administration API so that they can query Ocelot for the configuration.

In addition to this many people will configure Ocelot to proxy all traffic like /products/{everything} to their product service and you would not be describing what is actually available if you parsed this and turned it into a Swagger path. Also Ocelot has no concept of the models that the downstream services can return and linking to the above problem the same endpoint can return multiple models. Ocelot does not know what models might be used in POST, PUT etc so it all gets a bit messy and finally the Swashbuckle package doesnt reload swagger.json if it changes during runtime. Ocelot's configuration can change during runtime so the Swagger and Ocelot information would not match. Unless I rolled my own Swagger implementation.

If the user wants something to easily test against the Ocelot API then I suggest using Postman as a simple way to do this. It might even be possible to write something that maps configuration.json to the postman json spec. However I don't intend to do this.

I am really sorry to everyone who wanted this feature and hope they understand why Ocelot won't be supporting it at the moment. If anyone else would like to take them up then they are welcome but I am going to close the issue for now and have written up my thoughts in the Not Supported section of Ocelot docs.

Hi Tom,

I have read your reasons for not supporting swagger, and not going to argue ;-)

But the main reason we use swagger is not so much for the swagger doc and UI - though this is helpful - its mainly for being able to generate clients ( both c# and javascript ) as part of our build process.

is there an Ocelot'y way to do this ?

@TimJarvis thanks for your interest in the project. There isn鈥檛 currently a way to generate a client from an Ocelot config.

Again the main problem is going to be the lack of types so client wouldn鈥檛 know what it needs to post or what it is going to get. It might be possible to do it with JS / dynamics in C#.

Microsoft have just been exposing the services swagger endpoints via Ocelot if that helps!

@TomPallister thank you for a great project.
For our is very important to have a documentation for our API.

I've created a package that covers our scenarios MMLib.SwaggerForOcelot.
The idea is as follows:
In the first step, it is necessary to define a Swagger generator in downstream services. Next, in the API Gateway project, we define SwaggerUI to display interactive Swagger documentation.
SwaggerForOcelot
This package also adds middleware that modifies swagger.json from downstream services under ocelot.json.

I currently support our use case, where Ocelot is mainly used as a reverse proxy. So, in ocelot.json we have projects/{everything}.

I would also like to support other scenarios. I would like to ask if anyone can provide a more comprehensive ocelot.json configuration for inspiration?

Thanks.

@Burgyn I submitted a PR to make a replace on swagger better with JObject.

@TomPallister On this aproach just make a new swagger downStream Based with rules on configuration.json is more easy to expose downStreamSwagger configuration. and easy to expose swaggerUI and capapacities of Gateway Services.

Sry for my poor english.

is it working? any example please?

Was this page helpful?
0 / 5 - 0 ratings