Почему ServiceStack обременяет DTO проблемами маршрутизации? - PullRequest
2 голосов
/ 14 апреля 2020

Я изучаю ServiceStack, и после прочтения этой страницы мне кое-что не ясно.

Итак, учитывая эту пару DTO:

    [Route("/hello")]
    [Route("/hello/{Name}")]
    public class Hello : IReturn<HelloResponse>
    {
        public string Name { get; set; }
    }

    public class HelloResponse
    {
        public string Result { get; set; }
    }

И этот сервис:

    public class MyService : Service
    {
        public object Any(Hello request)
        {
            return new HelloResponse { Result = $"Hello, {request.Name}!" };
        }
    }

Почему Hello отвечает за указание типа возврата с помощью интерфейса маркера IReturn<HelloResponse>?

Похоже, это так может быть выведен из типа возврата MyService - за исключением того, что обычно используется тип возврата object, что также требует приведения типов в тестах и ​​клиентском коде. Почему?

И почему атрибуты Route применяются к модели Hello, а не к службе MyService, где запрос фактически обрабатывается?

Кажется, что оба из этих фактов больше относятся к сервису, чем к модели.

Например, человек, читающий декларацию сервиса, с большей готовностью найдет информацию, относящуюся к сервису, вместо того, чтобы искать ее в модели.

С другой стороны, принятые методы HTTP неявно объявляются службой через соглашения о присвоении имен методам, поэтому кажется, что факты о маршрутизации / диспетчеризации службы разбросаны между двумя уровнями.

От с этой точки зрения, я, вероятно, ожидал чего-то большего в соответствии с этим:

    // NON-VALID EXAMPLE

    public class Hello
    {
        public string Name { get; set; }
    }

    public class HelloResponse
    {
        public string Result { get; set; }
    }

    public class MyService : Service
    {
        [Route("/hello")]
        [Route("/hello/{Name}")]
        public HelloResponse Any(Hello request)
        {
            return new HelloResponse { Result = $"Hello, {request.Name}!" };
        }
    }

В чем причина или дизайн мышления, стоящий за конвенциями?

(Пожалуйста, не принимайте это всего лишь попытка критики - мне очень нравится эта концепция, и я искренне пытаюсь понять ее. подписи за этими соглашениями.)

1 Ответ

2 голосов
/ 14 апреля 2020

Почему ServiceStack обременяет DTO проблемами маршрутизации?

Обратите внимание, что в ServiceStack не требуется никакой нагрузки, связанной с маршрутизацией, и все пользовательские маршруты являются необязательными, когда все клиенты могут Сервисы вызовов используют свои автоматические c предопределенные маршруты .

Почему Hello отвечает за указание типа возврата с помощью интерфейса маркера IReturn?

Он обеспечивает лучший типизированный доступ для клиентских библиотек, таких как generi c C # /. NET Сервисные клиенты , которые могут повторно использовать существующие DTO SericeModel для включения его оптимальной типизации. API без какого-либо кода, например:

var client = new JsonServiceClient(baseUrl);
var response = client.Get(new Hello { Name = "World" });

Или, если вы не делитесь DTO, это также полезно для Добавить ссылку на ServiceStack Reference , а также клиентов.

Тип возврата для вашей реализации Сервиса в ServiceStack не имеет смысла, т. Е. Не имеет поведенческих различий и не позволяет той же реализации Сервиса возвращать один и тот же Ответный DTO или украшать пользовательским HTTP-ответом, например:

public object Any(Hello request)
{
    return new HelloResponse { Result = $"Hello, {request.Name}!" };
    //...
    return new HttpResult(new HelloResponse { Result = $"Hello, {request.Name}!" }) {
      //... custom
    };
}

оба типа возврата соответствуют контракту API IReturn<HelloResponse>

Это полезно только для вызова межпроцессных Сервисов с использованием более старого метода ResolveService, но для запросов между процессами рекомендуется использовать Service Gateway , который также использует маркеры интерфейса типа IReturn<T> для своих Typed API.

Маршруты не являются деталями реализации, они не входят в ваш опубликованный c Договор на обслуживание и должны быть помечены в ваших DTO, которые используются для определения вашего Договора на обслуживание.

[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
{
    public string Name { get; set; }
}

public class HelloResponse
{
    public string Result { get; set; }
}

Где они используются. NET Клиентами ServiceStack отправлять запросы клиентов службы.

var response = client.Get(new Hello { Name = "World" });

Для другого принимаются принятые методы HTTP Он был объявлен службой в соответствии с соглашениями об именах методов - поэтому кажется, что факты о маршрутизации / диспетчеризации службы разбросаны между двумя уровнями.

Пожалуйста, смотрите документы по Маршрутизация определение Маршрута определяет, на каких методах активен указанный маршрут c, в то время как наиболее подходящая реализация Сервиса вызывается в зависимости от Запроса, например:

public object GetJson(Customers request) => ... // ONLY GET JSON Requests
public object Get(Customers request) => ...     // All other GET Requests
public object Post(Customers request) => ...    // ONLY POST Requests
public object Any(Customers request) => ...     // ALL other Requests

В чем причина или дизайн размышляя о соглашениях?

Многие из этих проблем пытаются размыть явно типизированный сервисный контракт ваших API и его конкретную реализацию, в ServiceStack это отдельные явные концепции, где вся информация о вашей публикации c Договор на обслуживание должен поддерживаться в вашем проекте ServiceModel, не требующем реализации .

Пожалуйста, прочтите Справочные документы , чтобы ознакомиться с целью и целями ServiceStack.

...