11

環境は、Visual Studio 2012、ServiceStack、ASP.NET Webアプリケーションプロジェクト(https://github.com/ServiceStack/ServiceStack/wiki/Create-your-first-webserviceに続く)です。

ServiceStack.Examplesのいくつかのクラスを見ると、ほとんどのサービスに1つのメソッドしか含まれていないことがわかりました。Execute()のオーバーライド、またはRESTサービスの場合はオーバーライドのいずれかOnPost/Get/Put/Delete()

RegisterUser()実装する必要のある関数が数十ある場合、完全なAPIセットを作成するにはどうすればよいですか、、、RemoveUser()...メソッドごとAddFriend()RemoveFriend()1つのサービスですか?

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セットの実装を開始する方法にかなり迷っています。1つのサービスメソッドを作成するためにコピーした「最初のWebサービスの作成」の最初2番目のwikiページを読みました。しかし、今は10または40のサービスメソッドを作成したいのですが、その方法がわかりません。

fromを実装すると、各メソッドが異なるHTTP動詞に対応するという理由だけIRestService<T>で、1つのメソッドではなく最大4つのメソッドが可能になることに気付きました。Execute()それで、私が書くことができるようなものはありますか?基本的に次のようなものです。

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

1つのサービスクラスにすべてのメソッドが含まれている必要はないが、合理的に可能な限り多くのメソッドを探しているだけです...サービスメソッドごとに1つのサービスを作成する必要がありますか?

厳密にRESTfulなアーキテクチャを追求する際の注意:RESTについては少しだけ読んでいますが、次のようなルールに厳密に従う必要があるようです:モデルを再設計する必要がある場合でも、すべてをリソースとして扱います。 URL名(RESTはOnGet()、OnPost()、OnPut()、およびOnDelete()を提供するため、/GetFriendsではなく/Friends...基本的に私は最も簡単で迅速かつ最も苦痛のない実装方法に興味があります数十のサービス方法。これは個人的なプロジェクトであるため、要件はそれほど変わりません。

この最初のステップを案内してくれてありがとう。

編集:この関連する質問を見たばかりです:ServiceStackを使用してコマンドを送信する方法は?

Mythz氏は、設計するための「ServiceStackの方法」はないと述べました。男の質問は私のものとほとんど同じです。サービスに多くのサービスメソッドをスタックする方法を考えています。

編集2:サービススタックの実装、および個別のサービススタックサービスまたは結合されたサービススタックサービスに関するヘルプが必要ですか?

以下のコードを作業ルートで正常にテストしました。

[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()を解析して、どの文字列がnullまたは空でないかを解析するのではなく、それぞれが異なるメソッドに移動することです。


私の解決策

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

これは、(v3.9.15+) でリリースされたServiceStack の新しい API 設計により、はるかに簡単になりました。

@Rickard は、サービスを再構築する方法について多くの良い点を指摘しています。これにより、同じサービスが複数の異なる要求 DTO を処理できるようになり、制限が少なく柔軟になった ServiceStack の新しい API で実現しやすくなりました。返すことができる応答タイプに制限されなくなりました。

于 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 に答える