Нам нужно реализовать большое количество вызовов JSON API в веб-приложении Grails 3.3.
К сожалению, сборка каждого метода — это обработка ошибок, и в настоящее время мы дублируем этот код в каждом методе, что создает головную боль при обслуживании (если мы улучшим обработку ошибок, нам придется обновить более 70 методов). Есть ли лучший способ с меньшим количеством повторяющихся кодов ошибок? Какой-то шаблон, который может извлечь код проверки ошибок в одно место?
К вашему сведению, мы используем очень простой и эффективный упорядочиватель объектов для рендеринга json нужным нам образом. К сожалению, паттерн render(){...} игнорирует упорядочивающие объекты, поэтому в данном случае нам нужно использовать JSONBuilder.
Правильный логин выдаст что-то вроде этого:
{"result":"0","user":{"username":"bob","userId":"123"},"accounts":[{"balance":"0.00","currencyIso":"USD","id":1}]}
Ошибка будет выглядеть так:
{"result":"9999","message":"exception in xxx"}
У нас есть длинный список кодов результатов (около 70), поэтому клиент точно знает, в чем была ошибка (мы не используем для этого коды состояния HTTP, поскольку они вообще не отображаются)
class LoginCommand implements grails.validation.Validateable {
String username
String password
static constraints = {
username nullable:false, blank: false, size: 3..32
password nullable:false, blank: false, size: 3..32
}
}
class UserApiController {
def login(LoginCommand cmd) {
try {
if (cmd.hasErrors()) {
log.error("invalid parameters")
render(status: 400, contentType: 'application/json') {
result 10
message "errors in parameters"
return
}
} else {
User user = User.findByUsernameAndPassword(cmd.username, cmd.password)
def userAccounts = Account.findAllByUser(user)
if (user == null) {
render(status: 404, contentType: 'application/json') {
result 100
message "could not find user with that username and pass"
}
} else {
def builder = new JSONBuilder()
def json = builder.build {
result= "0"
user= {
username=user.username
userId=user.id
}
accounts=playerAccounts
}
render(status: 200, contentType: 'application/json', text: json)
} // else all good
} // else params ok
} catch (Exception e) {
log.error("Caught Exception in UserApiController.login()", e)
render(status: 500, contentType: 'application/json') {
result 9999
message e.toString()
}
}
}
Мы кратко рассмотрели представления json, но мы не думаем, что это нам поможет, усложнит и, поскольку наш проект не был построен с использованием rest-api, у нас нет к нему доступа.