将ActiveRecord验证错误转换为API消耗错误 [英] Transforming ActiveRecord validation errors into API consumable errors

查看:102
本文介绍了将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.

想象一下我有以下模型:

Imagine I have the following model:

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验证旨在与Forms一起使用。理想情况下,我想用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天的非常类似的问题

推荐答案

error_codes.yml 上,定义您的标准API错误,包括 status_code title 详细信息和内部代码,然后可以使用它们在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天全站免登陆