11

环境是 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) { ... } }

我对如何开始实现完整的 API 集非常迷茫。我已经阅读了关于“创建您的第一个 web 服务”的第一个第二个wiki 页面,我已将其复制以制作 1 个服务方法。但现在我想做 10 或 40 种服务方法,但我不知道该怎么做。

我注意到实现 fromIRestService<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) { }
}

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

关于追求严格的 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; }
}

我希望每个[Route("path")]人都使用不同的方法,而不是让它们全部解析Execute()并解析哪个字符串不为空或不为空。


我的解决方案

我决定采纳 Rickard 的建议并制作一个合适的 REST API,因为它最终看起来更简单、更干净。

现在这是我使用新 ServiceStack API 的课程(截至 2012 年 9 月 24 日是新的)

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;
        }
    }
}
4

2 回答 2

11

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

@Rickard 提出了很多关于如何重新构建服务的要点,使其更加符合 REST,现在使用 ServiceStack 的新 API 更容易实现,该 API 现在限制更少,更灵活,同一服务可以处理多个不同的请求 DTO并且您不再受限于可以返回的响应类型。

于 2012-09-24T07:59:58.127 回答
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}

等等

要在 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; }
}
于 2012-09-23T19:23:00.747 回答