als je aan een niet-hello-world rails-applicatie werkt, heb je onvermijdelijk kleine ajax-hulpprogramma's nodig om te communiceren met de server - om cliëntzijdige logica uit te voeren. ik heb het niet over een api per se, maar over ad-hoc utiliteiten zoals dit:
markdown.change(function(){
generate_html_on_the_server( markdown.val(), function(html){
preview.html(html);
});
});
of
reservation.change(function(){
check_availibity_on_the_server( reservation.val(), function(data){
if(!data['available']){
alert('die tijd is niet beschikbaar - kies een andere!');
};
})
});
enz.
deze soort functies maakt geen deel uit van een publieke server-to-server api, het zijn gewoon samenwerkende js/back-end-eindpunten die nodig zijn om de weergavefunctie te laten werken.
de meeste rails-applicaties zullen veel van deze functies verzamelen en de vraag rijst:
“Waar plaats je ze?”
in de meeste teams heb je drie of vier ontwikkelaars die deze functies anders benoemen en organiseren, waardoor de codebasis in korte tijd verandert in een cowboy-spaghetti-chaos.
@dojo4 hebben we dit geabstraheerd met een klein rpc-ontwerppatroon: eerst hebben we een kleine controller-dsl die is opgenomen in onze ApplicationController die declaratieve definities van 'rpc' js-hulpprogramma's op basis van per controller toelaat.
class ApplicationController < ActionController::Base
include(RPC)
end
bekijk de implementatie hier: https://gist.github.com/ahoward/7320900
in het Engels vertaald betekent deze dsl dat er een enkele actie op de controller is gedefinieerd die multiplexen welke methode moet worden gebruikt op basis van params, en een eenvoudige manier om deze te definiëren. het verwacht dat alle rpc-acties een hash teruggeven en json teruggeven.
de implementatie komt erop neer
def rpc
which = params['method']
action = @rpc[which]
result = action.call(params)
render :json => result.to_json
end
het gebruik moet duidelijk zijn uit de code
class GeoLocationController < ApplicationController
rpc(:geo_location) do |params|
geo_location = GeoLocation.geo_locate( params['address'] )
geo_location.attributes
end
rpc(:lat_lng