主に REST ベースの Rails サイトがあり、JSON API サポートを追加したいと考えています。
クリーンなコード ベースの場合、既存のコントローラー内にこのサポートを追加するか、この API メソッドのみを処理する新しいコントローラーを作成して、すべての共通コードをモデル/ヘルパーに移動する必要がありますか?
主に REST ベースの Rails サイトがあり、JSON API サポートを追加したいと考えています。
クリーンなコード ベースの場合、既存のコントローラー内にこのサポートを追加するか、この API メソッドのみを処理する新しいコントローラーを作成して、すべての共通コードをモデル/ヘルパーに移動する必要がありますか?
同じコントローラーで 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
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
http://someapp.com/users
http://someapp.com/users.json
別のものを非常に簡単に追加できます。例えば、
format.xml { render :xml => @users }
これで、アプリが応答しますhttp://someapp.com/users.xml
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" }
]
}