2014-02-11 2 views
3

Я пытаюсь установить шаблон кодирования (некоторые правила) в сервисах, которые мы создаем для нашего бизнеса. Мы следуем основным указаниям, изложенным apigree для проектирования сервисов RESTful.ServiceStack Маршруты и глаголы

Одним из правил, которые мы хотели бы принять, является блокирование определенных комбинаций маршрутов и глаголов, которые мы не хотим поддерживать. Предположительно, мы отправим обратно HttpStatusCode.NotSupported для этих незаконных комбо и, возможно, для чтения человеком?

Законные комбо мы хотим поддержать являются:

GET /resource - lists all resources 
GET /resource/{id} - retrieves specific resource by ID 
POST /resource - adds a new resource 
PUT /resource/{id} - updates specific resource by ID 
DELETE /resource/{id} - deletes specific resource by ID 

Есть некоторые незаконные комбо мы явно не хотят поддерживать.

POST /resource 
PUT /resource 
DELETE /resource 

У нас есть валидаторы для каждого поддерживаемого маршрута. Но у нас нет ни одного из этих незаконных маршрутов, определенных где-либо в нашей кодовой базе.

Из тестирования мы узнали, что если клиент отправляет запрос GET /resource/{id} с пустым идентификатором (String.Empty), то ServiceStack магия не выполняет валидатор для этого запроса (GET /resource/{id}), но вместо этого перенаправляет на GET/ресурса. Мы считаем, что он делает то же самое для DELETE /resource/{id} и PUT /resource/{id}. Но ни одно из этих поведения по умолчанию не является желательным, мы скорее хотим вернуть HttpStatusCode.NotSupported или с некоторым заголовком, направляющим клиент в документацию API (или некоторые такие рекомендации).

Не могли бы вы предложить некоторые варианты для обработки этих случаев явно в рамках?

веселит

ответ

5

Если вы хотите, чтобы соглашения определенных телефонное чем вы должны быть четко в том, что вы позволяете с определениями маршрута, например:

[Route("/resource", "GET")] 
public class GetAllResources {} 

[Route("/resource/{Id}", "GET")] 
public class GetResource 
{ 
    public int? Id { get; set; } 
} 

[Route("/resource", "POST")] 
public class CreateResource { ... } 

[Route("/resource/{Id}", "PUT")] 
public class UpdateResource 
{ 
    public int Id { get; set; } 
    ... 
} 

[Route("/resource/{Id}", "DELETE")] 
public class DeleteResource 
{ 
    public int Id { get; set; } 
    ... 
} 

Чем в вашей службе только соответствовать Глаголам вы «ве указано:

public class ResourceServices : Service 
{ 
    public object Get(GetResources request) { ... } 
    public object Get(GetResource request) { ... } 
    public object Post(CreateResource request) { ... } 
    public object Put(UpdateResource request) { ... } 
    public object Delete(DeleteResource request) { ... } 
} 

Что не соответствует просто будет 404 NotFound, потому что п o соответствующие маршруты, которые будут обрабатывать запрос.

В противном случае вы можете создать услуги специально ловить незаконные запросы и относиться к ним, как вы хотите, например:

[Route("/resource", "DELETE PUT")] 
public class IllegalActions {} 

public class ResourceServices : Service 
{ 
    public object Any(IllegalActions request) 
    { 
     return new HttpError(HttpStatusCode.NotAcceptable, "ActionNotSupported"); 
    } 
} 

Error Handling wiki делает хорошую работу при показе всех настроек ошибок, имеющихся в ServiceStack. Будучи в состоянии отобразить C# Исключения кодов статуса НТТР также могут быть полезны здесь:

SetConfig(new HostConfig { 
    MapExceptionToStatusCode = { 
     { typeof(NotImplementedException), (int)HttpStatusCode.NotAcceptable }, 
     { typeof(NotSupportedException), (int)HttpStatusCode.NotAcceptable }, 
    } 
}); 
+0

Проблема заключается в том, что ваше решение является именно то, что мы имеем (кроме того, что наш Id поля является строка не целое). Проблема в том, что когда мы вызываем GET/resource/{Id}, и идентификатор пуст (т. Е. String.Empty), SS перенаправляет вызов Get/resource, а не 404 или любую другую проверку. Здесь есть какая-то магия. Мы должны контролировать это. –

+0

@JezzSantos Вы имеете в виду 'GET/resource /' redirects? это будет ASP.NET, делающий перенаправление не ServiceStack. Поэтому не полагайтесь на разницу между «GET/resource» и «Get/resource /», они оба должны означать одно и то же, т. Е. ПОЛУЧИТЬ все ресурсы. – mythz

+0

Ах! спасибо, что имеет смысл.Наверное, должен быть какой-то Trim(), идущий где-то в конце маршрута, возможно? –

Смежные вопросы