ServiceStack服务可以包含多种方法吗?

Jas*_*son 11 c# api rest soa servicestack

环境是Visual Studio 2012,ServiceStack,ASP.NET Web应用程序项目(关注https://github.com/ServiceStack/ServiceStack/wiki/Create-your-first-webservice)

通过查看ServiceStack.Examples中的一些类,我注意到大多数服务只包含一个方法.有些覆盖Execute()或者,如果是REST服务,有些覆盖OnPost/Get/Put/Delete().

我应该如何看待做一个完整的API集,如果我有几我需要实现的功能RegisterUser(),RemoveUser(),AddFriend(),RemoveFriend()...每个方法的一个服务?

public RegisterUserService : IService<User> { public object Execute(User> dto) { ... } }
public RemoveUserService : IService<User> { public object Execute(User> dto) { ... } }
public AddFriendService : IService<Friend> { public object Execute(Friend dto) { ... } }
public RemoveFriendService: IService<RequestDTO4> { public object Execute(Friend dto) { ... } }
Run Code Online (Sandbox Code Playgroud)

我很失落如何开始实现完整的API集.我已经阅读了"创建您的第一个Web服务" 的第一个第二个 Wiki页面,我已经复制了该服务方法.但现在我想制作10或40种服务方法,我不知道该怎么做.

我注意到,实现from IRestService<T>允许你最多4个方法而不是一个Execute()方法,因为每个方法对应一个不同的HTTP动词.那么有什么我能写的吗?基本上是这样的:

public MyService : IService/IRestService/ServiceBase?<User>
{
     public object AddUser(User user) { }
     public object RemoveUser(User user) { }
     public object ModifyUser(User user) { }
}
Run Code Online (Sandbox Code Playgroud)

只是寻找一些不一定要包含一个服务类中的所有方法的东西,但是尽可能多的...我真的必须为每个服务方法创建一个服务吗?

关于追求严格RESTful架构的注意事项:我只阅读了一些关于REST的内容,但似乎我必须严格遵守以下规则:即使您必须重新设计模型,也不要将所有内容都视为资源. URL名称(/ Friends,不是/ GetFriends,因为REST给你OnGet(),OnPost(),OnPut()和OnDelete()...基本上我对最简单,最快速,最无痛的实现方式感兴趣几十种服务方法.这是一个个人项目,因此要求不会有太大变化.

在此先感谢您指导我完成第一步.

编辑:刚刚看到这个相关的问题:如何使用ServiceStack发送命令?

Mythz表示没有"ServiceStack方式"来设计.这家伙的问题非常像我的.我想知道如何在服务中堆叠很多服务方法.

编辑2:刚刚看到需要帮助的servicestack实现,以及单独或组合ServiceStack服务?.

我刚用工作路线成功测试了下面的代码:

[Route("/registerUser/setEmail/{Email}")]
[Route("/registerUser/setPassword/{Password}")]
[Route("/registerUser/setPhoneNumber/{PhoneNumber}")]
[Route("/lalal2395823")]
[Route("/test3234/test23423511")]
public class RegisterUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Nickname { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是我想要的是每个[Route("path")]人去一个不同的方法,而不是让他们都解析,Execute()并且必须解析哪个字符串不为null或为空.


我的解决方案

我决定采用Rickard的建议并制作一个合适的REST API,因为它最终看起来更简单,更清洁.

这是我的类使用新的ServiceStack API(截至9/24/12的新版本):

using UserModel = Project.Model.Entities.User;

[Route("/User", "POST")]
[Route("/User/{FirstName}", "POST")]
[Route("/User/{FirstName}/{LastName}", "POST")]
[Route("/User/{FirstName}/{LastName}/{Nickname}", "POST")]
[Route("/User/{FirstName}/{LastName}/{Nickname}/{PhoneNumber}", "POST")]
[Route("/User/{FirstName}/{LastName}/{Nickname}/{PhoneNumber}/{Email}", "POST")]
public class CreateUser : IReturn<UserModel>
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Nickname { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
}

public class CreateUserService : Service
{
   public object Post(CreateUser request)
    {
        try
        {
            using (var session = FluentNHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    var user = new UserModel()
                    {
                        FirstName = request.FirstName,
                        LastName = request.LastName,
                        Nickname = request.Nickname,
                        PhoneNumber = request.PhoneNumber,
                        Email = request.Email,
                        Password = request.Password,
                    };
                    session.SaveOrUpdate(user);
                    transaction.Commit();

                    return user;
                }
            }
        }
        catch
        {
            throw;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

myt*_*thz 11

现在,在(v3.9.15 +)中发布ServiceStack的新API设计,这简单得多了.

@Rickard在如何重新构建您的服务方面提出了很多好处,因此它更加REST-ful现在使用ServiceStack的新API更容易实现,现在这种新API更少限制,更灵活,同一服务可以处理多个不同的请求DTO并且您不再受限于您可以返回的响应类型.

  • 这真太了不起了; 非常感谢您对ServiceStack的贡献. (3认同)

Ric*_*ard 7

遵循HTTP方式,您必须颠倒思维方式.您需要考虑资源,即用户,朋友等.使用HTTP,您已经拥有一组有限的方法,即Get,Put,Post和Delete.

因此,服务API设计可能如下所示:

RegisterUser() => POST /users
RemoveUser() => DELETE /users/{userid}
AddFriend() => POST /users/{userid}/friends
RemoveFriend() => DELETE /users/{userid}/friends/{friendid}
ModifyUser() => PUT /users/{userid}
Run Code Online (Sandbox Code Playgroud)

等等

要在ServiceStack中实现例如RemoveFriend,您可以这样做:

public class UserFriendService : RestServiceBase<UserFriendRequest>
{
    public override object OnPost(UserFriendRequest request)
    {
        // pseudo code 
        var user = GetUser(request.UserId);
        var friend = GetUser(request.FriendId); // FriendId is a field in the HTTP body
        user.Friends.Add(friend);
        return HttpResult.Status201Created(user, ...);
    }
    //...
}

[Route("/users/{userId}/friends")]
public class UserFriendRequest
{
    public string UserId { get; set; }
    public string FriendId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • 嘿@Rickard很有建议!您可能也对ServiceStack的新API设计感兴趣,现在可以更轻松地在同一服务中处理多个请求DTO :) https://github.com/ServiceStack/ServiceStack/wiki/New-API (2认同)