yamamoWorks

.NET技術を中心に気まぐれに更新していきます

ASP.NET Core Web APIでSnake Caseに対応する - Body編

こんにちは。最近 Snake Case(スネークケース)という名称である事を知りました。

クラス名や変数名の記法である「PascalCase」や「camelCase」はよく耳にするかと思いますが、他にも色々と名称があるようです。

名称
Upper Camel Case (Pascal Case) FirstName
Lower Camel Case firstName
Snake Case first_name
Screaming Snake Case FIRST_NAME
Kebab Case first-name
Train Case First-Name

REST APIのJsonレスポンスには「snake_case」が使われることが多い気がします。 今回はASP.NET CoreでWeb APIを作成した際に「snake_case」をスマートに適応する方法を紹介します。

前提

こんなWeb APIがあったとします。

[ApiController]
public class UsersController : ControllerBase
{
    // GET: api/users/001
    [HttpGet("{userId}")]
    public ActionResult<User> Get(string userId)
    {
        return Ok(new User { UserId = userId, FirstName = "Taro", LastName = "Yamada" });
    }
}

public class User
{
    public string UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

標準ではレスポンスはこうなります。

{
    userId: "001",
    firstName: "Taro",
    lastName: "Yamada"
}

レスポンスに「snake_case」を適応する

モデルクラスのプロパティ名自体を「snake_case」に変える、または定義にJsonProperty属性を付けてJsonにシリアライズされる際の名前を指定すれば要件は満たされます。 しかし全てのモデルクラスのプロパティに属性を指定するのはスマートではありません。

// プロパティ名をsnake_caseに変える → 論外
public string user_id { get; set; }

// 属性で名前を指定する → 大変
[JsonProperty("user_id")]
public string UserId { get; set; }

全てのレスポンスに「snake_case」が自動で適応されるようにStartupクラスのConfigureServicesメソッドでJsonのシリアライズ設定でSnakeCaseNamingStrategyを指定します。

services.AddMvc()
    .AddJsonOptions(options => 
        options.SerializerSettings.ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() });

これで「snake_case」が適応されます。

{
    user_id: "001",
    first_name: "Taro",
    last_name: "Yamada"
}

次回はクエリパラメータの対応です。