Symfony 3.3 — Что является более оптимальным решением, чем наличие глобального картографического массива и проверка на наличие этого массива в каждой функции?

Текущая функциональность

Привет,

Мы создаем REST API с использованием Symfony 3.3 и хотим иметь возможность выводить информацию об ошибках любого типа (как об исключениях, так и об ошибках, специфичных для API) обратно запрашивающей стороне в виде ответа JSON.

Мы уже установили пакет для обработки исключений API. (Он будет перехватывать обычные встроенные исключения, такие как 404, и возвращать их коды состояния с кратким описанием в формате JSON).

Этот пакет делает, например, что если мы пойдем по маршруту, который не существует, он передаст обратно объект JSON, подобный следующему:

{ "errorCode": 404, "errorMessage": "No route found for /testing" }

Новая функциональность, которая необходима

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

Мы хотим отследить ошибки использования API, например, если пользователь:

  1. Отсутствуют обязательные параметры.
  2. Передача неверного типа параметра.

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

Мы хотим быть в состоянии отловить оба неверных параметра в самом маршруте (например, первая часть нашего маршрута начинается с кода языка — то есть что-то вроде HTTP: // локальный / о / SomeAction) и мы также хотим отловить неверные параметры, добавленные как запрос — т.е. если они делают что-то вроде HTTP: // локальный / а / SomeAction ПгвЬЫат = 123. Очевидно, что в этом случае мы бы хотели, чтобы строка передавалась в параметр firstName.

Текущее предлагаемое решение

О. Мы представляем, что нам понадобится какой-то глобальный массив отображения, который будет содержать данные о том, какими должны быть правильные имена параметров для каждого действия контроллера (сохранение этой информации в базе данных, скорее всего, не вариант). Например, я думал, что у нас может быть ассоциативный массив, подобный следующему:

[ "addUserAction" => ["firstName|str|req", "lastName|str|opt"],
"deleteUserAction" => ["userId|int|req"] ]

B. Единственное, мы не только хотим выполнять эти проверки на уровне действий контроллера, но мы также хотим выполнять эти проверки в каждой из функций репозитория, чтобы обеспечить дополнительный уровень безопасности. Таким образом, нам пришлось бы добавить дополнительные данные в массив выше, чтобы различать, выполняется ли действие контроллера или функция репозитория. Возможно что-то вроде:

[ "ctl.user.addUserAction" => ["firstName|str|req", "lastName|str|opt"],
"repo.user.deleteUser" => ["userId|int|req"] ]

C. Затем этот массив сопоставлений необходимо будет хранить где-то глобально, чтобы к нему могли обращаться как контроллеры, так и репозитории.

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

Вопросы

Q1. Лучшее решение?

Если посмотреть на мой предложенный план выше, даже если я смогу его реализовать, мне кажется, что это огромная накладная работа (и очень взаимосвязанный дизайн, который предполагает постоянное добавление этого массива всякий раз, когда мы добавляем новую функциональность). Я полагаю, что есть более разумный способ не только выполнить сопоставление в Symfony, но и проверить сопоставление в соответствующее время, не редактируя каждую функцию для сопоставления с ассоциированным массивом (именно поэтому я обращаюсь за помощью здесь, прежде чем я начну кодировать это). Я был бы признателен за любые отзывы о том, как это предлагаемое решение может быть сделано лучше и ремонтопригоднее.

Q2. Глобальные ассоциативные массивы

Предполагая, что по какой-то причине мы действительно хотели использовать идею глобального ассоциативного массива, предложенную выше, из любопытства, где в Symfony должно быть подходящее место для размещения такого массива, чтобы к нему можно было обращаться глобально (т. Е. Обоими контроллерами действие или функция хранилища)? (Как PHP-разработчик, пришедший из CodeIgniter-фона, я знаю, что в CodeIgniter мы поместили бы вещи, которые хотели бы использовать в приложении, в файл constants.php. Не представляю, какова будет аналогичная функциональность в Symfony).

0

Решение

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

Что касается параметров метода, ну, PHP — это язык с динамической типизацией). Если вы используете PHP 7 и выше, вы можете просто тип подсказка скалярные типы (integer, string, так далее.). Что касается необязательных параметров, вы можете просто по умолчанию их null,

Но то, что вы пытаетесь достичь с помощью дополнительного уровня безопасности, обычно бесполезно в реальном мире. Если вам нужен такой пуленепробиваемый код, возможно, стоит подумать об использовании Java или C #. Одно дело дезинфицировать пользовательский ввод (что всегда должно быть сделано), но дезинфицировать параметры метода немного параноидально. Не в обиду, но вы должны доверять своим разработчикам.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]