服务堆栈将RPC迁移到REST问题

时间:2012-08-09 19:50:42

标签: servicestack

尝试与管理团队一起从传统的ASP.Net / SOAP Web服务向ServiceStack出售。

我正在努力解决一些RPC问题。要求是我支持SOAP(甚至反过来),希望在REST上销售我的服务消费者。

以一个名为“ReplaceItem”的服务为例,它基本上需要:

  1. 关闭商品编号
  2. 更换项目编号
  3. 商店号码
  4. 一堆其他替换物品数据
  5. 我应该创建ReplacementItem DTO吗?似乎如果我有这些类型的函数,我将会有大量的DTO而不是大量的RPC方法。在这种情况下,什么是“id”以及我将使用什么REST方法?

    我得到REST / SS为域级结构(如Items / Customers / etc)提供了基本的CRUD功能,但是如何处理SS中的非CRUD方法。

    我也遇到了构成某项服务主键的多个参数的问题。几乎所有库存表都由项目编号和商店编号构成。我宁愿不在服务客户端上转储创建一些复合字符串。我该如何处理?

    感谢。

2 个答案:

答案 0 :(得分:1)

ServiceStack提升了基于消息的SOA设计,这种设计是最佳的provides many natural benefits for remote services

我最初的想法看起来像

  1. POST {CloseItemNumber} / item / 1 / close
  2. POST {ItemNumber} / item / 1?replace = true
  3. POST {ItemNumber} / item / 1
  4. POST {ItemNumber} / item / 1,即相同的DTO /服务不同的值。
  5. 其中ItemNumberCloseItemNumber是单独的请求DTO和服务。

    设计服务API

    我更喜欢围绕'资源/名词'构建我的服务,并将我的服务API设计为对其应用操作的操作。

    如果操作需要的信息多于存储资源DTO的信息,我会使用其他元数据创建单独的服务。

    即。以下是我将Amazons的RPC服务转换为REST-ful的方式:

    https://ec2.amazonaws.com/?Action=AttachVolume
    &VolumeId=vol-4d826724
    &InstanceId=i-6058a509
    &Device=/dev/sdh
    &AUTHPARAMS
    

    我更喜欢写它:

    POST https://ec2.amazonaws.com/volumes/vol-4d826724/attach 
    FormData: InstanceId=i-6058a509&Device=/dev/sdh&AUTHPARAMS
    

    哪个仍会使用明确的 AttachVolume 请求DTO。

    我用来展示WCF RPC和ServiceStack粗粒度基于消息的方法之间的不同的另一个例子是:https://gist.github.com/1386381

    RPC-chatty和基于消息的API之间的区别:

    这是WCF鼓励的典型API:

    public interface IService
    {
      Customer GetCustomerById(int id);
      Customer[] GetCustomerByIds(int[] id);
      Customer GetCustomerByUserName(string userName);
      Customer[] GetCustomerByUserNames(string[] userNames);
      Customer GetCustomerByEmail(string email);
      Customer[] GetCustomerByEmails(string[] emails);
    }
    

    这是我们在ServiceStack中鼓励的基于消息的等效API:

    public class Customers {
       int[] Ids;
       string[] UserNames;
       string[] Emails;
    }
    
    public class CustomersResponse {
       Customer[] Results;
    }
    

    注意:如果您希望相同的服务同时支持SOAP和基于REST的API,则需要structure your services slightly differently来克服SOAP通过HTTP POST隧道传输所有操作的限制。

答案 1 :(得分:1)

当我决定从1个繁琐的RPC api切换到REST api时,我仍然遇到的问题是,我发现自己只有2个解决方案,而不是有几个功能:

  1. 将DTO和服务相乘,使服务的内部代码变得繁琐复杂 或
  2. 将所有管理服务的代码放入单一路径(OnGet),但这样我必须解析不同的参数以'发现'已经请求了哪些参数(以简化而不是使用具有预定义参数的多个简单函数)我现在只有一个函数必须确定哪些参数有意义...但这很难维护 - 现在代码对我来说更复杂了。
  3. 在解决GetCustomerById,GetCustomersByEmails等提出的解决方案中,对我而言,我们现在必须根据填充的参数动态构造查询,而不是简单查询,这会使代码变得棘手且难以维护 - 必须管理多个参数的可能组合 - 某些组合也是不可能的。

    感觉有点难过,因为我真的不喜欢WCF。 混合WCF和REST似乎是复杂性的总和 - 对我来说最糟糕(定义REST api的复杂性+ WCF的复杂性)。

    我的感受是分享的还是我错过了什么?