E-Commerce System Architecture Summary 4 (WEBAPI version control)

Source: Internet
Author: User

In order to successfully iterate the upgrade, the Web API in the maintenance process is constantly upgraded, but users can not force them to follow you every time to upgrade, which will let users patience. In order to ensure that different versions of the client can be compatible, it is necessary to add version control to the Web API interface.

Of course, versioning is also good for the code we develop, not to get into chaos. The version parameter can be placed in the requested URL as part of the routing parameter, or it can be placed in the header. The solution is to implement ihttpcontrollerselector and replace it in the Webapiconfig registration method.

     Public classVersionhttpcontrollerselector:ihttpcontrollerselector {Private Const stringVersionkey ="version"; Private Const stringControllerkey ="Controller"; Private ReadOnlyhttpconfiguration _configuration; Private ReadOnlylazy<dictionary<string, httpcontrollerdescriptor>>_controllers; Private ReadOnlyhashset<string>_duplicates;  Publicversionhttpcontrollerselector (httpconfiguration config) {_configuration=config; _duplicates=Newhashset<string>(stringcomparer.ordinalignorecase); _controllers=Newlazy<dictionary<string, httpcontrollerdescriptor>>(initializecontrollerdictionary); }        Privatedictionary<string, httpcontrollerdescriptor>initializecontrollerdictionary () {varDictionary =Newdictionary<string, httpcontrollerdescriptor>(stringcomparer.ordinalignorecase); Iassembliesresolver Assembliesresolver=_configuration.            Services.getassembliesresolver (); Ihttpcontrollertyperesolver Controllersresolver=_configuration.            Services.gethttpcontrollertyperesolver (); ICollection<Type> controllertypes =controllersresolver.getcontrollertypes (Assembliesresolver); foreach(Type tinchcontrollertypes) {                varsegments =T.namespace.split (Type.delimiter); varControllername = T.name.remove (T.name.length-DefaultHttpControllerSelector.ControllerSuffix.Length); stringVersion = Segments[segments. Length-1]; varKey = String.Format (CultureInfo.InvariantCulture,"{0}. {1}", version, controllername); if(Version = ="Controllers") {Key= String.Format (CultureInfo.InvariantCulture,"{0}", controllername); }                //Check for duplicate keys.                if(dictionary. Keys.contains (key)) {_duplicates.                ADD (key); }                Else{Dictionary[key]=NewHttpcontrollerdescriptor (_configuration, T.name, T); }            }            foreach(stringSinch_duplicates) {Dictionary.            Remove (s); }            returndictionary; }        //Get A value from the route data, if present.        Private StaticT getroutevariable<t> (Ihttproutedata routedata,stringname) {            Objectresult =NULL; if(RouteData.Values.TryGetValue (Name, outresult)) {                return(T) result; }            return default(T); }         Publichttpcontrollerdescriptor Selectcontroller (httprequestmessage request) {Ihttproutedata Routedata 
    =request.            Getroutedata (); if(Routedata = =NULL)            {                Throw Newhttpresponseexception (Httpstatuscode.notfound); }            //Get the version and controller variables from the route data.            stringVersion = getroutevariable<string>(Routedata, Versionkey); if(string. IsNullOrEmpty (Version)) {version=Getversionfromhttpheaderandacceptheader (Request); }            stringControllername = getroutevariable<string>(Routedata, Controllerkey); if(Controllername = =NULL)            {                Throw Newhttpresponseexception (Httpstatuscode.notfound); }            //Find a matching controller.            stringKey = String.Format (CultureInfo.InvariantCulture,"{0}", controllername); if(!string. IsNullOrEmpty (version)) {Key= String.Format (CultureInfo.InvariantCulture,"{0}. {1}", version, controllername);            } Httpcontrollerdescriptor Controllerdescriptor; if(_controllers. Value.trygetvalue (Key, outcontrollerdescriptor)) {                returnControllerdescriptor; }            Else if(_duplicates. Contains (key)) {Throw Newhttpresponseexception (Request. Createerrorresponse (Httpstatuscode.internalservererror,"multiple controllers were found the match this request.")); }            Else            {                Throw Newhttpresponseexception (Httpstatuscode.notfound); }        }         Publicidictionary<string, httpcontrollerdescriptor>getcontrollermapping () {return_controllers.        Value; }        Private stringGetversionfromhttpheaderandacceptheader (Httprequestmessage request) {if(Request. Headers.contains (Versionkey)) {varVersionheader =request. Headers.getvalues (Versionkey).                FirstOrDefault (); if(Versionheader! =NULL)                {                    returnVersionheader; }            }            varAcceptHeader =request.            headers.accept; foreach(varMimeinchAcceptHeader) {                if(MIME. mediatype = ="Application/json"|| Mime. mediatype = ="text/html")                {                    varVersion =MIME. Parameters. Where (v=v.name.equals (Versionkey, StringComparison.OrdinalIgnoreCase)).                    FirstOrDefault (); if(Version! =NULL)                    {                        returnversion.                    Value; }                    return string.                Empty; }            }            return string.        Empty; }    }
View Code

The focus is on the Selectcontroller method to find the appropriate version of the controller from the HTTP request. I'm here to get the version from the routing and header, get it from the route first, and not get it from the header.

Ihttproutedata Routedata =request.            Getroutedata (); if(Routedata = =NULL)            {                Throw Newhttpresponseexception (Httpstatuscode.notfound); }            //Get the version and controller variables from the route data.            stringVersion = getroutevariable<string>(Routedata, Versionkey); if(string. IsNullOrEmpty (Version)) {version=Getversionfromhttpheaderandacceptheader (Request); }
      Private stringGetversionfromhttpheaderandacceptheader (Httprequestmessage request) {if(Request. Headers.contains (Versionkey)) {varVersionheader =request. Headers.getvalues (Versionkey).                FirstOrDefault (); if(Versionheader! =NULL)                {                    returnVersionheader; }            }            varAcceptHeader =request.            headers.accept; foreach(varMimeinchAcceptHeader) {                if(MIME. mediatype = ="Application/json"|| Mime. mediatype = ="text/html")                {                    varVersion =MIME. Parameters. Where (v=v.name.equals (Versionkey, StringComparison.OrdinalIgnoreCase)).                    FirstOrDefault (); if(Version! =NULL)                    {                        returnversion.                    Value; }                    return string.                Empty; }            }            return string.        Empty; }

The Webapiconfig file call code is as follows:

    Public Static void Register (httpconfiguration config)        {。。。 Config. Services.replace (typeofnew  versionhttpcontrollerselector (config));}

The definition of the Web API, it is possible to differentiate from the namespace. For example, the Loginapicontroller namespace with version number V1 is defined as XXX. WebAPI.Controllers.V1, the namespace for the Loginapicontroller with version number V2 is defined as XXX. WebAPI.Controllers.V2, and so on,

The client adds parameter versoin=v1/v2 to the header ... You can specify that you use different versions of the API.

E-Commerce System Architecture Summary 4 (WEBAPI version control)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.