💻
可変キーのJSONをSwaggerとC#でモデリングする方法
可変キーのJSONとは
ここではJSONの構造としてキーが動的に変わることを指しています。
例えば、キー自体が商品IDとなるオブジェクトで、その属性として、商品名や価格などが含まれる場合です。
"inheritsOrdetItems": {
"{!商品ID}": {
"itemName": "りんご",
"itemPrice": 250
},
"{!商品ID}": {
"itemName": "ばなな",
"itemPrice": 150
},
"{!商品ID}": {
"itemName": "みかん",
"itemPrice": 300
}
}
Swaggerにはどう定義するの?
Swaggerに可変キーを持つオブジェクトを定義する場合、additionalProperties を使用します。
Swagger.yaml
inheritsOrdetItems:
type: object
additionalProperties:
type: object
description: 商品ID ※このキーは可変
properties:
itemName:
type: string
description: 商品名
example: りんご
itemPrice:
type: integer
description: 価格
example: 250
format: int32
上記の定義により、inheritsOrdetItems はどんなキー名も受け入れることができ、そのキーの値は指定された形式のオブジェクトとしています。
また、Swagger UI上では additionalProp1~3 と表記されるため、Swagger.yaml の description 定義にキーが可変である旨記載しておくと良いでしょう。
{
"inheritsOrdetItems": {
"additionalProp1": {
"itemName": "りんご",
"itemPrice": 250
},
"additionalProp2": {
"itemName": "りんご",
"itemPrice": 250
},
"additionalProp3": {
"itemName": "りんご",
"itemPrice": 250
}
}
}
C#で値を受け取るモデルクラスの構造はどうなるの?
可変キーを持つオブジェクトを .NET で受け取るには Dictionary を使ってモデルを定義します。
csharp
using System.Collections.Generic;
namespace AdditionalPropertiesJson
{
public class InheritsOrdetItem
{
public Dictionary<string, ItemDetail> InheritsOrdetItems { get; set; }
}
public class ItemDetail
{
public string ItemName { get; set; }
public int ItemPrice { get; set; }
}
}
- InheritsOrdetItems はキーが文字列で、値が ItemDetail オブジェクトの辞書(Dictionary<string, ItemDetail>)型として定義しています。
- ItemDetail クラスは itemName と itemPrice の2つのプロパティを持っています。
値の設定は下記のように行います。
csharp
using System;
using System.Collections.Generic;
namespace AdditionalPropertiesJson
{
class Program
{
static void Main(string[] args)
{
var response = new HogeResponse
{
InheritsOrdetItems = new Dictionary<string, ItemDetail>
{
{ "SampleKey01", new ItemDetail { ItemName = "りんご", ItemPrice = 250 } },
{ "SampleKey02", new ItemDetail { ItemName = "バナナ", ItemPrice = 150 } },
{ "SampleKey03", new ItemDetail { ItemName = "オレンジ", ItemPrice = 200 } }
}
};
// 値が正しくセットされているか確認するための出力
foreach (var item in response.InheritsOrdetItems)
{
Console.WriteLine($"{item.Key} -> Name: {item.Value.ItemName}, Price: {item.Value.ItemPrice}");
}
}
}
public class HogeResponse
{
public Dictionary<string, ItemDetail> InheritsOrdetItems { get; set; }
}
public class ItemDetail
{
public string ItemName { get; set; }
public int ItemPrice { get; set; }
}
}
記事内のソースコードはGitに登録しています。
Discussion