Skip to content

Instantly share code, notes, and snippets.

@lmars
Last active December 30, 2015 14:39
Show Gist options
  • Save lmars/7843505 to your computer and use it in GitHub Desktop.
Save lmars/7843505 to your computer and use it in GitHub Desktop.
Async rack app to fetch giphy gifs
app = lambda { |env|
request = Rack::Request.new(env)
type = request.GET["list"] || "search"
query = request.GET["q"] || "cats"
giphy_request = GiphyRequest.new(type, query)
giphy_request.callback do
headers = {
"Content-Type" => "application/json",
"Access-Control-Allow-Credentials" => "true",
"Access-Control-Allow-Methods" => "GET, POST, OPTIONS",
"Access-Control-Allow-Origin" => "*"
}
body = {
query: type,
results: giphy_request.results
}.to_json
env['async.callback'].call [200, headers, body]
end
throw :async
}
run app
source "https://rubygems.org"
gem "em-http-request"
gem "eventmachine"
gem "json"
gem "rack"
gem "thin"
require "eventmachine"
require "em-http-request"
require "json"
class GiphyRequest
include EM::Deferrable
attr_reader :results
def initialize(type, query = "")
@results = []
http_query = { api_key: "XXXXXXXXXXXX" }
if type == "search"
http_query[:q] = query
end
req = EM::HttpRequest.new("http://api.giphy.com").get(
path: "/v1/gifs/#{type}",
query: http_query
)
req.callback do
populate_results(req.response, type)
succeed
end
end
private
def populate_results(response, type)
if type == "random"
@results.push(
url: JSON.parse(response)["data"]["image_original_url"]
)
else
JSON.parse(response)["data"].each do |gif|
@results.push(
url: gif["images"]["original"]["url"],
staticUrl: gif["images"]["fixed_width_still"]["url"]
)
end
end
end
end
@mattheworiordan
Copy link

Nice, I've never seen throw :async before, but with a bit of searching found this article. Interesting to see they ended up with a Sinatra-Async solution in the end too which reads quite nicely. I'll discuss this with the team on Thursday to see which direction we could take.

BTW. Having read the article above, it seems we could in theory run this type of evented script within a Rails stack. Do you think there is any way we could use the current application servers to service these evented requests still? It would make life a lot easier if we didn't need to provision a new type of server specifically to service these requests.

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