1

ServiceStack フレームワークを使用して RESTful API を構築しています。更新が必要なリソースの多くは非常に大きく、クラスごとに最大 40 個の属性があるため、リソース全体を置き換えるのではなく、部分的な更新を行いたいと考えています。多くの場合、クライアントは 40 個の属性のうち 1 つまたは 2 つの属性のみを更新する必要があるため、いくつかの属性で構成される JSON 本文のみを送信したいと考えています。

属性のすべての組み合わせが可能であるため、ここで提案されているように、クラスごとに「更新」クラスを作成することは現実的ではありません: https://github.com/ServiceStack/ServiceStack/wiki/New-Api#patch-request-example

Microsoft ASP.NET WebAPI OData パッケージには、クラスのサブセットを取り、このサブセットに基づいてリソースを更新する Delta クラスがあります ( http://www.strathweb.com/2013/01/easy-asp-net- web-api-resource-updates-with-delta/ )。これは私が望んでいる機能です。かなりの数のクラスを使用するため、ジェネリック メソッドが最適です。

基本的に、クラスがある場合

public class MyClass {
   public int a { get; set; }
   public int b { get; set; }
   ...
   public int z { get; set; }
}

MyClass のリソースを body 付きの PATCH リクエストで更新したい

{"a":42,"c":42}

ServiceStack でこれを達成するための標準的または推奨される方法はありますか?

4

2 に答える 2

4

DTO でスカラー値を null 許容として宣言します。これにより、リクエストで実際に送信されたフィールドを特定できます。

public class MyClass {
    public int? a { get; set; }
    public int? b { get; set; }
    public int? c { get; set; }
    // etc.
    // object-type properties are already nullable of course
    public string MyString { get; set; }
}

クライアントが部分的なリクエストを送信すると、次のようになります。

{ "a": 1, "b": 0 }

DTO を調べると、実際に送信されたプロパティを特定できます。

myClass.a == 1
myClass.b == 0
myClass.c == null
myClass.MyString == null
etc.

PATCHDTOのルートを設定し、Patchサービスにメソッドを実装します。

public object Patch(MyClass request)
{
    var existing = GetMyClassObjectFromDatabase();
    existing.PopulateWithNonDefaultValues(request);
    SaveToDatabase(existing);
    ...
}

PopulateWithNonDefaultValuesここで重要です。要求オブジェクトからデータベース エンティティに値をコピーしますが、デフォルト値ではないプロパティのみをコピーします。したがって、値が null の場合、クライアントがその値を送信していないため、値はコピーされません。ただし、ゼロの整数値をコピーすることに注意してください。これは、null 許容 int にしたためです。null 許容 int のデフォルト値は、このメソッドによってゼロではなく null と見なされます。DTO プロパティを null 許容として宣言しても、コードの残りの部分で大きな問題が発生することはありません。

このアプローチは JSON で簡単に機能することに注意してください。XML 要求/応答をサポートする必要がある場合はDataContract/DataMember、null が正しく処理されるように、属性を使用して追加の作業を行う必要がある場合があります。

于 2013-08-21T13:22:55.773 に答える
2

eskerの応答は問題ありませんが、null可能なフィールドには十分ではない可能性があることを付け加えたいと思います-デシリアライザーまたはユーザーがそのnullフィールドを作成したかどうかわからないためです。

1 つのアプローチは、生のリクエストを覗くことです。

別のアプローチは、パッチを適用するフィールドを明確に指定するために、追加のリクエスト (クエリ文字列) パラメーターを提供するようにユーザーに依頼することです。次のようなもの: patch_fields=name,description,field3 このアプローチの利点は、エンド ユーザーがパッチ適用をより詳細に制御でき、誤って値をオーバーライドしないことです (元のエンティティを使用し、いくつかのフィールドをクリアするのを忘れたため)。

于 2014-09-26T00:39:33.767 に答える