series
- Develop blog projects based on ABP vNext and.NET Core – build projects using ABP CLI
- Develop blog projects based on ABP vNext and.NET Core – slim the project down and make it run
- Development blog project based on ABP vNext and.NET Core – Refinement and beautification, Swagger enter
- Develop blog project based on ABP vNext and.NET Core – data access and code priority
- Development blog project based on ABP vNext and.NET Core – add, delete, change and check custom warehouse
- Develop blog project based on ABP vNext and.NET Core – Uniform specification API, wrapper back model
- Develop blog projects based on ABP vNext and.NET Core – say Swagger, grouping, description, little green lock
- Develop blog projects based on ABP vNext and.NET Core – access GitHub and protect your API with JWT
- Develop blog project based on ABP vNext and.NET Core – exception handling and logging
- Develop blog projects based on ABP vNext and.NET Core – using Redis to cache data
- Develop blog project based on ABP vNext and.NET Core – integrate Hangfire for timed task processing
- Develop blog projects based on ABP vNext and.NET Core – Use AutoMapper to map objects
- Developing blog projects based on ABP vNext and.NET Core – Best Practices for Timed Tasks (Part 1)
- Developing blog projects based on ABP vNext and.NET Core – Best Practices for Timed Tasks (Part 2)
- Developing blog projects based on ABP vNext and.NET Core – Best Practices for Timed Tasks (PART 3)
- Blog Development project based on ABP vNext and.NET Core
- Abp vNext and.NET Core
- Blog Development project based on ABP vNext and.NET Core
- Blog Development project based on ABP vNext and.NET Core
- Blog Development project based on ABP vNext and.NET Core
- Abp vNext and.NET Core Development Blog Project – Blazor
- Abp vNext and.NET Core Development Blog Project – Blazor – Part 2
- Abp vNext and.NET Core Development Blog Project – Blazor
- Abp vNext and.NET Core Development Blog Project – Blazor
- Abp vNext and.NET Core Development Blog Project – Blazor
- Abp vNext and.NET Core Development Blog Project – Blazor – Part 6
- Abp vNext and.NET Core Development Blog Project – Blazor
- Abp vNext and.NET Core Development Blog Project – Blazor Series (8)
- Abp vNext and.NET Core Development Blog Project – Blazor Series (9)
- Abp vNext and.NET Core development blog project – Final release project
Before we start this article, I have fixed a bug pointed out by @fanfan.thanks again for correcting it.
The steps are as follows:
- delete
.Domain.Shared
Add nuget dependencies to the project reference in the layerVolo.Abp.Identity.Domain.Shared
, you can use the following command:Install-Package Volo.Abp.Identity.Domain.Shared
- in
.Domain
Layer refers to the project.Domain.Shared
Add a dependency to the module classtypeof(MeowvBlogDomainSharedModule)
- will
.EntityFrameworkCore
Reference items in the layer.Domain.Shared
to.Domain
.
Previous article (juejin.cn/post/684490…) After completing the encapsulation of API return model, I plan to continue to fiddle with Swagger. Swagger has been simply used in previous articles, and this paper will focus on it to give it greater and more value.
As our project continues to grow and the number of apis continues to increase, it may not be easy to locate an API quickly and accurately. It takes a long time to find the right API. Therefore, it is necessary to group Swagger API documents and detailed document description. For this project, the blog system can be divided into blog foreground interface, blog background interface, other public interface and JWT authentication and authorization interface.
Among them, the interface in the blog background group can only be called after authorization, which involves authentication. Here, JWT(JSON WEB TOKEN) is used.
grouping
Grouping Swagger is easy, in. AddSwagger(this IServiceCollection services) calls options.swaggerDoc (…) Just like that
. options.SwaggerDoc("v1".new OpenApiInfo
{
Version = "1.0.0",
Title = "Oh, my interface.",
Description = "Interface Description 1"
});
options.SwaggerDoc("v2".new OpenApiInfo
{
Version = "1.0.0",
Title = "Oh, my interface 2.",
Description = "Interface Description 2"}); . .Copy the code
But that’s a little low, and then you can change your mind and go through it a little bit. options.SwaggerDoc(…) Two parameters are received: String name, OpenApiInfo info.
Name: can be understood as the prefix of the current group. OpenApiInfo: There are many configurable parameters, but I’m only using three here: Version, Title, and Description.
Note that when in AddSwagger(…) UseSwaggerUI(this IApplicationBuilder app), UseSwaggerUI(this IApplicationBuilder app), UseSwaggerUI(this IApplicationBuilder app), UseSwaggerUI The parameters it receives: string URL, String name.
Url: The URL must correspond to the name parameter previously configured.
Name: the group name that we customize to display.
You can then simply create a new inner class in the extension method: SwaggerApiInfo
internal class SwaggerApiInfo
{
/// <summary>
///The URL prefix
/// </summary>
public string UrlPrefix { get; set; }
/// <summary>
///The name of the
/// </summary>
public string Name { get; set; }
/// <summary>
/// <see cref="Microsoft.OpenApi.Models.OpenApiInfo"/>
/// </summary>
public OpenApiInfo OpenApiInfo { get; set; }}Copy the code
Then create a new List
to manually initialize some values for it.
./// <summary>
///Swagger grouping information will be used for traversal
/// </summary>
private static readonly List<SwaggerApiInfo> ApiInfos = new List<SwaggerApiInfo>()
{
new SwaggerApiInfo
{
UrlPrefix = Grouping.GroupName_v1,
Name = "Blog Foreground Interface",
OpenApiInfo = new OpenApiInfo
{
Version = version,
Title = "A-star Plus - Blog Front Desk Interface",
Description = description
}
},
new SwaggerApiInfo
{
UrlPrefix = Grouping.GroupName_v2,
Name = "Blog Background Interface",
OpenApiInfo = new OpenApiInfo
{
Version = version,
Title = "A Xing Plus - Blog Background Interface",
Description = description
}
},
new SwaggerApiInfo
{
UrlPrefix = Grouping.GroupName_v3,
Name = "Universal Public Interface",
OpenApiInfo = new OpenApiInfo
{
Version = version,
Title = "A-star Plus - Universal Public Interface",
Description = description
}
},
new SwaggerApiInfo
{
UrlPrefix = Grouping.GroupName_v4,
Name = "JWT Authorized Interface",
OpenApiInfo = new OpenApiInfo
{
Version = version,
Title = "Star Plus - JWT Authorized Interface", Description = description } } }; .Copy the code
Version: We configure it in appSettings. json so that it can be changed dynamically.
//AppSettings.cs./// <summary>
/// ApiVersion
/// </summary>
public static string ApiVersion => _config["ApiVersion"]; .//appsettings.json{..."ApiVersion": "1.0.0". }Copy the code
Description: Because of repeated use, define a variable, the content is mainly some introductory description, will be displayed in Swagger interface.
UrlPrefix: v1,v2,v3,v4 respectively. Define constants for them in the domain.shared layer
//MeowvBlogConsts.cs./// <summary>
///grouping
/// </summary>
public static class Grouping
{
/// <summary>
///Blog Foreground interface group
/// </summary>
public const string GroupName_v1 = "v1";
/// <summary>
///Blog background interface group
/// </summary>
public const string GroupName_v2 = "v2";
/// <summary>
///Other common interface groups
/// </summary>
public const string GroupName_v3 = "v3";
/// <summary>
///JWT authorization interface group
/// </summary>
public const string GroupName_v4 = "v4"; }...Copy the code
Now modify the extension method AddSwagger(…) List
.public static IServiceCollection AddSwagger(this IServiceCollection services)
{
return services.AddSwaggerGen(options =>
{
//options.SwaggerDoc("v1", new OpenApiInfo
/ / {
/ / Version = "1.0.0",
// Title = "my interface ",
// Description = "interface Description"
/ /});
// Walk through and apply Swagger to group informationApiInfos.ForEach(x => { options.SwaggerDoc(x.UrlPrefix, x.OpenApiInfo); }); . }); }...Copy the code
In the extension method UseSwaggerUI(…) Use, universal also need to traverse.
.// Iterate over the packet information to generate Json
ApiInfos.ForEach(x =>
{
options.SwaggerEndpoint($"/swagger/{x.UrlPrefix}/swagger.json", x.Name); }); .Copy the code
If you are careful, you can find that in our previous articles, you need to manually change the URL address when opening Swagger document:… / Swagger can be entered correctly. In fact, Swagger supports routing. At the same time, let’s also change the page Title. Look at the following UseSwaggerUI (…). Complete code:
./// <summary>
/// UseSwaggerUI
/// </summary>
/// <param name="app"></param>
public static void UseSwaggerUI(this IApplicationBuilder app)
{
app.UseSwaggerUI(options =>
{
// Iterate over the packet information to generate Json
ApiInfos.ForEach(x =>
{
options.SwaggerEndpoint($"/swagger/{x.UrlPrefix}/swagger.json", x.Name);
});
// The model's default extension depth is set to -1 to completely hide the model
options.DefaultModelsExpandDepth(- 1);
// THE API document only expands the markup
options.DocExpansion(DocExpansion.List);
// The API prefix is set to empty
options.RoutePrefix = string.Empty;
// API page Title
options.DocumentTitle = "😍 Interface documentation - A-Star Plus⭐⭐⭐"; }); }...Copy the code
options.DefaultModelsExpandDepth(-1); Is the default extension depth for the model, set to -1 to completely hide the model.
options.DocExpansion(DocExpansion.List); On behalf of the API document only expand the tag, do not silently expand all interfaces, we need to manually click to expand, you can view the DocExpansion.
options.RoutePrefix = string.Empty; Indicates that the route is set to empty, directly open the page can be accessed.
Options. DocumentTitle = “😍 Interface document – ALstar Plus⭐⭐⭐”; Is used to set the title of the document page.
To complete the above operation, use Attribute in Controller: [ApiExplorerSettings(GroupName =…)] Specify which group to use and then you can use it happily.
If you don’t specify it by default it will have all of them. Currently there are only two controllers, so we set HelloWorldController to v3 and BlogController to V1.
//HelloWorldController.cs. [ApiExplorerSettings(GroupName = Grouping.GroupName_v3)]public class HelloWorldController : AbpController{... }...//BlogController.cs. [ApiExplorerSettings(GroupName = Grouping.GroupName_v1)]public class BlogController : AbpController{... }...Copy the code
Compile and run, open our Swagger document and take a look.
Try switching groups yourself. You’re done.
describe
In the Swagger document, only the name of our Controller is displayed by default. In fact, it also supports the description information, so we need to expand this by ourselves. In the.Swagger layer create a new folder Filters and add the SwaggerDocumentFilter class to implement the IDocumentFilter interface.
//SwaggerDocumentFilter.cs
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Generic;
using System.Linq;
namespace Meowv.Blog.Swagger.Filters
{
/// <summary>
///Description of the Controller API documentation
/// </summary>
public class SwaggerDocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var tags = new List<OpenApiTag>
{
new OpenApiTag {
Name = "Blog",
Description = "Personal Blog Related Interface",
ExternalDocs = new OpenApiExternalDocs { Description = "Contains: Articles/tags/categories/links"}}new OpenApiTag {
Name = "HelloWorld",
Description = "Universal Public Interface",
ExternalDocs = new OpenApiExternalDocs { Description = "Here are some common public interfaces."}}};// Sort by ascending NameswaggerDoc.Tags = tags.OrderBy(x => x.Name).ToList(); }}}Copy the code
To realize the Apply (…). After the AddSwagger(…) method, use the Linq syntax to sort the documents, and then, most importantly, use the Filter in the extension method AddSwagger(…). The use of
public static IServiceCollection AddSwagger(this IServiceCollection services)
{
return services.AddSwaggerGen(options =>
{
...
// Application Controller API document description
options.DocumentFilter<SwaggerDocumentFilter>();
});
}
Copy the code
Open the Swagger file again to see the effect.
Ok, now the description comes out.
Little green lock
In Swagger document to open small green lock is very simple, just add a Package: Swashbuckle. AspNetCore. Filters, directly using the command installation: Install – Package Swashbuckle. AspNetCore. Filters
Then extend the method AddSwagger(this IServiceCollection Services) call
public static IServiceCollection AddSwagger(this IServiceCollection services)
{
return services.AddSwaggerGen(options =>
{
...
var security = new OpenApiSecurityScheme
{
Description = "JWT mode authorization, please enter Bearer {Token} for authentication",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey
};
options.AddSecurityDefinition("oauth2", security);
options.AddSecurityRequirement(new OpenApiSecurityRequirement { { security, new List<string> ()}}); options.OperationFilter<AddResponseHeadersFilter>(); options.OperationFilter<AppendAuthorizeToSummaryOperationFilter>(); options.OperationFilter<SecurityRequirementsOperationFilter>(); . }); }Copy the code
Display the small green lock in Swagger document. Our new OpenApiSecurityScheme object, we can see the specific parameters by ourselves. Respectively call options. AddSecurityDefinition (…). And the options. AddSecurityRequiremen (…). And the options. OperationFilter (…). Compile and run, open and see.
Now just do the little green lock, but there is no practical significance, because in the. Net core also need to configure our identity authentication authorization code, can play a role of the real specific, so now we are still in the running of the state of the API, who can call your API, waiting for you to find your articles be deleted, You don’t even know why.
Implementing JWT, which will be explained in more detail in the next article, ends this article by improving the Swagger document, adding groups, descriptions, and little green locks to the interface. Tey, did you learn? 😁 😁 😁
Open source: github.com/Meowv/Blog/…