Come modificare la versione della tua API Web

Dovresti sempre eseguire la versione della tua API Web mantenendo allo stesso tempo quanto più possibile lo stesso URI. Immagina una situazione in cui hai un'API Web che è attiva e in esecuzione in produzione e viene utilizzata dagli utenti. Supponiamo ora di aver bisogno di più funzionalità nell'API Web ma di mantenere intatta la funzionalità esistente. Potresti avere alcuni utenti che hanno ancora bisogno della vecchia API, mentre altri avranno bisogno di una versione con funzionalità nuove o estese. Questo è esattamente il punto in cui il controllo delle versioni dell'API Web viene in soccorso.

Puoi eseguire la versione della tua API Web in uno dei seguenti modi:

  1. Usa URL: le informazioni sulla versione sono specificate nell'URL come stringa di query.
  2. Usa intestazioni di richiesta personalizzate: le informazioni sulla versione del controller sono specificate nell'intestazione della richiesta, senza la necessità di modifiche all'URL.
  3. Usa intestazioni di accettazione: le intestazioni di accettazione generalmente definiscono il tipo di supporto e le codifiche dei caratteri. È possibile passare le informazioni sulla versione per l'API Web tramite le intestazioni di accettazione senza dover modificare l'URL.

Controllo delle versioni dell'API Web tramite URL

Considera i seguenti controller API Web, che sono stati rispettivamente denominati  AuthorsV1Controllere AuthorsV2Controller.

public class AuthorsV1Controller: ApiController

    {

        [HttpGet]

        public IEnumerable GetAuthors ()

        {

          restituisce una nuova stringa [] {"Joydip Kanjilal", "Gerben Wierda"};

        }

    }

public class AuthorsV2Controller: ApiController

    {

        [HttpGet]

        public IEnumerable GetAuthors ()

        {

            restituisci nuova stringa [] {"Joydip Kanjilal, INDIA", "Gerben Wierda, Paesi Bassi"};

        }

    }

Per semplificare questa illustrazione, ho incorporato un metodo denominato GetAuthors()in ogni controller. Mentre GetAuthors()in AuthorsV1Controllerrestituisce solo i nomi degli autori, GetAuthors()in AuthorsV2Controller(la nuova versione) restituisce i nomi degli autori insieme ai nomi dei paesi in cui risiedono gli autori.

Il frammento di codice seguente mostra come i due controller usano il metodo Register della WebApiConfigclasse.

config.Routes.MapHttpRoute (

                nome: "WebAPIV1",

                routeTemplate: "api / v1 / {controller} / {id}",

                valori predefiniti: new {controller = "AuthorsV1Controller", action = "GetAuthors", id = RouteParameter.Optional}

            );

config.Routes.MapHttpRoute (

                nome: "WebAPIV2",

                routeTemplate: "api / v2 / {controller} / {id}",

                valori predefiniti: new {controller = "AuthorsV2Controller", action = "GetAuthors", id = RouteParameter.Optional}

            );

È ora possibile richiamare il metodo API Web GetAuthorsutilizzando il seguente URL.

// localhost / WebAPI / api / v1 / Authors / GetAuthors

Controllo delle versioni dell'API Web utilizzando l'intestazione della richiesta

È inoltre possibile implementare il controllo delle versioni dell'API Web utilizzando l'intestazione della richiesta. Per ottenere ciò, è necessario implementare una classe personalizzata che estende la DefaultHttpControllerSelectorclasse, quindi eseguire l'override SelectControllernella classe personalizzata. Notare che la DefaultHttpControllerSelectorclasse implementa l' IHttpControllerSelectorinterfaccia. SelectControllerchiama GetControllerNameinternamente e accetta un'istanza di HttpRequestMessagecome parametro.

Il frammento di codice seguente illustra come recuperare le informazioni sulla versione dall'intestazione della richiesta.

stringa privata GetControllerVersionFromRequestHeader (richiesta HttpRequestMessage)

        {

            var acceptHeader = request.Headers.Accept;

            const string headerName = "Versione";

            string controllerVersion = string.Empty;

            if (request.Headers.Contains (headerName))

            {

                controllerVersion = "V" + request.Headers.GetValues ​​(headerName) .First ();               

            }

            return controllerVersion;

        }

Controllo delle versioni dell'API Web utilizzando l'intestazione di accettazione

Il metodo seguente mostra come recuperare le informazioni sulla versione per l'API Web dall'intestazione di accettazione. Il metodo controlla il tipo MIME e restituisce le informazioni sulla versione in modo appropriato. Se il tipo di supporto non è application/json, la versione predefinita viene restituita come V1.

private string GetControllerVersionFromAcceptHeader(HttpRequestMessage request)

        {

            var acceptHeader = request.Headers.Accept;

            string controllerVersion = string.Empty;

            foreach (var mime in acceptHeader)

            {

                if (mime.MediaType.Equals("application/json"))

                {

                    NameValueHeaderValue version = mime.Parameters.FirstOrDefault(v => v.Name.Equals("Version", StringComparison.OrdinalIgnoreCase));

                    controllerVersion = "V" + version.Value.ToString();

                    return controllerVersion;

                }

            }

            return "V1";

        }

You can invoke your Web API from Fiddler by passing the accept header as shown below.

Accept: application/json; charset=utf-8;version=2

The following code listing illustrates how you can override SelectController to select a controller dynamically. Note how GetControllerVersionFromRequestHeader has been used. If you would like to retrieve the controller version from the accept header, you should leverage GetControllerVersionFromAcceptHeader instead.

public override HttpControllerDescriptor SelectController(HttpRequestMessage request)

        {

            try

            {

                string controllerName = base.GetControllerName(request);

                var controllers = GetControllerMapping();

                var routeData = request.GetRouteData();

                string controllerVersion = GetControllerVersionFromRequestHeader(request);             

                controllerName = String.Format("{0}{1}", controllerName, controllerVersion);

                HttpControllerDescriptor controllerDescriptor;

                if (!controllers.TryGetValue(controllerName, out controllerDescriptor))

                {

                    string message = "No HTTP resource was found that matches the specified request URI {0}";

                    throw new HttpResponseException(request.CreateErrorResponse(System.Net.HttpStatusCode.NotFound, String.Format(message, request.RequestUri)));

                }

                return controllerDescriptor;

            }

            catch (Exception ex)

            {

                throw new HttpResponseException(request.CreateErrorResponse(System.Net.HttpStatusCode.NotFound, String.Format(ex.Message, request.RequestUri)));

            }

        }

You should add the following line in the Register method of the WebApiConfig class to provide support for controller selection at runtime.

config.Services.Replace (typeof (IHttpControllerSelector), new ControllerSelector ((config)));

È ora possibile utilizzare Fiddler per testare l'API Web: utilizzare la scheda Composer di Fiddler e fornire l'URL e le informazioni sulla versione in base alle esigenze. Se desideri che venga richiamata la versione 2 del tuo controller API Web, devi specificare Version: 2quando componi le informazioni dell'intestazione della richiesta nella scheda Composer in Fiddler.