preface

In the last article, we set up our development environment and created our project template framework. In the whole project of separating the front and back ends, the API interface of the back end is very important. It is the medium of communication between the front end and the back end. How to build a “good” API interface needs our back end personnel to think carefully.

In the system the whole process of iteration, the inevitable will add new resource, or modify the existing resources, the backend interface as exposed to the outside world service, the smaller changes, the use of the service side caused by the smaller, therefore, how to appropriate the our API interface version control, we will need to first consider.

ASP.NET Core project

Storage address: github.com/Lanesra712/…

Step by Step

Projects are always iterative, and at some point, the business needs to upgrade the existing interface, but the existing interface cannot be stopped immediately. You developed a interface, for example, provide for the use of love fills version 1.0, then love fills the version of the iteration, needs to interface the data returned to the original version 1.0 the data returned is different, this time, the interface is certainly need to upgrade, but if directly to upgrade the original interface, still use 1.0 version of the user is not GG, Therefore, how to make both the 1.0 version of the user, also can let the 2.0 version of the user to use the need to consider, common solutions, there are mainly the following.

1. Use different API names

When the interface logic needs to be changed, a new API name is created. The new version calls the new API name, and the old version calls the old API name.

https://yuiter.com/api/Secret/Login ## Love Sex 1.0
https://yuiter.com/api/Secret/NewLogin ## Love Sex 2.0
Copy the code

2. Specify the version number in the Url

Add the API version information directly to the requested Url, call different versions of the API, and indicate which version is used directly in the Url.

https://yuiter.com/api/v1/Secret/Login ## Love Sex 1.0
https://yuiter.com/api/v2/Secret/Login ## Love Sex 2.0
Copy the code

3. Add version information to the request parameters

The version information of the API is passed as a parameter to the request, and the requested API version is determined by specifying the parameter value.

https://yuiter.com/api/Secret/Login?version=1 ## Love Sex 1.0
https://yuiter.com/api/Secret/Login?version=2 ## Love Sex 2.0
Copy the code

4. Specify the version number in the header

When the front end requests the API interface, it adds a parameter in the header to indicate the version information of the request. The back end determines the parameter set in the header by the front end to execute different branches of business logic.

POST https://yuiter.com/api/Secret/Login
Host: yuiter.com  
api-version: v1   ## Love Sex 1.0

POST https://yuiter.com/api/Secret/Login
Host: yuiter.com  
api-version: v2   ## Love Sex 2.0
Copy the code

In my project estadore. VuCore, I chose to add the version of the API to the requested address to explicitly indicate the version of the interface being requested.

Swagger integration

After finishing the interface, the back end must tell the front end, no matter it is organized into TXT/Excel/Markdown document, or directly send wechat message to tell the front end after finishing an interface, there is always an extra step to do, and Swagger can save us this step. After configuration, Swagger can automatically generate API interface documents based on our interfaces, saving time and effort. Of course, if the front lady is available and you happen to be interested, we can talk about it.

Swagger is an open source framework that can automatically generate interface documents and test interface functions. Swashbuckle.AspNetCore and NSwag are two open source frameworks that help us generate Swagger Documents. Here, I’m using Swashbuckle.AspNetCore.

Before we can use Swashbuckle.AspNetCore, we first need to add a reference to Swashbuckle.AspNetCore in our API project. You can load a reference directly by right-clicking on an API project and selecting the Manage Nuget package, or you can add a reference from the Package Management console. Note that to use the package Management Console, you need to change the default project into AN API(Estade.webAPI) project. When the reference is added, we can configure Swagger in the project.

Install-Package Swashbuckle.AspNetCore
Copy the code

ASP.NET
ASP.NET

In the Program class file generated by the framework, when configuring IWebHostBuilder, the framework adds some services by default. Of course, you can comment out the default script here and create a WebHostBuilder object yourself. The Startup class is mandatory for an ASP.NET Core application. (You can delete the generated Startup class and create a new one. However, the newly created class must contain Configure methods. After that, you only need to configure the class as Startup class on UseStartup. If you do not specify Startup class, Startup will fail.

In the Startup class, there are ConfigureServices and Configure methods. In the ConfigureServices method, We add custom services to the IServiceCollection container through dependency injection, and these services can be used in the Configure method. The Configure method specifies how the ASP.NET Core application will respond to each HTTP request. This is where we can bind our own Middleware to the IApplicationBuilder. To add to the HTTP request pipeline.

ASP.NET Core 2.0:7. ASP.NET Core 2.0:7 Here’s a look at the secret behind the launch. Since ASP.NET Core 2.1 has changed a bit since version 2.0, there are a few differences that you should be aware of.

Once we understand the startup process, we can configure our Swagger. Swashbuckle.aspnetcore helps us build middleware that uses Swagger, so we can just use it directly.

First we need to add our service to the IServiceCollection container in the ConfigureServices method. Here we need to do some configuration for the generated Swagger Document.

services.AddSwaggerGen(s => { s.SwaggerDoc("v1", new Info { Contact = new Contact { Name = "Danvic Wang", Email = "[email protected]", Url = "https://yuiter.com" }, Description = "A front-background project build by ASP.NET Core 2.1 and Vue", Title = "estadual. Version = "v1" }); });Copy the code

After that, we can enable our Swagger middleware in the Configure method.

app.UseSwagger(); App.useswaggerui (s => {s.waggerendpoint ("/swagger/v1/swagger.json", "estadore.vucore API V1.0"); });Copy the code

At this point, when you run the program, type /swagger after the domain name to access our API documentation page. Since the default access to our API /values GET request interface is when the project is launched, we can open the launchsetting. json file under Properties to configure our application to open the page by default.

Right-click our API project, properties = “production, check the XML document file, the system will create the default address for us to generate the XML file, at this time, we regenerate the project, we will find that the current project under the XML file. As you rebuild the project, you’ll notice that the error list displays many warning messages indicating that some methods do not add XML annotations. If you are as obsessive-compulsive as I am, you can add the 1591 error to the forbidden display warning above so that the warning is no longer displayed.

PS: Here I put the address of the annotated XML document generated by each project in the base path of the program. If you generate the XML document in another location, the method of retrieving the XML here will need to be modified.

services.AddSwaggerGen(s => { //... //Add comments description // var basePath = Path.GetDirectoryName(AppContext.BaseDirectory); //get application located directory var apiPath = Path.Combine(basePath, "Grapefruit.WebApi.xml"); var dtoPath = Path.Combine(basePath, "Grapefruit.Application.xml"); s.IncludeXmlComments(apiPath, true); s.IncludeXmlComments(dtoPath, true); });Copy the code

Two, with version control API interface implementation

Specify the version number in the requested API Url. I don’t know what you will think when you first see this implementation. For me, just add the version number to the routing information. Em, this is too opportunistic…

[Route(" API /v1/[controller]")] [ApiController] public Class ValuesController: ControllerBase {}Copy the code

On second thought, adding a version number to the Url looks a lot like the Area we used in MVC.

Area is a function frequently used in MVC. We usually divide some small modules into areas one by one, and these small areas are actually MVC in this MVC project. Creating a hierarchical routing structure is achieved by adding another routing parameter, area, to the controller and Action. For example, we can create an Area called v1 to store our 1.x API. If we have a new version of the API, we can add an Area.

Right click on our API project and select Add Area. The new Area is named v1.

ASP.NET

app.UseMvc(routes => { routes.MapRoute( name : "areas", template : "{area:exists}/{controller=Home}/{action=Index}/{id? } "); });Copy the code

After we add the routing rule definition, we add a WebAPI Controller in the Controllers folder of the Area. Unlike Area in ASP.NET, when an Area is created in ASP.NET Core, there is no longer XXXAreaRegistration in the scaffolding file to register the Area. We just need to add the Area feature to the Controller of the Area to tell the system framework that the Controller is under the current Area.

If you try it yourself, you will find that when we create a v1 Area, the requested address does not show up in the routing information as we intended. We eventually need to manually specify the API version in the Route.

[Area("v1")]
[Route("api/v1/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
}
Copy the code

In the same way we used Swashbucking.aspnetcore above, we need to add a reference to this DLL in our API project before we can use Versioning. One thing to watch out for is the installed versioning, because the framework has been in production for a few months, and.NET Core 2.2 was released earlier this month. If you have.NET Core 2.1, like me, Versioning versions installed here are only up to 2.3.

Install-Package Microsoft.AspNetCore.Mvc.Versioning
Copy the code

When we have installed it, we can configure it.

public void ConfigureServices(IServiceCollection services) { services.AddApiVersioning(o => { o.ReportApiVersions = true; //return versions in a response header o.DefaultApiVersion = new ApiVersion(1, 0); //default version select o.AssumeDefaultVersionWhenUnspecified = true; //if not specifying an api version,show the default version }); }Copy the code

ReportApiVersions: This configuration is optional, when we set it to true, the API will return version information in the header of the response.

DefaultApiVersion: specifies the DefaultApiVersion to use if the version is not specified in the request. This will default to version 1.0.

AssumeDefaultVersionWhenUnspecified: this configuration items will be used to provide the request did not identify the API version of the case, by default, will be the default version of the API request, for example, this will request the 1.0 version of the API.

Here, delete the Area we created and the default ValuesController, create a new v1 folder in the Controllers folder, and place all v1 Controllers in that folder. Create a new Controller and add the ApiVersion Attribute to specify the current version information. Since my approach is to specify the API version in the Url, we also need to modify our Route attributes in the Route to match the API version. The v here is just a default convention, and you don’t have to add it.

[API ("1.0")] [Route(" API /v{version: ApiVersion}/[controller]")] [ApiController] public Class VaulesController: ControllerBase { }Copy the code

When we modify our Controller and run our project, you will find that the request address shown in the API document is not correct. Is it because our configuration does not work? Test our interface with Swagger’s built-in API test tool. Originally, the Url requested here already contains the version information we defined. When we specify the wrong version information, the tool will tell us that the version of the interface does not exist.

public void ConfigureServices(IServiceCollection services)
{
    services.AddSwaggerGen(s =>
    {
        //...

        //Show the api version in url address
        s.DocInclusionPredicate((version, apiDescription) =>
        {
            var values = apiDescription.RelativePath
                .Split('/')
                .Select(v => v.Replace("v{version}", version));

            apiDescription.RelativePath = string.Join("/", values);

            return true;
        });
    });
}
Copy the code

conclusion

This chapter USES the Microsoft. AspNetCore. Mvc. Versioning this component to achieve our for the realization of the function of the API version control, may you have a question, we directly in the routing version information easier, isn’t it? In my opinion, the purpose of using this component is to enable API versioning in a variety of ways, and if one day you don’t want to specify the version in the Url, you can quickly use another form of API versioning. In addition, directly write the version information in the route, will it appear that we are “low”, ha ha ha, joke, finally wish everyone happy double eggs ~~~

Of the pit

Personal Profile: Born in 1996, born in a fourth-tier city in Anhui province, graduated from Top 10 million universities. .NET programmer, gunslinger, cat. It will begin in December 2016. NET programmer career, Microsoft. NET technology stalwart, aspired to be the cloud cat kid programming for Google the best. NET programmer. Personal blog: yuiter.com blog garden blog: www.cnblogs.com/danvic712