11

主に REST ベースの Rails サイトがあり、JSON API サポートを追加したいと考えています。

クリーンなコード ベースの場合、既存のコントローラー内にこのサポートを追加するか、この API メソッドのみを処理する新しいコントローラーを作成して、すべての共通コードをモデル/ヘルパーに移動する必要がありますか?

4

2 に答える 2

15

同じコントローラーで API ロジックを記述し、API 要求用に別のコントローラーを作成するという、両方の手法を使用しました。

API のみの場合、つまり自分だけが使用する小さなアプリの場合は、rails が提供するデフォルトのコントローラーとモデルの関係を使用してください。コードはかなりきれいになります。ルート ファイルもきれいになります。

ウェブサイトを持っていて、それに沿って API を構築したい場合は、個別に行ってください。既存のコントローラーと一緒に作成しましたが、コードが乱雑すぎました。コードを何度かリファクタリングしましたが、それでも気に入りませんでした (これも個人的な好みの問題です)。

別の解決策は、接頭辞付きのコントローラーを作成することです。例: ApiUsersController. これによりroutes.rb、対応するコントローラーメソッドに一致するようにルートを手動で指定する必要があるため、ファイルの見栄えが悪くなります。

私にとって有効な解決策は、すべての API ロジックを API 名前空間の別のコントローラーに移動することでした。名前空間を使用すると、API のバージョン管理も行うことができます。たとえば、ルートは次のようになります。

GET /api/v1/users.json
POST /api/v1/users.json

v2その後、古いバージョンの API を使用する既存のアプリケーションを壊すことなく、別の API バージョン (たとえば ) を作成できます。

名前空間の詳細については、http: //guides.rubyonrails.org/routing.html#controller-namespaces-and-routingを参照してください。

バージョニング付きの REST フル API に関する素晴らしいチュートリアル: http://railscasts.com/episodes/350-rest-api-versioning?view=asciicast

于 2012-12-11T07:50:36.013 に答える
6

Rails コントローラー ジェネレーターは、デフォルトで JSON 応答を実装します。

たとえば、次のメソッドがある場合:

class UsersController < ApplicationController
  def index
    @users = User.all
  end
end

次のように JSON 応答を追加できます

class UsersController < Application Controller
  def index
    respond_to do |format|
      format.html
      format.js { render :json => @users }
    end
  end
end

これで、次の 2 つの応答があります。/users

  1. http://someapp.com/users
  2. http://someapp.com/users.json

別のものを非常に簡単に追加できます。例えば、

format.xml { render :xml => @users }

これで、アプリが応答しますhttp://someapp.com/users.xml


json のカスタマイズ

json でテーブルのすべてのフィールドを出力したくない可能性があります。そのためには、 を参照してrails/jbuilderください。ビルダー スタイルの DSL を使用して JSON 構造を作成できます。

jbuilder README の例

Jbuilder.encode do |json|
  json.content format_content(@message.content)
  json.(@message, :created_at, :updated_at)

  json.author do
    json.name @message.creator.name.familiar
    json.email_address @message.creator.email_address_with_name
    json.url url_for(@message.creator, format: :json)
  end

  if current_user.admin?
    json.visitors calculate_visitors(@message)
  end

  json.comments @message.comments, :content, :created_at

  json.attachments @message.attachments do |attachment|
    json.filename attachment.filename
    json.url url_for(attachment)
  end
end

次の出力が生成されます。

{ 
  "content": "<p>This is <i>serious</i> monkey business",
  "created_at": "2011-10-29T20:45:28-05:00",
  "updated_at": "2011-10-29T20:45:28-05:00",

  "author": {
    "name": "David H.",
    "email_address": "'David Heinemeier Hansson' <david@heinemeierhansson.com>",
    "url": "http://example.com/users/1-david.json"
  },

  "visitors": 15,

  "comments": [
    { "content": "Hello everyone!", "created_at": "2011-10-29T20:45:28-05:00" },
    { "content": "To you my good sir!", "created_at": "2011-10-29T20:47:28-05:00" }
  ],

  "attachments": [
    { "filename": "forecast.xls", "url": "http://example.com/downloads/forecast.xls" },
    { "filename": "presentation.pdf", "url": "http://example.com/downloads/presentation.pdf" }
  ]
}
于 2012-12-11T07:34:59.213 に答える