2009-10-29 5 views
-3

J'ai quelques plugins Engine avec des extrémités métalliques qui implémentent des services web extrêmement simples que j'ai l'intention de partager entre plusieurs applications. Ils fonctionnent bien comme ils le sont, mais évidemment, en les chargeant localement pour le développement et les tests, l'envoi de Net :: HTTP à get_response pour demander à localhost une autre page à l'intérieur de l'objet contrôleur en cours entraîne un blocage instantané. Voici donc ma question: le système de routage de Rails (ou Rack) permet-il de consommer en toute sécurité un service Web qui peut ou non faire partie de la même application sous la même instance de serveur, ou devrais-je pirater un cas spécial avec render_to_string pour les moments où le nom d'hôte dans l'URI correspond au mien?Sous-demandes ré-entrant dans Rack/Rails

+0

Vous pouvez utiliser un objet Mock: le chapitre 13 dans le livre "Développement Web Agile avec Rails 2", qui sont essentiellement des stubs :) est passé à passer dessus (donc je ne suis pas un expert à ce sujet) – Shyam

Répondre

3

Il ne fonctionne pas en développement car il ne traite qu'une seule requête à la fois et la requête du contrôleur reste bloquée. Si vous en avez besoin, vous pouvez exécuter plusieurs serveurs localement derrière un équilibreur de charge. Je recommande d'utiliser Passenger même pour le développement (et le prefpane si vous êtes sur OS X).

Je vous recommande de séparer les services web internes et les applications qui les utilisent. De cette façon, vous ne dupliquez pas le code et vous pouvez facilement les mettre à l'échelle et les contrôler individuellement.

0

Ceci est en effet possible. Cependant, vous devez vous assurer que les services que vous appelez ne s'appellent pas récursivement.

Un très simple "rentrants" middleware Rack pourrait fonctionner comme ceci:

class Reentry < Struct.new(:app) 
    def call(env) 
    @current_env = env 
    app.call(env.merge('reentry' => self) 
    end 

    def call_rack(request_uri) 
    env_for_recursive_call = @current_env.dup 
    env_for_recursive_call['PATH_INFO'] = request_uri # ...and more 
    status, headers, response = call(env_for_recursive_call) 
    # for example, return response as a String 
    response.inject(''){|part, buf| part + buf } 
    end 
end 

Puis dans le code d'appel:

env['reentry'].call_rack('/my/api/get-json') 

Un cas d'utilisation très valable pour cela Sideloading réponses API JSON format dans votre page principale.

Évidemment, le succès de cette technique dépendra de la sophistication de votre pile Rack (car certaines parties de l'environnement Rack ne seront pas réutilisées).

Questions connexes