series

  1. Develop blog projects based on ABP vNext and.NET Core – build projects using ABP CLI
  2. Develop blog projects based on ABP vNext and.NET Core – slim the project down and make it run
  3. Development blog project based on ABP vNext and.NET Core – Refinement and beautification, Swagger enter
  4. Develop blog project based on ABP vNext and.NET Core – data access and code priority
  5. Development blog project based on ABP vNext and.NET Core – add, delete, change and check custom warehouse
  6. Develop blog project based on ABP vNext and.NET Core – Uniform specification API, wrapper back model
  7. Develop blog projects based on ABP vNext and.NET Core – say Swagger, grouping, description, little green lock
  8. Develop blog projects based on ABP vNext and.NET Core – access GitHub and protect your API with JWT
  9. Develop blog project based on ABP vNext and.NET Core – exception handling and logging
  10. Develop blog projects based on ABP vNext and.NET Core – using Redis to cache data
  11. Develop blog project based on ABP vNext and.NET Core – integrate Hangfire for timed task processing
  12. Develop blog projects based on ABP vNext and.NET Core – Use AutoMapper to map objects
  13. Developing blog projects based on ABP vNext and.NET Core – Best Practices for Timed Tasks (Part 1)
  14. Developing blog projects based on ABP vNext and.NET Core – Best Practices for Timed Tasks (Part 2)
  15. Developing blog projects based on ABP vNext and.NET Core – Best Practices for Timed Tasks (PART 3)
  16. Blog Development project based on ABP vNext and.NET Core
  17. Abp vNext and.NET Core
  18. Blog Development project based on ABP vNext and.NET Core
  19. Blog Development project based on ABP vNext and.NET Core
  20. Blog Development project based on ABP vNext and.NET Core
  21. Abp vNext and.NET Core Development Blog Project – Blazor
  22. Abp vNext and.NET Core Development Blog Project – Blazor – Part 2
  23. Abp vNext and.NET Core Development Blog Project – Blazor
  24. Abp vNext and.NET Core Development Blog Project – Blazor
  25. Abp vNext and.NET Core Development Blog Project – Blazor
  26. Abp vNext and.NET Core Development Blog Project – Blazor – Part 6
  27. Abp vNext and.NET Core Development Blog Project – Blazor
  28. Abp vNext and.NET Core Development Blog Project – Blazor Series (8)
  29. Abp vNext and.NET Core Development Blog Project – Blazor Series (9)
  30. 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.SharedAdd 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.DomainLayer refers to the project.Domain.SharedAdd a dependency to the module classtypeof(MeowvBlogDomainSharedModule)
  • will.EntityFrameworkCoreReference items in the layer.Domain.Sharedto.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/…