目的
ASP.NET Coreでjson-rpcを用いたAPIを作りたい
方法
既存のライブラリedjCase/JsonRPCを使う
作ってみる
ドキュメントをもとに作成
Program.cs
using EdjCase.JsonRpc.Router.Defaults;
using EdjCase.JsonRpc.Router;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddJsonRpc(config =>
{
config.BatchRequestLimit = 10;
config.ShowServerExceptions = true;
config.JsonSerializerSettings = new System.Text.Json.JsonSerializerOptions
{
WriteIndented = true
};
config.OnInvokeException = (context) =>
{
if (context.Exception is InvalidOperationException)
{
int customErrorCode = 1;
var customData = new
{
Field = "Value"
};
var response = new RpcMethodErrorResult(customErrorCode, "Custom message", customData);
return OnExceptionResult.UseObjectResponse(response);
}
//Continue to throw the exception
return OnExceptionResult.DontHandle();
};
}).AddAuthorization().AddAuthentication();
var app = builder.Build();
app.UseJsonRpc();
app.Run();
TestController.cs
using EdjCase.JsonRpc.Router;
using EdjCase.JsonRpc.Router.Abstractions;
namespace jsonrpctest.Controllers
{
[RpcRoute("/api/test")]
public class TestController: RpcController
{
public async Task<string> HelloWorld()
{
await Task.Delay(1000); // 非同期実行の確認のため1秒ウエイト
return "Hello World!";
}
public async Task<int> Add(int a, int b)
{
await Task.Delay(1000); // 非同期実行の確認のため1秒ウエイト
return a + b;
}
}
}
試してみる
Azure(AppService)に公開してアクセスしてみた。
→普通に動いた。メソッドを3回コールしたが、1秒ちょっとでレスポンスが帰ってきているので、3回のコールが非同期で並列に実行されることがわかる
わかったこと
- クラス名/メソッド名で自動でマッピングし、対応するメソッドをコールしてくれる
- バッチリクエストも非同期で実行してくれる
このライブラリの懸念点
- セッションやサーバ変数をとれるような作りになってなさそうなので、これらを使用する必要がある場合はこのライブラリが使えないかもしれない
- 入力値のバリデーションを自分でやらないといけない(REST APIの場合はモデル検証でやれそう)→FluentValidationなどを使用すれば可能
- 冪等性を担保する方法としてIdempotencyKeyを設定することがあるが、バッチで処理を行う場合にIdempotencyKeyを各メソッドにつける運用ではうまくいかなさそう(1つ目に実行されるメソッドと2つ目に実行されるメソッドで別の値にする?)
- バッチ全体に対してトランザクションをかけることができなさそう
- 外から拡張してやることを考慮されていないので機能追加が難しい→folkして改造すればいいが保守性が。。
ほか
vs-StreamJsonRpcを使うか