Organize external API calls in Rails 4 - module or class?

I am creating a Rails application that will use quite a few external APIs, such as SalesForce, FolderGrid (e.g. Dropbox), etc., which will be synchronized with my database. I have never worked with external api calls, so I created some basic Ruby scripts with scattered methods to test the invocation of these resources. Now I would like to implement them with my full Rails application.

So far, I started by creating a directory in the / lib folder to host the api call modules / classes.

/lib/apis/foldergrid.rb

Now I'm not sure what the best approach would be to 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 the module? Do I need a module? What should be in the classroom? How can I use these methods in my models and controllers, where necessary? Are there any best practices regarding external APIs?

Any resources, links and / or deeper understanding are highly appreciated.

+5
source share
2 answers

I have an application that does this too (extracts data from several APIs), so I can tell you what I would do (or in some cases, what I would do now if I started all over again).

Data storage

First of all, if you already save the data extracted from it into the Rails application, then you will have models representing the data itself. So what would you indicate in your controllers if your controller is not responsible for calling the API.

Use gems if possible

Secondly, do not forget to use the existing gems that exist for the API so that you do not recreate the authentication wheel, parsing JSON from the application, etc. For example: there is a rest-force for salesforce.

Use Ruby Objects in Lib to Map Between Your Models and API Responses

Thirdly, I would make classes that displayed data between the API responses and your models in "Plain old ruby ​​objects" and saved them in the lib/apis folder (there is no need to store them in the module, but IMHO in these cases). They can be very functional, and in the case of data mapping, this is normal.

API without existing gems

In these cases, I would definitely save them in one or more classes under the module in my own folder in lib. That way, you can analyze them, if necessary, like a gem (or if you take the time to start using them, I'm sure others can benefit). I just started this journey this week using the Infoconnect API that didn't have a Gem (or any code samples in any language). But I'm not very far.

If necessary, create service objects for the code between V and C (view and controllers)

If you really need to do something to interact with users for API information or anything that causes this request, I would put them in service objects so that your code does not get bloated in the view or controller.

+5
source

What should be in the module?

The module must contain code that is divided by different classes or can be added to one class.

Do I need a module?

No, you can achieve the same with inheritance. If there is no code to share, then you probably don't need a module.

How can I use these methods in my models and controllers, where necessary?

Access to them is carried out using a class from the controller:

 SalesForceAPI.get_data 

"Module or class?" this is an old question in Ruby and any other language that supports both.

I would encapsulate the functionality for each API in the class. For example, you can have the SalesForceAPI class. Then, if you need to split functionality between classes for authentication, creating a folder, checking files, or uploading files, you can create an API class.

Each of the classes that need access to the API class inherits it:

 SalesForceAPI < API 

You can achieve the same by creating an API module and mixing it with other classes. In this case, it largely depends on preference, because any solution is good.

FWIW, I don’t know if there will be many common functions for authentication, creating a folder, checking files or downloading files, because each API can work in a completely different way. However, if they are a REST API, you can create some helper REST methods and put them in an API class.

An excellent, understandable, and complete resource on the topic Practical Object Oriented Ruby Design .

+1
source

All Articles