2015-06-28 5 views
1

Я создаю службу WebAPI для приложения, и я застрял на перекрестке дорог, я понимаю принципы SOLID и хочу реализовать свои услуги WebAPI в соответствии с этими принципами, однако я провел последние пару дней борясь с реализацией и хотели бы получить некоторые советы от сообщества.принцип единой ответственности webapi

The Single Ответственность принцип гласит, что каждый класс должен нести ответственность за одной части функциональных возможностей, предоставляемых программным обеспечением (см Solid Principles)

У меня есть два ApiControllers на данный момент, но будет гораздо больше , и у обоих в настоящее время есть функции Get, Post и Put, но для каждого контроллера также требуется функция поиска, и мой вопрос заключается в том, чтобы методы поиска были перемещены в отдельный ApiController, например, SearchController.

Например:

У меня есть контроллер пользователя

public class UserController : ApiController { 
    Get - returns a User 
    Post and Put - Add and update a User 
} 

и у меня есть контроллер пациента по той же схеме, как описано выше, должны я есть свои методы поиска в каждом контроллере я должен иметь SearchController, например.

public class SearchController : ApiController { 
    SearchUsers() - returns ICollection<User> 
    SearchPatients() - returns ICollection<Patient> 
} 

Я понимаю, что нет однозначного ответа, и будет так же, как некоторые советы по лучшей практике

+1

«Поиск», вероятно, просто GET с фильтром, не так ли? – Padraic

ответ

1

Я хотел бы представить поиск как действие на соответствующем контроллере, и если вы хотите, чтобы отслеживать все контроллеры, которые имеют выполните поиск, поместите на него интерфейс.

public interface ISearchable 
{ 
    IHttpActionResult Search(string q); 
} 

public class UsersController : ApiController, ISearchable 
{ 
    [Route("api/Users/Search")] 
    [HttpGet] 
    public IHttpActionResult Search([FromUri] string q) 
    { 
     var userRepo = new UserRepo(); 

     //this search method can be as complex as needed 
     //search initials, middle names, phone numbers, whatever you need. 
     var results = userRepo.Search(q); 

     return this.Ok(results); 
    } 
} 

Использование:

https://domain.com/api/Users/Search?q=smith 

Это позволяет очень четко для ваших клиентов, так как они не должны знать о конкретном SearchController, что бы в принципе быть куча RPC-х. Если вы думаете о том, что такое поиск, это в основном глагол, который не является стандартным глаголом http, поэтому мы привязываем его к маршруту как к действию. Мы по-прежнему действуем на коллекцию Users, подобную GET или POST, против коллекции. Поскольку у нас нет ПОИСКА в качестве допустимого метода HTTP, действие является следующим лучшим.

В отношении ТВЕРДОГО. Это упрощает управление контроллером. Это работа (IMO) - это контроль запроса и маршрута до логики. В этом случае он прошел маршрут, сопоставил его с UserRepo и выполнил метод поиска. Поиск не является задачей контроллера, у вас есть другой класс, делающий этот тяжелый подъем. Контроллер просто обрабатывает, какую логику следует выполнять с учетом запроса. Даже возвращенные данные откладываются до конца в конвейере через сериализаторы, поэтому SOLID должен оставаться верным на контроллере.

+0

Учитывая, что используемый вами URL-адрес использования фактически использует строку запроса, не должен ли атрибут параметра быть '[QueryString]'? –

+1

@ ScottK.Fraley [FromUri] работает так, как ожидалось, и я использовал его во многих проектах WebApi. Я никогда не пробовал [QueryString], поэтому мне нужно будет сделать снимок. Спасибо, что указал мне на что-то новое, чтобы попробовать. – ManOVision

+0

Ну, я буду .. Я всегда считал, что '[FromUri]' означает, что он (любой заданный параметр) должен был быть частью Url, например. 'api/bla/Param1Value' и не будет работать с строками (-ами) запроса. Спасибо, что научили меня чему-то, чего я не знал! (Но, конечно, следовало бы попробовать!) –

0

Если вы сходите с ума с помощью СРП и не находите надлежащего уровня ответственности, вы в конечном итоге получаете класс zillion, который ничего не делает.

Я рассматриваю контроллер пользователя как ответственный за посредничество между ресурсом пользователя api и тем, как эта концепция реализована внутри приложения. В этом случае имеет смысл иметь все операции api в одном контроллере.

Это говорит о том, что мы выполняем разделение команд/запросов, чтобы наши контроллеры делегировали команды или запросы для выполнения фактической работы. Таким образом, единственная причина, по которой наш контроллер должен измениться, заключается в том, что мы хотим изменить API, который мы предоставляем.

+0

Тем не менее, я предполагаю, что каждая команда/запрос вводится в ApiController. Это означает, что каждое действие, вероятно, использует хотя бы одно, но, вероятно, не одно из других действий. Это приводит к контроллеру webapi, который засоряется зависимостями, из которых используются только некоторые из них. В этом случае я бы предпочел использовать один класс для каждого метода и просто убедиться, что вы поместили их в ясную структуру папок, которая мешает тому, чтобы стать беспорядочным. – Robba

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

  • Нет связанных вопросов^_^