Схема

Схема


В общем, я предлагаю придерживаться следующей схемы обмена сообщениями:


##### Успешный ответ

В случае успешного ответа возвращать код 200, а в теле ответа либо ничего, либо строку, либо массив/объект, в зависимости от контекста:

- `response('', 200)`

- `response('Сохранено!', 200)`

- `response(['a' => 123, 'b' => 'asd'], 200)`


##### Ошибка валидации

В случае ошибки валидации Laravel сам заботится об ответе (если конечно использовать `$request->validate`). Формат ответа будет такой (код ответа 422):

```

{

   "message": "The given data was invalid.",

   "errors": {

       "field-1": [

           "Error 1",

           "Error 2"

       ],

       "field-2": [

           "Error 1",

           "Error 2"

       ],

   }

}

```

В случае, когда мы не можем использовать встроенную валидацию, я предлагаю просто придерживаться этого же формата. Объект "errors" здесь не является обязательным. То есть, в самом простом случае можно обойтись кодом 422 и полем "message".


##### Эксепшены

В случае критичной ошибки Laravel в продакшене отдает аналогичный ответ, как и в предыдущем пункте. Только код ошибки может быть разным. Например, код `$user = User::findOrfail(99999);` кинет исключение (если юзера 99999 не существует), а в браузер придет ответ с кодом 404 и телом:

```

{

   "message": "No query results for model [App\\User] 99999"

}

```

В идеале, конечно, нужно стремиться к тому, чтобы конечный пользователь не видел этих эксепшенов. Во-первых, текст ошибки захардкожен в движок, он всегда будет на английском, и вряд ли сообщит что-то полезное пользователю. Во-вторых, тут может быть раскрыто немного внутренней информации, например класс App\\User.


Но т.к. идеала не существует, я считаю, что это — приемлемый вариант, особенно для прототипа. Предполагается, что если юзер не будет пытаться "хакать" систему, то таких эксепшенов он и не увидит. Также, эксепшены будут появляться в логе, и мы должны будем быстро на них отреагировать.


##### Ошибки логики, прав доступа и прочее

Бывает, что по логике приложения нужно показать пользователю ошибку. Например, "недостаточно денег на балансе". В принципе, здесь доступны разные варианты, но проще всего вернуть ответ в таком же формате, как возвращает Laravel. Нужно только вручную указать код ответа, написать сообщение и, если необходимо, добавить дополнительные данные:

```

response(['message' => 'Недостаточно денег на балансе'], 402)

response(['message' => 'Есть несколько ошибок', 'errors' => [...]], 403)

response(['message' => 'Есть несколько ошибок, вот вам доп.инфа', 'errors' => [...], 'anyData' => [...]], 403)

```


Единственный нюанс, который может возникнуть в будущем, это если Laravel в будущих версиях изменит формат ошибок, как это случилось в версии 5.5. Например, вместо "message" сделает "errorMessage". Тогда нам придется везде, где мы вручную кидаем ошибки, поменять это. Но подобные изменения происходят очень редко, так что серьезной опасности я тут не вижу. К тому же, всегда можно написать свой метод а-ля `custom_error`, и везде использовать его, вместо встроенного `response`. Тогда поменять придется только его реализацию.


В общем, если видишь слабые места здесь — говори прямо. Я скорее всего что-нибудь не учел, но думаю 95% случаев данная схема закроет.

Report Page