Seeding my Sinatra project from an external API

Ely Karr
4 min readMar 6, 2022

--

Oh, to make your Sinatra project sing in the key of seed (from an API)

In this post, I’ll share how I populated data into a Sinatra backend using an external API. I decided to create a poetry app, and I had initially planned to simply manually seed data (perhaps to seed in a few poems, and to allow further entries to be created and persisted by using the site). However, it occurred to me that it would be worthwhile to incorporate data from an external API for two main reasons- first, that in production environments, there seems to often be a need for multiple APIs to called in a variety of different ways, and that this would be a good chance to see how this might work. And second, that it would make for a much more interesting app, with a robust backend that feels like much more to work with- a small taste of what it might be like to interact with a production environment. I now have thousands of poems in my project- needless to say, a lot more than could be manually entered in any reasonable amount of time.

There are four basic steps that need to happen for this entire process:

  1. Make a GET request to an endpoint of an API that can provide data.
  2. Once a JSON response is received, parse the data into a ruby hash.
  3. Find the data from that response to be saved into your database.
  4. Use Active Record to save that data into your database.

With this general process in mind, you’ll need to apply these steps according to the endpoints of the API being called and the structure of the database to be seeded. The process in this particular case is the following:

  1. GET and save all of the authors from the /authors endpoint into the Poet class.
  2. Make another GET request for all of the poems for each poet, and save them into the database by their Poet association (has_many).

The first step with using Ruby to make a call to an API would be to install the Rest client gem. With the Rest client gem installed, I created a method for making the request to the API. In my seed file, I made a GET request to the /author endpoint as follows:

On line 7, the GET request is saved to a variable, which is then parsed into a ruby hash on line 8, using JSON.parse. On line 9, the ruby hash is iterated over using the each method to create new entries in the database for all of the authors, by calling on the Poet class. To avoid duplicates or errors, the authors were saved into the database by calling the .find_or_create_by method on the Poet class.

With all of the authors available on the API now saved into the database, I could then make the second call to the API, in order to GET all of the poems for each poet.

On line 13, the entire Poet class is iterated over, once more with the each method, and then the name of the poet is interpolated into the GET request (notice the name of the poet, which at minimum includes a first and last name in a string, is split on the spaces using .split(“ “) and then joined together with %20, which represents the space character in REST conventions).

On line 15, the JSON response is once again parsed into a ruby hash, which now contains all of the poems for a particular poet.

For the final (and most magical) step, every element in the hash (each containing one poem) is iterated over and entered into the database using the Active Record chaining association on line 17- poet.poems.create. This final step here demonstrates the power and simplicity of Active Record, which takes care of creating the relationship between every poet and their poems, as indicated in the class models.

One small useful indicator for the seeding process is to include print “.” after the iteration for each poet, so that when seeding, a period is printed to the console, providing a visual confirmation that this iteration is occurring.

At last, call the method at the end of the file:

Once you’re ready to seed, enter rake db:seed in the console to run the file and seed your database.

I hope you’ve found this helpful- in any case, please do feel free to leave me any comments if you feel so inclined. Happy coding!

--

--