Using rails to consume web services/apis - ruby-on-rails

I'm new to the rails world and am trying to build a app to simply allow me to search things on Amazon and such sites based on the users input.
I've done a little reasearch and it seems the httparty gem is a good place to start? The documents ive found so far though are not the best. They don't really give me a lot of information (where to put the code etc).
Are there any existing tutorials out there or code examples that I can either use or take a look at to give me a better idea of how this thing works?

I'm working on an app like this right now, so let me offer a few thoughts.
First, if you're a complete newcomer to Rails, then as a first step I'd suggest taking a parallel approach to the problem, with two tracks:
Learn about Rails
Learn about how to interact with an API (make requests and parse responses) in Ruby
These are two separate problems, and although you may end up implementing them together, it's best to think about them in isolation first.
For the first one, I'd suggest writing a couple simple apps first to get a feel for how things work. Even only a simple app will require a certain amount of user interaction, possibly saving records to the DB, etc., problems that are separate from consuming data from an API. There are an endless number of tutorials out there on Rails, but just to mention one, you might try Michael Harti's Learn Web Development with Rails as a starting point.
The second point, consuming API data, is distinct from the problems of designing the app itself. To learn more about this aspect of the problem, I'd suggest using a popular API client gem like (as you mentioned) HTTParty, which I use myself. Rather than immediately try to use the HTTParty methods in a Rails app, as an exercise I'd suggest playing around a bit in a console (irb). If you install the gem (gem install httparty) you can then require it (require 'httparty') from the console and immediately make requests and parse responses from the APIs.
E.g.:
irb(main):001:0> require 'httparty'
=> true
irb(main):002:0> response = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
=> ...
Once you've got a bit more familiar with Rails and with accessing an API in ruby, then you could move on to actually building the app itself. Depending on how complex your requests to the API(s) are going to be, you have a few options as to how to structure your API requests in your Rails app:
Make the requests part of the Rails app itself, directly from controller actions. This is really only okay if you are only going to support a very limited number of request types (e.g. simple search) on a limited number of services. Anything more complex and your controller will get fat, which is a no-no in MVC frameworks.
Create a separate ruby class (usually called an API wrapper) to group together methods for making requests and parsing responses from the API. With a gem like HTTParty you can do this just by adding a line include HTTParty in the class, which adds the module to the class. There are lots of examples out there on how to do this, here is one.
Use a dedicated gem for accessing specific APIs, or create one (or more) yourself. There are gems for most popular services, e.g. Twitter, Linkedin, Flickr, etc. See this list of API client gems for more. This takes away a lot of the pain of interacting with an API, but will only work for a subset of all services.
You mention you're thinking of using HTTParty, which I can recommend as I am using it myself. There are alternatives such as Faraday (see this list of HTTP clients for more), but I find for most tasks HTTParty will do fine. The documentation may be a bit sparse, but there are a bunch of examples that you can work from.
Hope that helps!

Related

Generate and send xml on model save

I need to generate xml from a model and send it to a web service on model save.
I'm sure this is a common case and should be straight forward. Just create a job on after_save callback that generates the xml and sends it to the endpoint.
Since I'm new to Ruby on Rails I'm not to sure how to handle this though. My questions are more about code organization. It's not unlikely that this api connection will be discontinued in the future so I need a clean modular way to get rid of it. Would it be best practice/convention to put this in a separate gem? Can gems actually add jobs to an existing rails queue? Can gems create migrations on install? I'll probably need to add a model to keep track of the api sync. How about dropping a table on gem uninstall? Or should I not use a gem for this at all?
I realize these are broad and basic Ruby on Rails questions but I'm kind of drowning in documentation. I'm just hoping for some examples and/or advice and maybe some pointers to relevant documentation. Thanks.
Gem installs/uninstalls are unrelated to apps, they live on different level and do not khow anything about your app code, db and so on unless they are loaded.
Gems for rails can provide rake tasks and/or generators, for example you can look into devise gem structure on how it does this.
But i'd advise against moving code to a gem before you know you have to, like for example when you need to reuse it in different project.
To reuse code inside single project - use mixins/concerns
In general:
don't make it a gem
it's an unnecessary world of pain, pretty much always,
never make anything a gem unless you intend to use it in the same way in 3+ applications
don't extract it into a concern either,
it doesn't seem very likely that you'll do the same operation on multiple models, code reuse seems to not be an issue here and you can actually reuse code more efficiently using service classes too
a lot of experienced Rails programmers regard this practice as concerning, forgive the pun. It seems this view is not shared by the Rails development team, but at least from my experience writing service classes seems like unnecessary complexity until your project grows enough and then you need to refactor a BUNCH of stuff and you realize you would have been better off ditching concerns from the start
use a service class instead and delegate the necessary methods to it from the model
this will leave you with a clean interface to extract later and will also allow you to use dependency injection if you need to mock your XML service for tests
don't tie API requests to model callbacks, there's usually just 2-3 places where you need to do something with the API and a bunch of other cases where that may not be the case, imagine:
tests,
or if you get a requirement to implement cache column,
or a "number of visits" column
or a gem like Paperclip that thought that it wanted to add something to the model but changed his mind and instead of that just touched updated_at
or any such trickery which will make you a grandiose API spammer and a sufferer of VERRRRY slow database updates
if you DO tie API requests to model callbacks,
then you better make sure that error handling is done properly and that timeouts etc don't rollback or delay your DB operation,
best way from my experience is to run these things through ActiveJob + one of the backends (though obviously not the :inline backend and ideally one of the backends which don't use your main database and allow asynchronous job submission - sidekiq comes to mind as a candidate)

Correct rails place for no-db data fetching code

I'm looking for the "rails" design pattern for code that fetches data from other websites.
I have a rails controller in my app that fetches data not from the database, but from external API's or scraped from the web.
Where's the "rails" place to put this code.
For quick implementation, I just stuck it in a model, but the model doesn't interact with the database - or support standard model functionality - so that feels wrong, but my understanding of rails and ruby isn't yet solid enough to know where it should go.
The way the code works roughly is
controller calls model.fetchData args
the model uses HTTParty or similar to make the call
processes data
passes it back to the controller
Any advice?
Broadly-speaking I think there are two possible ways to do this:
Create a plain ruby class to contain the methods for making requests to the API(s) and processing responses from it(them). You can include the HTTParty module in this class with include HTTParty. The usual place to put this code is in lib/ (make sure that wherever you put it, the path is in autoload_paths).
If you're doing anything really complex, or the API itself is complex, you might want to consider creating a separate gem to handle interaction with the API(s). The term for this type of gem is an "API wrapper" -- if you look around, you'll see there are lots of them out there for popular services (Twitter, LinkedIn, Flickr, etc.)
Notice I haven't mentioned activerecord. If you're not going to be saving anything to the DB, I don't see any need to even create any activerecord models. You can get by with just controllers and views, and then (if needed) pick and choose components from activemodel (validations, internationalization, etc.) to make your ruby API wrapper class feel more like a Rails model. For example, one thing that I've done in an app I'm working on is to apply validations to query strings before actually making requests to an external API, which is a bit like running validations on database queries before querying a DB. See this article by Yehuda Katz for more on how to make plain ruby objects feel like activerecord models.
Hope that helps. I answered another question very similar to this one just yesterday, you might want to have a look at that answer as well: Using rails to consume web services/apis

What tools to use for a website with lots of "realtime" page updates (coming from a Rails background)?

We are planning to make a "large" website for I'd say 5000 up to many more users. We think of putting in lots of real time functionality, where data changes instantly propagate to all connected clients. New frameworks like Meteor and DerbyJS look really promising for this kind of stuff.
Now, I wonder if it is possible to do typical backend stuff like sending (bulk) emails, cleaning up the database, generating pdfs, etc. with those new frameworks. And in a way that is productive and doesn't suck. I also wonder how difficult it is to create complex forms with them. I got used to the convenient Rails view helpers and Ruby gems to handle those kind of things.
Meteor and DerbyJS are both quite new, so I do expect lots of functionality will be added in the near future. However, I also wonder if it might be a good idea to combine those frameworks with a "traditional" Rails app, that serves up certain complex pages which do not need realtime updates. And/or with a Rails or Sinatra app that provides an API to do the heavy backend processing. Those Rails apps could then access the same databases then the Meteor/DerbyJS app. Anyone thinks this is a good idea? Or rather not? Why?
It would be nice if anyone with sufficient experience with those new "single page app realtime" frameworks could comment on this. Where are they heading towards? Will they be able to handle "complete" web apps with authentication and backend processing? Will it be as productive/convenient to program with them as with Rails? Well, I guess no one can know that for sure yet ;-) Well, any thoughts, guesses and ideas are welcome!
For things like sending bulk emails and generating PDFs, Derby let's you simply use normal Node.js modules. npm now has over 10,000 packages, so there are packages for most things you might want to do on the server. Derby doesn't control your server, and it works on top of any normal Express server. You should probably stick with Node.js code as much as possible and not use Rails along with Derby. That is not to say that you can't send messages to a separate Rails app, but since you already have to have a Node.js app running to host Derby, you might as well use it for stuff like this.
To communicate with such server-side code, you can use Derby's model events. We are still exploring how this kind of code works and we don't have a lot of examples, but it is something that we will have a clear story around. We are building an app ourselves that communicates with an email server, so we should have some real experience with this pretty soon.
You can also just use a normal AJAX request or send a message over Socket.IO manually if you don't want to use the Derby model to do this kind of communication. You are free to make your own server-side only routes with Express along with your Derby app routes. We think it is nice to have this kind of flexibility in case there are any use cases that we didn't properly anticipate with the framework.
As far as creating forms goes, Derby has a very powerful templating system, and I am working on making it a lot better still. We are working on a new UI components feature that will make it possible to build libraries of self-contained UI widgets that can simply be dropped into a Derby app while still playing nicely with automatic view-model bindings and data syncing. Once this feature is completed, I think form component libraries will be written rather quickly.
We do expect to include all of the features needed for a normal app, much like Rails does. It won't look like Rails or work like Rails, but it will be similarly feature complete eventually.
For backend tasks (such as sending emails, cleaning up the database, generating pdfs) it's better to use resque or sidekiq
Now, I wonder if it is possible to do typical backend stuff like
sending (bulk) emails, cleaning up the database, generating pdfs, etc.
with those new frameworks. And in a way that is productive and doesn't
suck. I also wonder how difficult it is to create complex forms with
them. I got used to the convenient Rails view helpers and Ruby gems to
handle those kind of things.
Also, my question is not only about background jobs, but also about stuff one can might do during a request, like generating a pdf, or simply rendering complex views with rails helpers or code from gems. –
You're mixing metaphors here - a single page app is just a site where the content is loaded without doing a full page reload, be that a front end in pure js or you could use normal html and pjax.
The kind of things you are describing would be done in a background task regardless of the fornt-end framework you used. But +1 for sidekiq if you're using ruby.
As for notifying all the other users of things that have changed, you can look into using http://pusher.com or http://pubnub.com if you don't want to maintain a websocket server.

What's the benefit of using Sinatra instead of RoR if I'm only need a DB and an API

I need to build a web service, for a mobile game, to manage the states of multiplayer games. I need a database and an RESTful API to access it. I'm very familiar with Ruby On Rails and was thinking of using that since I can throw together the DB and API pretty quickly. However, since RoR is a framework for building web pages and I'm not actually building any web pages, it naturally seems like the wrong technology to use even though it would work. As such, I'm considering using Ruby on Sinatra, but I've never used it before and I'll have to kill some time learning it. For you Ruby gurus, is there an advantage to using Sinatra or a disadvantage to using RoR for what I'm trying to accomplish?
Thanks so much in advance for your wisdom!
You know Rails, you don't know Sinatra. Personally I prefer the latter for things like building APIs, but there's nothing stopping you from doing it in Rails, and there's nothing intrinsically wrong with it either. Unless you want to see this as a learning opportunity for getting into Sinatra, I'd say stick with Rails. Here's some links that might be useful btw:
Building APIs With Rails
Building a Platform API on Rails
It probably depends on your API. If you need more than just a bunch of routes then you will have to come up with your own solutions (authentication, ...).
If all you need is some RESTfulness without the added weight, Sinatra is great. All you need to know is what happens in what route and you're fine. See the Sinatra Readme which has all the information to get started.

Need help designing my first Rails app! (involves Twitter, databases, background processes)

Firstly let me mention that I'm new to web-frameworks.
I have to write my first web-app for a Uni project. I spent two weeks learning Grails and Django. Started working with Rails yesterday and loved it. So I've decided to go with it and discard my work in the other frameworks.
About the app
It's supposed to be a Twitter app that utilizes Twitter's Streaming API to record tweets which match a set of specified filters. (I'm going to use the Tweetstream gem which takes care of connecting to Twitter and capturing matching tweets).
The app's web interface should have the following functionality -
Creating new requests The user inputs a set of filter parameters (keywords to track) & URL/username/password of an existing PostgreSQL or MySQL database.
When a request is created, the web-app spawns a background ruby process. This process connects to Twitter via the Tweetstream gem. It also connects to the database specified by the user to stores received tweets.
View/terminate of existing requests
The user should be able to see a list of requests that are running as background processes by visiting a URL such as /listRequests.
See further details about a process/terminate the process
The user should be able to go to URL such as /requests/1/detail to view some details (e.g how long request has been running, number of tweets captured, etc). The user should also be able to terminate the process.
My inexperience is showing as I'm unable to comprehend -
what my models should be (maybe Request should be a model. Tweet doesn't need to be a model as it's not being stored locally)
how I'm going to connect to remote databases.
how I can create background processes (backgroundrb??) and associate them with request objects so that I can terminate then when the user asks.
At the end of the day, I've got to build this myself, so I'm not asking for you to design this for me. But some pointers in the right direction would be extremely helpful and appreciated!
Thanks!
Hmm.
Since the web app is just a thin wrapper around the heavy-lifting processes, it might be more appropriate to just use something like Sinatra here. Rails is a big framework that pulls in lots of stuff that you won't need for this project, even though it will work.
Does the "background process" requirement here strictly mean a separate process, or does it just mean concurrency? TweetStream uses the EventMachine gem to handle updates as they come, which uses a separate thread for each connection. It would be quite possible to spawn the TweetStream clients from a simple Sinatra web app, keep them in a big array, have them all run concurrently with no trouble, and simply run stop on a given client when you want it to stop. No need for a database or anything.
I'm not sure exactly what your prof is looking for you to do here, but MVC doesn't really fit. It's better to work with the requirements than to mush it into a design pattern that doesn't match it :/
Even so, I <3 Rails! Definitely get on that when you're working primarily with objects being represented in a database :)
Quite a project. Most of what will be challenging is not related to rails itself, but rather the integration with background processes. backgroundrb is a bit out of fashion. The last commit on the main github project is over a year ago, so it's likely not up to snuff for Rails 3. Search around and evaluate your options. Resque is popular, but I'm not sure if your real-time needs match with its queue-based structure.
As for your app, I see only a single model, but don't call it request. That's a reserved name in rails. Perhaps a Search model, or something along that line.
Connecting to different databases is straight forward but will require direct configuration of your ActiveRecord class during operation rather than using database.yml.

Resources