I am creating a Rails app that will use quite a few external APIs such as SalesForce, FolderGrid(like Dropbox) etc., which would all sync to my database. I've never worked with external api calls so I created a few basic Ruby scripts with scattered methods to test the call to those resources. Now I would like to implement them with my full Rails app.
So far, I started off by creating a directory in my /lib folder for holding the api call modules/classes..
/lib/apis/foldergrid.rb
Now I'm not sure what the best approach would be towards organizing the code. In my standalone Ruby scripts, I have methods for authenticating, creating a folder, auditing files, downloading files
etc.
What should be in a Module? Do I even need a Module? What should be in a class? How do I make sure I can use these methods in my models and controllers where needed? Is there a best practices concerning external APIs?
Any resources, links, and/or deeper understanding is highly appreciated.
External API allows you to create workflows that send HTTP requests to external web servers, API endpoints, and URLs. This allows your bot to integrate with almost any third party service or even your own server.
Having spent a lot of time working with JavaScript and React recently, I thought I'd revisit Rails for some practice, and wanted to write a post about creating a RESTful API using Ruby on Rails. Rails now has the option to create an API application which is a slimmed down version of a traditional Rails web app.
I have an app that does this too (pulls data from multiple APIs) so I can tell you what I would did (or in some cases what I would do now if I was to start over).
First off if you are already persisting the data pulled from those into a Rails app, then you will have models representing the data themselves. So that's what you would refer to in your controllers unless your controller is in charge of calling the APIs.
Second make sure to leverage existing gems that existing for the APIs so you're not recreating the wheel of authentication, parsing the JSON to and from the app, etc. For example: there is a rest-force gem for salesforce.
Third, I would make the classes that map data in between API responses and your models into "Plain old ruby objects" and store them in a lib/apis
folder (no need in these cases to store in a module, yet IMHO). They might end up very functional and in the case of mapping data, that is ok.
In those cases, I would definitely keep them in one or more classes under a module, in their own folder in lib. That way you can parse them out if needed as a Gem (or if you to take the time make them a Gem to start with, I'm sure others could benefit). I just started down this road myself this week using Infoconnect's API which didn't have a Gem (or any code samples in any language). But I'm not very far along.
If you do end up needing to do anything to interact with users for the API information or anything that calls those request, I would put those in service objects so your code doesn't get bloated in the view or controller.
What should be in a Module?
A module should contain code that is shared by different classes, or it can be added to a single class.
Do I even need a Module?
No, you can achieve the same thing with inheritance. If there is no code to share, then you probably don't need a module.
How do I make sure I can use these methods in my models and controllers where needed?
You can access them using the class from within a controller:
SalesForceAPI.get_data
"Module or class?" is an age-old question in Ruby, and any other language that supports both.
I would encapsulate the functionality for each API in a class. For example, you can have a SalesForceAPI
class. Then, if you need to share functionality between the classes for authenticating, creating a folder, auditing files, or downloading files, you can create an API
class.
Each of the classes that needs access to the API
class would inherit from it:
SalesForceAPI < API
You can achieve the same thing by creating an API
module, and mixing it into the other classes. In this case, it's largely a matter of preference, because either solution is good.
FWIW, I don't know if there would be much shared functionality for authenticating, creating a folder, auditing files, or downloading files, because each API can work quite differently. However, if they are REST API's then you may create some REST helper methods and put them in the API
class.
A great, easy to understand, and complete resource on the topic is Practical Object Oriented Design Ruby.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With