-
Notifications
You must be signed in to change notification settings - Fork 712
Add Support for Swagger #60
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
Comments
I am not sure what you are after here but in the last day or so I have been adding swagger and api versioning to a new core api site I am working on. I wanted my version and a functional area split out in my swagger docs. I am using swashbuckle to implement swagger (Swashbuckle.AspNetCore). The way I implemented this was all on the swagger generation side not in versioning. I decided to generate separate documents for each API version (and namespace in my case) I was going to have. Then it is just a mater of selecting the document for the api I want to see. You can also insert a default query or header parameter and it will just work. I have attached some of my code if it helps. In the end I get a list of swagger documents for my api that is split by a functional area (portion of the namespace) and api version ie DoSomeWorkGroup1 - v1.0 Generate a list of Namespaces and Versions for Swagger:
Swagger generation in ConfigureServices of Startup Class
Swagger UI Settings in Configure of Startup Class
Helper Class Used to Get the Portion of the namespace I want to split the documents by.
Helper Function to add the needed query or header parameters to all Item:
Hope this helps. |
Do you mean like releasing a package related to API Versioning with a solution from here packaged into a single library with easy setup? |
Exactly. An interesting challenge is how to aggregate the controller versions for documentation. In the versioning libraries this happens by letting the routing infrastructure find all candidates for a route and then aggregating from there. In addition, the client knows the route their looking for. For documentation, all of the routes need to be collated and then aggregated. I know this is possible, but the implementation has yet to be hashed out. Another aspect is making sure that the documentation is built using the right abstractions. A lot of the early variants that I'm seeing people build are based on attributes. This not actually what the API versioning libraries use. The libraries only care about IApiVersionProvider and IApiVersionNeutral. One of the ways these interfaces are realized just happen to be attributes. It's important for the right abstractions are used so that the solution is generic and can be used for various API versioning scenarios. Regardless, there has been some great progress in a number of attempts to create a library and I'll certainly be reviewing the implementations I know about for input to the out-of-the-box solution. Now that I've nearly burned down all of the other issues, I should have some time (soon) to dedicate to this feature. Thanks for your patience. |
So what help do you need? |
Someone looking to help ... yeah! Coincidentally, I've finally burned down just about every other outstanding issue, so I can now give this topic the full attention it deserves. Admittedly, I haven't spent a bunch of hands-on time with Swagger and Swashbuckle, so I'll be looking for feedback there for sure. I'll be catching myself up as quickly as possible. Here's the 10,000ft overview: ObjectiveProvide an aggregated API version meta-model that groups all services (e.g. controllers) by route and their associated API versions. This is the part that is difficult and provides the value proposition to service authors. The result should be something analogous to, if not an implementation of, an API Explorer that is API version aware. This will provide all the heavy lifting for service authors and can potentially live directly within the API versioning libraries. I'm up in the air as to whether a separate library should be required for these capabilities. Opinions are welcome. Requirements
|
Hi guyz ! Just play with versioning and swagger few days ago and here is what I found :
For DocInclusionPredicate we already have all the api to configure this method because c.DocInclusionPredicate((docName, apiDesc) =>
{
var model = apiDesc.ActionDescriptor.GetProperty<ApiVersionModel>();
var version = docName;
if (model.IsApiVersionNeutral)
{
return true;
}
else if (model.DeclaredApiVersions.Any())
{
return model.DeclaredApiVersions.Any(_ => _.ToString() == version);
}
else if (model.ImplementedApiVersions.Any())
{
return model.ImplementedApiVersions.Any(_ => _.ToString() == version);
}
return false;
}); For other points, we can't use that because ApplicationModel hasn't been executed yet but to build SwaggerDoc and SwaggerEndpoint we just have to know all version available into our application not necessarily which action is available in a specific version Example of code to configure swagger doc and endpoint : app.UseSwaggerUI(c =>
{
foreach (var version in versions)
{
c.SwaggerEndpoint($"/swagger/v{version}/swagger.json", $"V{version} Docs");
}
}); // Register the Swagger generator, defining one or more Swagger documents
services.AddSwaggerGen(c =>
{
foreach (var version in versions)
{
c.SwaggerDoc($"v{version}", new Info { Title = $"Sample service v{version}", Version = $"v{version}" });
}
c.DocInclusionPredicate((docName, apiDesc) =>
{
//implem is above
...
});
}); |
Or like this options.DocInclusionPredicate((docName, apiDesc) =>
{
var model = apiDesc.ActionDescriptor.GetProperty<ApiVersionModel>();
switch (model)
{
case ApiVersionModel _ when model.IsApiVersionNeutral: return true;
case ApiVersionModel _ when model.DeclaredApiVersions.Any():
return model.DeclaredApiVersions
.Any(apiVersion => apiVersion.ToString() == docName);
case ApiVersionModel _ when model.ImplementedApiVersions.Any():
return model.ImplementedApiVersions
.Any(apiVersion => apiVersion.ToString() == docName);
default: return false;
}
}); |
ApiVersionModel usage is pretty low-level, so let me elaborate a little about how it's used. I'll limit the specifics to ASP.NET Core, but things work similarly in Web API. Ultimately, the logic should be very close to the way that the action selector works. If API versioning is enabled, then you can grab the ApiVersionModel as you've shown; however, there's a chance that it's not and the model will be Once you've retrieved a model, that should be all that's necessary based on the example I'm seeing. The only time any of the properties on the model are empty is when it's version-neutral. Since the both version-neutral and any version are matches, these conditions seem unnecessary. The DeclaredApiVersions are probably not useful for documentation. This collection is used by the controller and action selectors to find the matching implementation. The ImplementedApiVersions is an aggregation of the SupportedApiVersions and DeprecatedApiVersions for a single service. For creating a simple list, ImplementedApiVersions is probably sufficient; however, I suspect there would be a desire to know and document which API versions are deprecated. The ApiVersion class intentionally does not track that information. In order to bucketize these two groups, you'll want to use the SupportedApiVersions and DeprecatedApiVersions instead (though probably not in this code snippet). I hope that provides some additional context. |
To complete answer, i think that actually retrieving ApiVersionModel is dependant to have an ApplicationModel, ControllerModel or ActionModel. |
Sort of. The ControllerModel and ActionModel contain the information used to discover and populate the version information from attributes. This information is merged with any version information defined by conventions. The final set of version information is aggregated into a single ApiVersionModel and is attached as a property to the corresponding model. The ApiVersionModel defines a constructor that accepts the models, but this is purely a convenience as a shortcut to populate the information from attributes. Beyond that, there is no use or coupling to the models. The models and ApiVersionModel can still be built-up independent of this behavior. Unless I'm mistaken, this behavior doesn't add any additional dependency coupling that didn't already exist. If it does, then we should consider changing it now before the 1.1 milestone is officially released. These constructors were previously internal, but changed recently due an extensibility bug. |
A quick update. I have first set of changes out for review in PR #103 which introduces support for the IApiExplorer in Web API. I know a lot of you are waiting for the ASP.NET Core flavor, but I wanted to get - what I believe will be - the hard one out of the way. I'm expecting the ASP.NET Core version to come sometime during the next week. As a sanity check, if there is formal support for an API explorer that groups and enumerates all the controllers and actions by API version, is there really any other support needed to light up Swagger and/or Swashbuckle? It seems to me that the main challenge is collating all the metadata about API-versioned services. After that, the integration to Swagger and Swashbuckle should be business as usual, no? |
Alright folks, an alpha version of the ASP.NET Core functionality is now in PR #103. You can see how it comes together in the new Swagger Sample in the working branch. Free feel to share your thoughts on the PR. |
For those following the thread, there is now an end-to-end working Web API Swagger Sample. Now that there are working examples for ASP.NET Core and Web API, I'm convinced the work here is all in the API explorer. There are a few conveniences that could be provided API versioning, but I don't think I should own them. In my conversations with the ASP.NET team, they still looking to take the core abstractions from here and roll them into the platform. The work has been delayed so I can't say when that will happen. When it does finally happen, it will be easier for Swagger/Swashbuckle libraries to provide some of these capabilities directly out-of-the-box. The current build is alpha quality. The majority of the remaining work will be testing. I won't release anything official until the quality bar is high. However, since so many of you have been clamoring for this feature and have patiently waited for months, I'm willing to put out an alpha package for you to play with. No guarantee that nothing else will change, but I'm pretty confident little will change to the public API surface. Let me know your reaction. Thanks |
The first iteration of packages are available. I'm leaving a little burn-in time with a beta release for issues and/or feedback before the official release. I'll be updating the wiki soon.
You can use the links to the sample projects above to get started. Thanks to everyone that helped drive this forward. |
Yes, please. Because I have no idea which things are now unnecessary in my previous Swagger usage implementation |
The first round of documentation is up. See the API Documentation topic. The sample projects should also help point you in the right direction. Feel free to ask questions if anything is unclear. |
Looks cool! I will try it tomorrow |
You can simplify sample by moving public void Configure( ...loggerFactory, IApiVersionDescriptionProvider provider )
{
...
app.UseSwaggerUI(
options =>
{
// build a swagger endpoint for each discovered API version
foreach ( var description in provider.ApiVersionDescriptions )
{
options.SwaggerEndpoint( $"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant() );
}
} );
} |
Reasonable. I'll update it. |
I've added full versioning support to the ASP.NET API Boilerplate project template. You can now use |
Awesome! I'm sure this will help folks stitch things together very quickly. Thanks for putting in the work and sharing. :) |
Add basic support for Swagger. The Swagger functionality should be supported for all of the platforms:
The text was updated successfully, but these errors were encountered: