Skip to content

Instantly share code, notes, and snippets.

@jqmtor
Last active June 1, 2016 16:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jqmtor/53859d11a2ba0beee155 to your computer and use it in GitHub Desktop.
Save jqmtor/53859d11a2ba0beee155 to your computer and use it in GitHub Desktop.
Make URLs more visible in HTTP-based gateways. In HTTP-based gateways, URL visibility is an important feature because it gives the reader a very good idea of the overall functionality of the class. This proposal strives to achieve that goal and was instigated by @tjsousa, who brought the problem up while reviewing some code.
# simple DSL to describe and build URLs in an HTTP gateway
module ConfigurableGateway
def self.included(base)
base.extend(ClassMethods)
end
def url_for(name, params = nil)
# probably should be replaced by an automatic forwarding mechanism
self.class.instance_variable_get("@gateway_config").url_for(name, params)
end
module ClassMethods
def configuration(&block)
@gateway_config ||= GatewayConfiguration.new
@gateway_config.instance_eval(&block)
end
private
class GatewayConfiguration
def url_for(name, params = {})
url = instance_variable_get("@#{name}_url")
replace_params(url, params)
end
private
def replace_params(url, params)
params.each do |name, value|
url.gsub!(":#{name}", value.to_s)
end
url
end
def method_missing(method, *args)
url = args.first
instance_variable_set("@#{method}", url)
end
end
end
end
class HTTPGateway
include ConfigurableGateway
configuration do
user_url 'http://example.com/users/:user_id'
user_message_url 'http://example.com/users/:user_id/messages/:message_id'
end
end
# Client code demo
gateway = HTTPGateway.new
puts gateway.url_for(:user, {user_id: 123})
puts gateway.url_for(:user_message, {user_id: 123, message_id: 321})
@tjsousa
Copy link

tjsousa commented Jan 20, 2015

me likes it!

@rfelix
Copy link

rfelix commented Jan 21, 2015

Looks pretty interesting! It reminded me a bit of HTTParty except that here it's generating URLs as opposed to actual HTTP requests.

The only thing is that it goes against hypermedia principles, but some APIs I guess just don't work that way and are completely URL based, and an approach like this might be handy :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment