2016-10-02 12 views
1

私はこれを可能な限り簡潔かつポイントにとどめようとします。RubyでのREST APIの使用 - 認証するタイミング

私はDiplomat gemの後ろにモデル化されたRuby gemを書いています。これは、製品のREST APIのラッパーです。私が消費しているAPIは、トークンベースの認証を使用しています。 POSTを介してAPIトークンが送信され、セッションがクッキーとして返されます。私は、APIによって返されたクッキーを処理するために、ファラデーのcookiejarミドルウェアを利用しています。概念的に私が苦労している問題は、認証するときです。

私はRestClientとVolumeという2つのクラスを持っています。後者は前者から継承する。現在のところ、RestClientのinitメソッドは接続オブジェクトを作成して認証し、Volumeのinitメソッドはsuperを呼び出してパスを渡します。私の考えは、RestClientから継承したクラスが初期化されると、そのクラスがユーザーを認証するということです。

class RestClient 
    def initialize(api_path) 
    <build connection> 
    auth 
    end 
    def auth 
    <post token, get session cookie> 
    end 
end 

class Volume < RestClient 
    def initialize 
    super('/volume') 
    end 
    def volumes 
    <send GET, receive volumes> 
    end 
end 

obj = Volume.new #Creates object, authenticates user 
obj.volumes #Returns list of volumes 

私は正しいトラックに向かいましたか?メソッドが初期化されたときに認証するのではなく、メソッドがオブジェクトに対して最初に呼び出されるまで認証を延ばすべきですか?私はこれについて完全に間違っているのですか?

答えて

0

あなたがここで求めているのは、コードスタイルの質問のほうです。ここには間違いありません。私はそれがprimarily opinion-basedだと思うので、私は閉会しようとしていた。

私は意見があるので、代わりに答えを書いています。

A)

はちょうどそれが動作するかどうか、それは十分に良いですが、ものを実装オーバーとは思わない

b)のルールあなたが同じの3つの事を実装している場合は3

の種類とパターンが現れる、リファクタリング!

c)の疑いで、継承を使用しないとき相続

を使用することを拒否します。モジュールはほとんどの場合十分に良いでしょう。私は、HTTP呼び出しを行うために初期化子を使用することはありません

:特にあなたの質問に

。エラーが発生しやすく、イニシャライザやその周辺からのエラー処理が実際には醜いです。それはお尻の痛みをテストします。

単純な方法で必要なものを実装するだけです。

別のAPIコールを呼び出す前にauthenticateを呼び出すと何が問題になりますか?ブロックにそれを置くことは、それは本当に素晴らしく、読みやすくすることがあります。

client.authenticate do |session| 
    session.volumes 
end 

これはあなたのユースケースにはあまりにも醜いであれば、あなたは認証を必要とするかもしれない他のメソッド呼び出しの前に遅延してそれを行うことができます。

+0

である私は、フィードバックを感謝し、私はoverthinkingに非常になりやすいです。 APIコールを呼び出す各メソッドの前に怠惰な認証を行い、テストが大幅に簡単になりました。初期化中に認証を指摘するのは貧弱なパターンであり、そのアドバイスだけで大きな助けとなったという単純な事実の答えとしてマークします。 – Alayde

0

APIがサポートする唯一の認証はクッキーですか?非常に多くの場合、サーバー指向の(サーバー間)REST APIは、要求ごとに認証を渡すためのより良い認証戦略も実装しています。

すべてのことが言われて、何も行うことができますが、このようなものである:認証が必要な場合、あなたが「右に使用するクラスを奨励する」ことで良いことをやってしまうため、この方法

client = MyApi::Client.for_user(username: ..., password: ....) 
#...or 
client = MyApi::Client.for_token(token) 
volumes = MyApi::Volumes.get(client: client) 

- 認証データなしでクライアントをインスタンス化するのではなく、クライアントなしでリモートオブジェクト/呼び出しを初期化しないということです。

はその後、クライアントの中に、何を行うことができますすることは、第1の要求にメモ化認証

def perform(http_method, url, ...) 
    @auth_cookie ||= @client.get_cookie_by_authentication 
    ... 
end 
関連する問題