Автор оригинала: David Wong.
До этого я руководил проектом в компании и разделил переднюю и заднюю части. Автор взял на себя ответственность за построение базовой структуры всего проекта и обобщил здесь некоторый опыт. В этой статье в основном рассказывается о разработке и реализации внутреннего веб-api. Ссылка на демонстрационный код: код на GitHub
Наслоение Кода
Базовая архитектура приложения состоит из следующих пяти частей:
- Уровень Контроллера
- Трансформаторный Слой
- Уровень обслуживания
- Уровень Хранилища
- Слой Модели (Слой Модели)
Основные обязанности на всех уровнях показаны на рисунке ниже.
Подробное описание
- Основной поток процедур показан на рисунке выше, с 1 по 8. Если бизнес-логика относительно проста, уровень обслуживания может быть пропущен напрямую, а уровень хранилища может быть вызван непосредственно уровнем контроллера.
- Слои могут быть связаны посредством внедрения зависимостей.
- Бизнес-логика в основном распределена на уровне сервиса и уровне модели. Уровень обслуживания отвечает за логику рабочего процесса, то есть за конкретный процесс выполнения задач, таких как обработка транзакций; Уровень модели отвечает за логику домена, которая включает бизнес-правила, бизнес-вычисления и так далее.
- Обычно уровень обслуживания имеет плохую возможность повторного использования, поскольку он содержит основную логику рабочего процесса, но когда бизнес-логика уровня обслуживания накапливается в определенной степени, это приведет к некоторой общей бизнес-логике (логике рабочего процесса). Лучше извлечь общую бизнес-логику для формирования подсервисного уровня. Уровень, известный как Уровень общего процесса, может поместить эту часть кода в Общий каталог в текущем каталоге служб.
- Возвращаемое значение уровня обслуживания: 1. Бизнес-объекты (бизнес-данные, такие как модель) 2. значение bool Указывает результат обработки.
- Когда бизнес-логика уровня обслуживания не может быть выполнена должным образом, необходимо создать исключение Бизнес-исключение для бизнес-обработки. (Обратите внимание, что это не исключение при выполнении программы. Примеры аномалий ведения бизнеса: недостаточные остатки на счетах, невозможность перевода средств). Благодаря исключениям бизнес-обработки вызывающему абоненту (например, контроллеру или другой службе) возвращаются ненормальные результаты бизнес-обработки. В случае нормального выполнения бизнес – логики возвращается обычное возвращаемое значение уровня обслуживания, то есть пункт 5 выше.
- На каждом уровне, когда открывается новая подклассификация, лучше установить базовый класс подклассификации. Возьмем в качестве примера слой контроллера. Когда вам нужно создать подкаталог блога в каталоге app/Api/Controllers/V1, лучше добавить Базовый контроллер во встроенный каталог в качестве базового класса в каталоге.
Слой модели можно разделить на слой AR (Активная запись) и Доменный слой. Доменный слой обычно основан на AR-слое. Каждый класс на уровне AR соответствует таблице базы данных, и данные, содержащиеся в классе домена, могут поступать из нескольких классов AR.
- Обычно код, связанный с базой данных, пишется на уровне AR, например, для сопоставления таблиц, атрибутов таблиц и т. Д.
- Доменный уровень обычно записывает соответствующую доменную логику. Например: Правила оценки определенных значений в Моделях предметной области
- Класс домена представляет собой полную модель домена, в то время как класс AR не обязательно представляет собой полную модель домена. Например: Данные о продукте хранятся в нескольких таблицах: product_a и product_b, поэтому этим таблицам будет соответствовать несколько классов AR; в то же время мы можем ввести класс домена с именем “Продукт”, который представляет полный продукт (модель домена). Классы домена могут быть основаны на одном из базовых классов AR (как правило, на основе основной таблицы).
структура каталогов
Структура каталогов выглядит следующим образом:
Подробное описание
- Как показано на рисунке выше, каждый уровень Контроллера, Службы, Трансформатора, Модели, Репозитория имеет свой собственный каталог
Описание каталога контроллеров (уровень контроллера)
- Уровень контроллера, где все контроллеры API размещаются в каталоге, классифицируются по версии (V1, V2…) и классифицируются по бизнесу в каталоге версий
Обязанности уровня контроллера:
- Проверьте ввод
- Обработка Запросов и Построение Ответов
- Уровень преобразования вызовов, уровень обслуживания, уровень хранилища, но не должен включать в себя какую-либо бизнес-логику в контроллере
- В каждом каталоге версий (V1, V2…) контроллер разделен на разные подкаталоги (например, Блог, Маркетинг…) по бизнесу, а не по базе данных, хотя результат может быть таким же по бизнесу, как и по базе данных.
- В каждом каталоге версий есть контроллер версий (например, контроллер V1), и все контроллеры в этой версии должны наследоваться от контроллера. Контроллеры версий должны наследоваться от контроллеров Http приложений ApiController
- В подкаталоге контроллеров, разделенных по бизнесу, должен быть базовый класс контроллеров (например, Базовый контроллер), и все контроллеры в этом каталоге наследуются от контроллеров базового класса.
Общее Описание Каталога
- Общий каталог используется для размещения общего кода, который может использоваться во всем проекте, который обычно не должен содержать специфической бизнес-логики.
- Компоненты подкаталога используются для размещения кода компонента (Примечание: Этот код компонента не должен наследоваться от кода платформы/кода сторонних производителей, в противном случае он должен быть помещен в каталог расширений). Обычно эти коды предоставляют определенную функцию, но не зависят от самой платформы и могут использоваться в качестве сторонних пакетов для других проектов.
- Расширения подкаталога используются для размещения кода, расширяющего исходную функциональность кода платформы/стороннего кода (обычно имеется в виду наследование от кода платформы/стороннего кода), обращая внимание на то, чтобы отличать его от компонентов
- Перечисление подкаталога используется для размещения кода “определение константы”
- Помощники подкаталога используются для размещения некоторых классов инструментов, которые обычно предоставляют некоторые статические методы для легкого вызова.
- Области подкаталогов используются для размещения определений областей, связанных с красноречивым ORM
- Подкаталог Lib используется для хранения некоторых базовых файлов библиотеки
Описание каталога Моделей (Слой Модели)
- Слой модели, на котором размещены все классы моделей. Обычно классифицируется по базе данных (например: Блог Бд)
Ответственность слоя модели (унаследована от класса Eloquent):
- Для таблицы базы данных экземпляр модели представляет запись в таблице
- Свойства обработки, такие как $db, $таблица, $заполняемый и т.д.; Область обработки
- Средства доступа и мутаторы: Атрибуты форматирования, когда они извлекаются или сохраняются из экземпляров модели
- Конфигурация ассоциации: использование hasMany (), belongsTo () и т.д.
- Код собственного поведения модели (т. е. код логики домена, который является частью бизнес-логики) включает изменения состояния модели во время выполнения, такие как статус, преобразованный из допустимого в недопустимый.
Ответственность за уровень модели (не унаследовано от класса красноречивых):
- Как класс домена, он содержит логику домена
- Когда полный класс домена разделен на несколько таблиц базы данных и хранится в базе данных, в каждом каталоге базы данных можно создать каталог домена (например, DbBlog) для хранения полного класса домена.
- Все модели, соответствующие таблицам базы данных, должны быть косвенно унаследованы от AppModel. Каждый каталог базы данных (например, Блог Бд) должен содержать Базовую модель (представляющую базу данных), от которой наследуются другие модели.
- Примечание: Не помещайте код операции “добавить, удалить и изменить проверку” в таблицы базы данных в модели, но поместите код “добавить, удалить и изменить проверку” в слой репозитория.
Описание каталога Репозиториев (Уровень Репозитория)
- Уровень хранилища, на котором размещаются все классы хранилища. Обычно классифицируется по бизнесу/базе данных
Обязанности на уровне репозитория:
- Он содержит только код для непосредственного добавления, удаления и изменения базы данных и помогает уровню модели (за исключением того, что не следует размещать никакой другой код; обычно логика добавления и удаления относительно одна, но поиск будет иметь множество ситуаций, и здесь будет реализована различная логика запросов).
- Уровень репозитория содержит только код, который непосредственно работает с базой данных. Другой код, который включает такие функции, как внешние вызовы, следует рассматривать на уровне обслуживания.
- Все классы хранилища должны наследоваться от класса хранилища приложений.
Описание Каталога Служб (Уровень обслуживания)
- Уровень обслуживания, на котором размещаются все классы обслуживания. Обычно классифицируется по бизнесу
Обязанности уровня обслуживания:
- Обработка задействованного внешнего поведения: например, отправка почты, использование внешних API (например, использование очередей, экономный вызов, вызов служб других команд и т.д.)
- Включая бизнес-логику (в основном логику рабочего процесса), то есть конкретный процесс для выполнения задачи: уровень обслуживания-это основное место, где существует бизнес-логика, помогающая уровню контроллера; когда необходимо добавить, удалить и изменить базу данных, следует вызвать соответствующий уровень хранилища.
- Все классы служб должны наследоваться от класса службы приложений
Описание каталога трансформаторов (слой трансформаторов)
- Слой трансформатора, где размещены все классы преобразования. Обычно классифицируется в соответствии с бизнесом.
Обязанности трансформаторного слоя:
- Обработка логики отображения
- Управление выводом интерфейса API (отделение вывода интерфейса от базовых служб, репозитория, модели и т. Д., Чтобы даже при изменении базовых таблиц базы данных использование интерфейса не влияло)
- Все классы преобразования должны наследоваться от класса App Transformer
Будьте осторожны Формат ответа, обсуждаемый здесь, относится к ответу, связанному с бизнесом приложения, и ответ интерфейса API, предоставленный третьей стороной, не входит в объем обработки (например: ответ, предоставленный laravel passport, ответ, предоставленный swagger)
Классификация ответов
- Успешный ответ класса: коды ответа HTTP варьируются от 200 до 300. Возврат такого ответа указывает на то, что сервер полностью обработал запрос и что не было обнаружено никаких исключений или ошибок. (За исключением нормальных условий, При сбое обработки бизнес-логики такие ответы возвращаются вместе с соответствующей информацией о сбое бизнес-обработки. )
- Ответ класса сбоя: код ответа HTTP не находится между 200 и 300. Возврат такого ответа указывает на то, что сервер выдает исключение или ошибку, которые не были зафиксированы и обработаны.
Примеры ответов
Успешный ответ класса
1. Успешная обработка бизнес-логики
2. Сбой Обработки Бизнес-Логики
Структуры показаны на рисунке выше: Структуры так же успешны, как и обработка бизнес-логики. Разница в том, что код успеха равен 0, а код ошибки для сбоя-это общий код ошибки перечисления приложений. php . Коды ошибок бизнес-уровня (См. Код ошибки ниже).
Ответ класса сбоя
Формат ответа на сбой настраивается в файле config/api.php (ключевое слово-errorFormat). В основном это включает сообщение, ошибки, код, status_code, отладку. Некоторая информация не будет отображаться в рабочей среде.
Мысли об обработке форматирования ответов
Общая идея обработки форматирования ответов состоит в том, чтобы перехватывать результаты обработки конкретных запросов (помечать такие запросы), когда они возвращаются пользователям (с использованием механизма событий), и форматировать исходный ответ. Код ответа:
- Вывод бизнес-формата промежуточного программного обеспечения Http приложения: Промежуточное программное обеспечение маршрутизации, которое размещается на некоторых маршрутах, помечает запрос, указывая, что его ответ необходимо отформатировать
- Прослушиватели приложений Добавляют Бизнес-статус В Ответ: Обработчик событий, который обрабатывает измененные события, вызванные dingo, и форматирует ответы
- Заголовок постоянного бизнес – статуса в ApiController Http-контроллеров приложений. PHP-файл передает результат обработки бизнес-логики обработчику событий в 2 через заголовок в ответе в качестве посредника и, наконец, формирует форматированный ответ.
Файл кода, связанный с кодом ошибки, является общим кодом ошибки перечисления приложения. Формат кода ошибки PHP: A-BB-CCC
- A: Представляет уровень ошибки, 0 представляет успех, 1 представляет ошибку системного уровня, а 2 представляет ошибку уровня обслуживания (бизнеса).
- B: Представляет проекты/модули/классификации;
- C: Конкретный номер ошибки;
Использование кодов ошибок на разных уровнях ошибок:
Коды ошибок бизнес-уровня используются для представления результатов бизнес-обработки.
- Сбой бизнес-обработки на уровне службы, и при возникновении бизнес-исключения использовался код состояния бизнес-уровня
- Когда уровень контроллера создает ответ, он определяет результат бизнес – обработки ответа, например: возвращает $this – > ответ – > массив ($validator – > ошибки () – > toArray () – > с заголовком (self:: Заголовок состояния бизнеса, [Код ошибки:: BUSINESS_INVALID_PARAM,’Информация о результатах бизнес-обработки’);
- Используется для ведения журнала (ведение журнала, связанного с бизнесом)
Коды ошибок системного уровня используются для указания исключений при выполнении кода.
- Используется для записи систематических журналов исключений, доступны все уровни Контроллера, Службы, Трансформатора, Хранилища, Модели
Будьте осторожны:
- Файлы с кодом ошибки не могут быть перезаписаны. Если есть новые коды ошибок, пожалуйста, добавьте их в соответствии с существующей классификацией. Старые коды ошибок нельзя удалить или изменить.
Код, связанный с исключениями: каталог приложений/исключений. В коде приложения может быть создано только Бизнес-исключение или Системное исключение. Пожалуйста, не делайте никаких других исключений. Различные исключения различаются кодом исключения. (Код определяется в app/Common/Enum/ErrorCode.php).
Когда бизнес-логика не выполняется, возникает бизнес-исключение. Общие возможности заключаются в следующем:
- Уровень Контроллера Проверяет Сбой Ввода, Создает Бизнес-Исключение
- Бизнес-логика сервисного уровня не выполняется и создает бизнес-исключение напрямую (например, баланс счета недостаточен и не может быть переведен)
- Если бизнес-логика уровня обслуживания не выполняется (вместо создания исключения она указывает на сбой выполнения возвращаемым значением), вызывающий объект, получающий возвращаемое значение, создает бизнес-исключение.
Контроллер должен фиксировать бизнес-исключение (поэтому, даже если возникает бизнес-исключение, он все равно возвращает успешный ответ класса (см. Выше) и создает ответ на основе соответствующей информации о бизнес-исключении. Рекомендуется, чтобы все действия контроллера были записаны в следующем формате.
public function add(Request $request, ReserveService $reserveService){
Try {// Put all controller logic into try block
$postData = $request->post();
// Check data validity
/** @var \Illuminate\Validation\Validator $validator*/
$validator = Validator::make($postData, [
'orderName' => 'required',
'reservePhone' => 'required',
]);
If ($validator - > fails (){// check failure
new BusinessException(ErrorCode::BUSINESS_INVALID_PARAM, "", $validator->errors()->toArray());
}
$result = $reserveService->addReservation($postData);
if(true === $result){
// Successful execution of business logic
return $this->response->array([]);
}else{
// Failure of Business Logic Execution Indicated by Return Value
throw new BusinessException(ErrorCode::BUSINESS_BUSY);
}
} Catch (Business Exception $e) {// Capture Business Exception, and construct responses based on exception information. The following code is generic
return $this->response->array($e->getExtra())
->withHeader(self::BUSINESS_STATUS_HEADER, [$e->getCode(), $e->getMessage()]);
}
}Когда возникает базовое системное исключение, создается Системное исключение. Исключение SystemException без обработки захвата вызывает сбой ответа класса (см. Выше).
Компоненты журналов и компоненты предупреждений существуют для лучшего обслуживания проекта и своевременного устранения ошибок. Соответствующие компоненты журнала и компоненты раннего предупреждения должны быть добавлены в соответствии с их собственными потребностями.
Вы можете выбрать интеграцию зрелого инструмента документооборота, такого как swagger, blueprint и т. Д.
Оригинал: “https://developpaper.com/web-api-development-practice/”