将 ActiveRecord 验证错误转换为 API 可使用错误 [英] Transforming ActiveRecord validation errors into API consumable errors

查看:22
本文介绍了将 ActiveRecord 验证错误转换为 API 可使用错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Rails 4 中编写一个非常标准的 CRUD RESTful API.不过我在错误处理方面做得不够.

I'm writing a pretty standard CRUD RESTful API in Rails 4. I'm coming up short on error handling though.

假设我有以下模型:

class Book < ActiveRecord::Base
  validates :title, presence: true
end

如果我尝试创建一个没有标题的书对象,我会收到以下错误:

If I try to create a book object without a title I'll get the following error:

{
  "title": [
    "can't be blank"
  ]
}

ActiveRecord 验证旨在与表单一起使用.理想情况下,我想将每个人类可读的验证错误与 API 使用者可以使用的常量相匹配.所以像:

ActiveRecord validations are designed to be used with Forms. Ideally I'd like to match up each human readable validation error with a constant that can be used by an API consumer. So something like:

{
  "title": [
    "can't be blank"
  ],
  "error_code": "TITLE_ERROR"
}

这既可以用于显示用户面临的错误(标题不能为空"),也可以在其他代码中使用(if response.error_code === TITLE_ERROR...).Rails 中是否有针对此的工具?

This can be both used to display user facing errors ("title can't be blank") and can be used within other code (if response.error_code === TITLE_ERROR...). Is there any tooling for this in Rails?

这是来自 Rails 2 天的 非常相似的问题.

Here's a very similar question from Rails 2 days.

推荐答案

error_codes.yml 上定义您的标准 API 错误,包括 status_codetitledetails 和内部 code 然后您可以使用它在 API 文档中提供有关错误的更多信息.

On error_codes.yml define your standard API errors, including status_code, title, details and an internal code you can then use to provide further info about the error on your API documentation.

这是一个基本示例:

api:
  invalid_resource:
    code: '1'
    status: '400'
    title: 'Bad Request'

not_found:
    code: '2'
    status: '404'
    title: 'Not Found'
    details: 'Resource not found.'

config/initializers/api_errors.rb 上将该 YAML 文件加载到常量中.

On config/initializers/api_errors.rb load that YAML file into a constant.

API_ERRORS = YAML.load_file(Rails.root.join('doc','error-codes.yml'))['api']

app/controllers/concerns/error_handling.rb 上定义一个可重用的方法来以 JSON 格式呈现 API 错误:

On app/controllers/concerns/error_handling.rb define a reusable method to render your API errors in JSON format:

module ErrorHandling
  def respond_with_error(error, invalid_resource = nil)
    error = API_ERRORS[error]
    error['details'] = invalid_resource.errors.full_messages if invalid_resource
    render json: error, status: error['status']
  end
end

在您的 API 基础控制器上包含关注点,因此它可用于所有继承自它的控制器:

On your API base controller include the concern so it's available on all the controllers which inherit from it:

include ErrorHandling

然后您就可以在任何这些控制器上使用您的方法:

You will then be able to use your method on any of those controllers:

respond_with_error('not_found') # For standard API errors
respond_with_error('invalid_resource', @user) # For invalid resources

例如,在您的用户控制器上,您可能有以下内容:

For example on your users controller you may have the following:

def create
  if @user.save(your_api_params)
    # Do whatever your API needs to do
  else
    respond_with_error('invalid_resource', @user)
  end
end

您的 API 将输出的错误如下所示:

The errors your API will output will look like this:

# For invalid resources
{
  "code": "1",
  "status": "400",
  "title": "Bad Request",
  "details": [
    "Email format is incorrect"
  ]
}

# For standard API errors
{
  "code": "2",
  "status": "404",
  "title": "Not Found",
  "details": "Route not found."
}

随着 API 的增长,您将能够轻松地在 YAML 文件中添加新的错误代码,并通过此方法使用它们,避免重复并使您的错误代码在整个 API 中保持一致.

As your API grows, you'll be able to easily add new error codes on your YAML file and use them with this method avoiding duplication and making your error codes consistent across your API.

这篇关于将 ActiveRecord 验证错误转换为 API 可使用错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆