Могут ли Службы ServiceStack содержать несколько методов?


Среда-Visual Studio 2012, ServiceStack, ASP.NET проект веб-приложения (далее https://github.com/ServiceStack/ServiceStack/wiki/Create-your-first-webservice )

Просмотр некоторых классов в ServiceStack.Например, я заметил, что большинство сервисов содержат только один метод. Либо некоторое переопределение на Execute(), либо, если служба REST, некоторое переопределение OnPost/Get/Put/Delete().

Как я должен подходить к созданию полного набора API, если у меня есть десятки функций I потребность реализована 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. Я прочитал первую и вторую вики-страницу "Создание вашего первого веб-сервиса", которую я скопировал, чтобы сделать 1 метод обслуживания. Но теперь я хочу сделать 10 или 40 методов обслуживания, и я не уверен, как это сделать.

Я заметил, что реализация из 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) { }
}

Просто ищет что-то, что не обязательно должно содержать все методы в одном классе обслуживания, но как можно больше ... действительно ли я должен создать 1 сервис для каждого метода обслуживания?

Примечание о следовании строго спокойной архитектуре: я только немного читал об отдыхе, но, похоже, мне придется строго соблюдайте такие правила, как: относитесь ко всему как к ресурсу, даже если вам нужно перепроектировать свои модели, никаких глаголов в именах URL (/Friends, не / GetFriends, потому что REST дает вам OnGet (), OnPost (), OnPut () и OnDelete ()... в основном меня интересует самый простой, быстрый и безболезненный способ реализации нескольких десятков методов обслуживания. Это личный проект, поэтому требования не будут сильно отличаться.

Заранее благодарю вас за то, что вы провели меня через этот первый шаг.

Правка: просто видел этот связанный вопрос: как отправлять команды с помощью ServiceStack?

[14]}Mythz сказал,что нет никакого" сервисного пути " для проектирования. Вопрос этого парня очень похож на мой. Мне интересно, как складывать множество методов обслуживания в сервис.

EDIT 2: Только что увидел нужна помощь по реализации servicestack , и отдельные или комбинированные сервисы ServiceStack?.

Я только что успешно протестировал приведенный ниже код с помощью working маршруты:

[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() и не разбирал, какая строка не является пустой или пустой.


Мое Решение

Я решил последовать совету Рикарда и сделать правильный 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;
        }
    }
}
2 11

2 ответа:

Следуя пути 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}

И т. д.

Для реализации, например, RemoveFriend в ServiceStack можно сделать так:

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

Теперь это намного проще с новым дизайном API ServiceStack , выпущенным в (v3.9.15+).

@Rickard делает много хороших замечаний о том, как переструктурировать свой сервис, чтобы он был более спокойным, что теперь легче достичь с помощью нового API ServiceStack, который теперь менее ограничен и более гибок, когда одна и та же служба может обрабатывать несколько различных DTO запросов, и вы больше не ограничены в типе ответа, который вы можете вернуть.