0

Я использую RABL для моего API REST. Однако в настоящее время, даже если есть ошибка, код ответа HTTP, который я получаю, равен 200. Есть ли способ изменить это на код уровня 4xx? Было бы замечательно, если бы мой клиент прочитал.Изменение кода ответа HTTP с использованием Rails и RABL

Я не использую render template: "api/v1/error.rabl”, потому что если я его использую, есть фильтр after, который устанавливает заголовки контроля доступа CORS, которые не выполняются.

Я пробовал искать, но не нашел способ.

+0

Так что же вы используете для вызова рендера? – phoet

+0

Я возвращаю метод контроллера естественно, поэтому RABL-файл автоматически вызывается Rails автоматически как представление. –

+0

как это отличается от вызова? – phoet

ответ

1

Похоже, this answer обеспечивает хорошее решение. Например,

class FoosController < ActionController::Base 
    respond_to :json 

    class ApiResponder < ActionController::Responder 
    def to_format 
     case 
     when has_errors? 
     controller.response.status = :unprocessable_entity 
     when get? && !resource 
     controller.response.status = :not_found 
     when post? 
     controller.response.status = :created 
     end 

     default_render 
    rescue ActionView::MissingTemplate => e 
     api_behavior(e) 
    end 
    end 
    self.responder = ApiResponder 

    def show 
    @foo = Foo.find(params[:id]) 
    @foo.errors.add(:base, "foo bar") # e.g. of errors on the object 
    respond_with @foo 
    end 
end 

the wiki Хотя есть предупреждение, что «установка controller.response.status походит на значение по умолчанию», respond_with или render не должны явно установить status и, похоже, призыв к render "my_template" триггеры, которые 200 вы упомянули. Если вы хотите использовать один шаблон ошибки, something like the author's suggested template, это работает:

... 

    self.responder = ApiResponder 

    def show 
    @foo = Foo.find(params[:id]) 
    @foo.errors.add(:base, "foo bar") # e.g. of errors on the object 
    respond_with @foo do |format| 
     if @foo.errors.empty? 
     flash[:notice] = 'Foo was successfully created.' 
     else 
     format.json { render "error" } 
     end 
    end 
    end 

# error.rabl 
object false 

node :errors do 
    { 
    :message => "Sorry, fubar'ed", 
    :code => 12345 
    } 
end 

Это работает с действиями, которые пишут, а также читать. В original bug discussion также есть несколько интересных примеров.