-
Notifications
You must be signed in to change notification settings - Fork 704
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 Support for API Explorer #59
Comments
I found article which turned out to be very helpful in case of versioning and Web API Help Page. It isn't perfect but in 95% of cases it works perfectly! All of step are explained in the article. I changed implementation of GetFriendlyID method to takes api versioning into the account. In my case i'm using url versioning so RelativePath always conatins {version} string but you should consider another versioning strategies. ApiDescriptionExtensions
Issue I found in this solution affects identical routes but different HttpMethods. In this case it treats them as matching routes and because of this it creates more ApiDescriptions than actually exist. Workaround for this issue is to distinct Model in the ApiGroup.cshtml but I think there is better solution for this case. ApiGroup.cshtml
I think you should consider to add this code to your solution. Probably you have to suit it to be more universal but at least it's a great starting point. Hope this gonna be helpful for you and looking forward for changes! |
Nice. This is will be useful. I've started taking a crack at creating an IApiExplorer that adds support for versioning. The built-in implementation uses a lot of internal types and methods, which makes the port more difficult. This is a great link. It might negate the need to folk the original code and rather adapt over it. I'm hoping to have a beta version of the functionality out during the holidays. Thanks for sharing. |
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. |
@commonsensesoftware, how to remove letter |
Good question. I guess I haven't really documented those scenarios yet. This is handled by the IApiVersionGroupNameFormatter service. The default behavior is implemented by the DefaultApiVersionGroupNameFormatter. This class is sealed for now because there's nothing to extend or override in the base implementation thus far. The single method defined by the interface is responsible for formatting a given ApiVersion as a group name. To change it, just add your own implementation and then replace that service in the services collection as a singleton. services.TryAddSingleton<IApiVersionGroupNameFormatter, MyApiVersionGroupNameFormatter>(); The default implementation uses a |
Well I would add that to |
So if I want plain version, will |
By plain, do you mean no other formatting? I suspect - yes - that's what you're looking for. You can see the ApiVersion.ToString implementation. A limited set of format codes are available. If no format code is provided, then the entire version is formatted. The string result depends on the API version value itself. I considered implementing IFormattable, but there hasn't been a strong need for it up to this point. |
Yep. |
I considered it, but a single delegate won't actually work because the functionality is used in two separate, disconnected places:
I considered putting on the ApiVersioningOptions, but the API explorer behaviors aren't really associated. There's still a few possible alternatives. Option 1Add a DelegatingApiVersionGroupNameFormatter which accepts a delegate. Then you can register the service with: new DelegatingApiVersionGroupNameFormatter( version => version.ToString() ) Option 2Add options specific to the API Explorer. Something like: services.AddMvcCore().AddVersionedApiExplorer(
o =>
{
o.FormatApiVersionAsGroupName = version => version.ToString();
} ); I think I'd favor the second option. In either case, what should the default format be? Every example I've seen uses a |
The second one looks better. |
@xperiandri checkout PR #124 if you get a chance. I think you may have some thoughts there. I've added support for formatting ApiVersion and refactored the how group name formatting gets done. By default, there will be no formatting, which will basically be the result of ToString(). Without making you spelunk everything for some basic thoughts, here's what things look like in the updated examples: services.AddMvcCore().AddVersionedApiExplorer( o => o.GroupNameFormat = "'v'VVV" ); This format translates to: Not to worry, I'll put up a comprehensive wiki page that will document all of the format speciifiers, their meanings, and examples. If you're curious about how this is done, take a look at the ApiVersionFormatProvider. I think this sets things up better for new options in the future. |
Looks good. |
Here's my cheat sheet of format codes I used and will be the basis of the forthcoming wiki page:
I placed a strong emphasis on providing format specifiers that will deal with handling all of the optional components, which is something that would be difficult to do otherwise without writing code. For example, the period between major and minor version should be omitted when the optional minor version is also omitted. The minor version is optional if it is missing (e.g. null) or exactly equals zero. The major version is never optional (according to spec). There isn't currently a way to pad the major or minor version numbers, so formatting something like "ver01.25" wouldn't be possible. However, inline with the standard format codes, I could add support for a numeric placeholder. Something like:
If this was supported, then your scenario would be satisfied by the format: |
I would propose:
|
I considered something like that. I certainly won't argue that it makes more logical sense. However, when you consider how format specifiers get used, it doesn't quite hold up. Consider the "M" specifier for month in January:
When you include time, "m" is minutes. A format like "Mm" would be "15" where "1" is January and "5" is the minutes. I mention this because in your example the following are ambiguous: "V" + "v" and "Vv". In terms of any alternative forms, format specifier rules require that the casing of each code have matching casing. Using a number at the end does feel a bit wonky, but would be consistent with how other format specifiers work. For example:
If a different format specifier can be used for the alternate form[s], I'd be onboard with that. Perhaps use "V" and "v" for the normal forms and "P" and "p" for the padded forms?
The If it helps provide additional context, don't forget that all these codes can be used in var apiVersion = new ApiVersion( 1, 1, "Beta" );
var message = string.Format( "Welcome to version {0:VV} (S)", apiVersion );
Console.WriteLine( message );
// Output: Welcome to version 1.1 (Beta) |
Yep, makes sense. And if I want padding there will be no ability to make minor optional. |
Yes. The Assuming people will really want padding, I don't know that they'd want more than 2 digits. If I only support I'll add the support for padding, update the PR, and push things in. BTW: Thanks for taking the time to provide input. It helps flush out ideas and get a larger perspective of how things might actually be used. |
Cool! Thanks. Your work is highly valuable. |
@xperiandri Sorry for the delay. The 1.1 RC has now been published with all these features. Note that there is breaking, behavioral change for ASP.NET Core. :( You'll now need to call Let me know if you run into anything, but I think 1.1 is ready. |
So, does it require full MVC to run? |
No. The UseMvc extension is already part of Mvc.Core. It's kind of a lot to explain, but basically there needs to be a catch-all router at the end of the pipeline because the IActionSelector can be called multiple times. This is the only way to ensure that all candidates have been considered in the current ASP.NET Core routing design. It's similar to why 405 (Method Not Allowed) is not and cannot currently be supported. This is something I'm working with the ASP.NET team to address in ASP.NET Core 2.0. I'm happy to discuss this further for those that are curious. In most cases, this was not a problem for adopters. In the cases that hit this issue, it was a really design flaw that could only be addressed by changing the way you author your service. One of my key design principles was make sure no one has to learn anything new or different about routing. |
Well if it is the only option then fine. |
I think you might be confusing AddMvc and AddMvcCore with UseMvc. UseMvc adds the middleware. To my knowledge, UseMvcCore and UseMvc must always be called. Both AddMvcCore and UseMvc reside in the core MVC library, while AddMvc lives in the full MVC library. No references have changed, so everything should still work without any of the UI stuff. |
Overview
Add out-of-the-box support for the API Explorer. The implementation should enable enumerating controllers and their associated actions, which are grouped by API version .
Requirements
Tasks
The text was updated successfully, but these errors were encountered: