如何使用restful API实现对象属性更新?
使用ServiceStack(面向消息的RESTfulWeb服务)实现对象属性更新的正确方法是什么 如果客户端需要更新Foo.bar并且只有Foo的id 我应该接受包含Foo id和Foo.bar值的FooBarUpdate请求对象吗? 这意味着我必须为每个属性更新创建单独的请求,或者至少为那些我希望更新的属性(或它们的组合)创建单独的请求。这似乎也不符合RESTful标准 或者,如果我接受一个包含整个具有更新属性的Foo的Foo请求对象,那么客户端首先需要检索Foo,然后服务将检查哪些属性已更新。这似乎是不必要的开销 最后,如果我接受一个Foo请求,但只使用id和修改的属性值(Foo.bar),那么Foo对象是不完整的,根据其他帖子,这可能会导致混淆,因为有人认为它是完整的对象。如何处理RESTful更新: 如果如何使用restful API实现对象属性更新?,rest,
servicestack,updates,Rest,
servicestack,Updates,使用ServiceStack(面向消息的RESTfulWeb服务)实现对象属性更新的正确方法是什么 如果客户端需要更新Foo.bar并且只有Foo的id 我应该接受包含Foo id和Foo.bar值的FooBarUpdate请求对象吗? 这意味着我必须为每个属性更新创建单独的请求,或者至少为那些我希望更新的属性(或它们的组合)创建单独的请求。这似乎也不符合RESTful标准 或者,如果我接受一个包含整个具有更新属性的Foo的Foo请求对象,那么客户端首先需要检索Foo,然后服务将检查哪些属性已更
Bar
是Foo
上的一个单独属性,那么就没有理由不让一个updateforequest
包含更新的Bar
像这样:
[Route(“/foo/{Id}”,“POST”)]
公共类UpdateForeQuest
{
公共int Id{get;set;}
公共条{get;set;}
}
但是,如果Bar
是一个集合,那么Foo是:
公共类Foo
{
公共int Id{get;set;}
公共条[]条{get;set;}
}
然后,更新Foo
上的Bar
项的更安全的方法是通过Foo
路径引用Bar
的实例。但您需要知道该条的id(或集合中与其Foo
相关的索引)
[路由(“/foo/{FooId}/bar/{Id}”,“POST”)]
公共类UpdateForRequest:Bar
{
公共int FooId{get;set;}
}
在服务器上处理部分更新 为解决这些问题: 或者,如果我接受一个
Foo
请求对象,该对象包含具有更新属性的整个Foo,则客户端首先需要检索Foo,然后服务将检查哪些属性已更新。这似乎是不必要的开销
你唯一需要关心整个Foo
的时间是在创建Foo
时,它会有自己的路线。所以这里应该没有什么可担心的
[路线(“/foo”,“POST”)]
公共类CreateFooRequest
{
...
}
更新Foo
时,您将发布到一个现有的Foo路由,如下/Foo/123
:
[Route(“/foo/{Id}”,“POST”)]
公共类UpdateForeQuest
{
公共int Id{get;set;}
...
}
最终,您的服务应该能够指示ORM只更新请求中包含的字段以及更改。因此,如果请求只有几个更改,那么ORM将处理这些更改
例如,ORMLite更新简单如下:
db.Update(updateForeQuest);
这将仅使用在请求中找到的字段,在由Id
标识的行上创建SQLUPDATE
如果发送了一个完整的Foo
,则允许ORM将其视为更改了许多字段,记录将被覆盖。正如您所建议的,您可以在更新之前查找记录并确定更改的字段,但正如您所说,这是不必要的开销
通常,如果更新方法处理部分更改,那么发送整个Foo
应该没有问题,但理想情况下,客户端应该只发送更改
最后,如果我接受一个Foo请求,但只有id和修改后的属性值(Foo.bar),那么Foo对象是不完整的,根据其他帖子,这可能会导致混淆,有人认为它是一个完整的对象
最后一行有人假设它是一个完整的对象,这有点令人担忧。更新路由应仅用于更新,您不应在此处使用完整对象。update方法应该期望请求Foo
是部分的,并按照上面的解释进行处理
我认为您可能应该看到一些很好的例子,说明如何将部分更新应用于现有数据。虽然没有必要选择ORM,但基本概念适用于其他ORM,我认为这很好地说明了它们
按名称更新
Foo
上集合中的项目Bar
:
那样做很不传统。使用具有含义的值(如名称)的缺点是,您无法轻松更改此属性,因为它是一个标识符。如果它是静态的,那么就可以了
所以Foo
看起来像这样:
db.Update(updateBarRequest, p => p.FooId == updateBarRequest.FooId && p.Name == updateBarRequest.Name);
公共类Foo
{
公共int Id{get;set;}
公共条[]条{get;set;}
}
让我们假设Bar
公共类栏
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共int Baz{get;set;}
公共布尔值已启用{get;set;}
}
如果我正在使用条形图的Name
而不是Id
进行更新,则无法更改Name
属性,因为这样我就不知道要更新哪个条形图。我现在需要一条全新的路线来处理酒吧名称的变更
如果您决定将其用作集合中的标识符,您可以执行以下操作:
[路由(“/foo/{FooId}/bar/{Name}”,“POST”)]
公共类UpdateForRequest:Bar
{
公共int FooId{get;set;}
}
因此,要在名为“Bob”的条上用更新的Baz=13
和IsEnabled=false
更新Foo 123
POST/foo/123/bar/Bob
{
巴兹:13,,
我被逮到了:错
}
在y