Miroslav Holec

Software & Cloud Architect

miroslavholec.cz / blog / nastaveni-json-formatteru-v-api-dle-klienta

Nastavení JSON formatteru v API dle klienta

Miroslav Holec

Miroslav Holec

Publikován 16. března 2016 , aktualizace: 21. září 2016

Stalo se vám, že jste potřebovali vracet JSON data v odlišném formátu podle toho, jaký klient se dotazuje na vaše API? Pokud ano, velmi snadno se dá tento "problém" vyřešit pomocí ActionFilter atributu a dodatečné konfigurace controlleru.

Problém

Máme dva klienty, například mobilní aplikaci z roku 2012, která v minulosti konzumovala JSON data ve formátu:

{
	"FirstName" : "Miroslav",
	"LastName" : "Holec"
}

Píše se rok 2016 a vzniká nové API, které bude po vzoru JavaScript konvencí vracet lowerCamelCase JSON:

{
	"firstName" : "Miroslav",
	"lastName" : "Holec"
}

Problém je, že globální změna v API by znemožnila správnou funkci ve starých klientech z roku 2012, které má plno uživatelů nainstalováno v mobilních zařízeních. Jak nastavit API aby uspokojilo všechny klienty?

Řešení

Předpokladem pro řešení je schopnost rozlišit, jaký klient se dotazuje na data. Obvykle máme podobnou informaci přímo v Requestu. Může to být querystring, hlavička, IP adresa nebo jiný příznak. Pokud tuto informaci nemáme, prohlásíme všechny stávající klienty jako legacy a novým přidáme povinnost uvádět verzi API (například v hlavičce).

Pak už si stačí napsat jednoduchý atribut, který na základě requestu nakonfiguruje vhodný formatter.

[FormatterController]
public class MyController : ApiController
{
}

public class FormatterControllerAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var queryParameters = actionContext.Request.GetQueryNameValuePairs().ToList();
        var apiKey = queryParameters.FirstOrDefault(x => x.Key.Equals("API_KEY", StringComparison.InvariantCultureIgnoreCase));

        // pokud se nejedna o stara API calls, ktere pouzivaji API_KEY, nastavi se novy formatter
        if (apiKey.Value != "holec9876api_key_xxxxxxxxxxxxxxxx")
        {
            actionContext.ControllerContext.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        }

        base.OnActionExecuting(actionContext);
    }
}

A to je celé řešení. Právě actionContext.ControllerContext.Configuration nám poskytuje možnost dodatečně nakonfigurovat controller podle potřeby.

Školení ASP.NET Core a Entity Framework Core

Budoucnost platformy .NET bude patřit technologiím ASP.NET Core a EF Core. Přijďte se naučit tyto moderní technologie používat na mém praktickém školení.

6.11.2017 - 8.11.2017 ASP.NET Core MVC
20.11.2017 - 21.11.2017 Entity Framework Core