Strawberry Shake (.NET) で GraphQL #4 GraphQL の型とのマッピングのカスタマイズ
Strawberry Shake (.NET) で GraphQL #4 GraphQL の型とのマッピングのカスタマイズ
- Strawberry Shake (.NET) で GraphQL #1 こと始め
- Strawberr yShake (.NET) で GraphQL #2 JetBrains Rider 編
- Strawberry Shake (.NET) で GraphQL #3 Shopify につなぐ
- Strawberry Shake (.NET) で GraphQL #4 GraphQL の型とのマッピングのカスタマイズ
- Strawberry Shake (.NET) で GraphQL #5 GraphQL union の利用
前回 GraphQL に Strawberry Shake を利用して Shopify の API を呼び出すことができましたが、うまくいかないケースもあったことを説明しました。今回はその対処方法その一です。
うまくいかなかったケース
次のように Shopify から商品の価格も含めて取得します。(Shopify に限らず、価格は商品だけでなく、サイズなどでも変化するため、商品の Variant
が必要です)
query GetProducts {
products(first: 100) {
edges {
node {
id
title
variants(first: 100) {
edges {
node {
id
title
price {
amount
}
}
}
}
}
}
}
}
Rider での .graphql
ファイルの実行は問題はないのですが、次のように .NET Decimal
型への変換に失敗します。
レスポンスを確認すると、該当のプロパティ (価格) がレスポンスの JSON は string
型でした。123.00
ではなく、"123.00"
となっています。ここで変換ができなかったようです。
マッピングのカスタマイズ
GraphQL は型を自由に作ることができます。Shopify のスキーマを読むと、Decimal
型が宣言されています。Strawberry Shake はソースコードを自動生成しますので、Strawberry Shake 流の対処方法が必要になります。
まずは .NET String
<-> .NET Decimal
のコンバーターを書きます。
using StrawberryShake.Serialization;
namespace ConsoleApp1;
internal class String2DecimalSerializer() : ScalarSerializer<string, decimal>(BuiltInScalarNames.Decimal)
{
public override decimal Parse(string serializedValue)
{
return decimal.Parse(serializedValue);
}
protected override string Format(decimal runtimeValue)
{
return runtimeValue.ToString();
}
}
Program.cs
のサービスの構成にこのコンバーターを追加します。
// ...
serviceCollection.AddSerializer<String2DecimalSerializer>();
var services = serviceCollection.BuildServiceProvider();
// ...
そして、schema.extensions.graphql
ファイルに追加で GraphQL の Decimal
型をこのコンバーターを利用するようにします。次の内容を追記してください。
extend scalar Decimal
@serializationType(name: "global::System.String")
@runtimeType(name: "global::System.Decimal")
これでちゃんと動くようになりました。
詳しい方法やそれ以外のマッピングも含めて公式ドキュメントの Scalars に書いてあります。
最後に
Strawberry Shake は自動生成を伴うので、何か問題が起きたときの対処が StrawberryShake 流の解決方法を調べる必要があります。このあたりは自前でコードを書くスタイルのライブラリの方がやりやすいですよね。
次回はもう一つはまった GraphQL union の扱いです。
Discussion