Rails修改預設顯示格式為json


在Rails當中撰寫controller時,一般都是用respond_to來調整輸出的格式,讓使用者可以自由選擇。例如常見的一般html及json兩種格式:

respond_to do |format|
    format.html { redirect_to @post }
    format.json { render :show, status: :ok, location: @post }
end

這樣不管是連結到html頁面,或是指定輸出為json格式,都可以輕鬆應付。


不過有時我們希望整個controller都是輸出成json格式,不需要html,則可以用幾種方式處理:

1. 直接輸出json格式

一般來說要指定輸出json,都必須在網址列上輸入https://example.com/posts.json,在結尾加上json才會有json格式出現。

如果要強制html輸出成json格式的話,只要在controller action結尾撰寫如下:

render :json => @posts

就會將@posts輸出成json格式。

2. 指定輸出json檔案

有時搭配其他gem例如jbuilder來打造特別的輸出方式,由於jbuilder就無法使用簡單的render方式輸出,因此除了原本在網址列最後加上json的方法之外,可以直接指定輸出的template:

respond_to do |format|
  format.html {render template: "posts/index.json.jbuilder"}
end

可以達到同樣預設輸出json格式的效果。有關jbuilder的用法可以參考以前的文章

3. 指定整個controller使用json格式輸出

對於喜歡乾淨code的人來說,如果整個controller預設就是該使用json格式,則要如何乾淨俐落的寫呢?首先到routes.rb檔案:

# config/routes.rb
resources :posts , defaults: {format: :json}

這個設定會讓整個controller的輸出方式都是json。

接著到controller的頂部,加上respond_torespond_with

class PostsController < ApplicationController
    # 設定會回應的輸出格式
    respond_to :json

    def index
        respond_with Post.all
    end
end

respond_with的用法比較特別,就是不管使用者呼叫什麼樣的格式,Rails伺服器就是以指定的資料回應,假如我設定多種回應格式包括xml、pdf等等,都會用同樣方式回應。在此就是將所有posts內容以json回傳,寫起來變得非常簡便。未來擴充的方便性在於如果要回應更多種格式,只需要在最前面的respond_to那邊增加格式即可。有關respond_with的用法,可參考APIdock

補充:有許多Rails開發者認為在routes檔案內設定輸出格式是不專業的作法,因為就像Rails所強調的各司其職,routes就應該只管routes的內容即可,以避免未來維護會有找不到修改處的問題。當然這只是一種論點,對於實務上的使用可以再斟酌。當然,整個controller都用前面提到的render :json => @posts也是一個替代方案。