Creating web-API routes with Active Record & Sinatra
Published: 2022-06-07 04:20:55

Javascript, and react have been some very fun and interesting topics to learn about in these last couple of weeks. Phase-3 which included: Ruby, Active Record and Sinatra is no exception. It is very exciting to think that I can now create the not only the front-end of an application but now the back-end as-well. A topic that certainly stood out for me was building Sinatra applications, but more specifically, building web-API routes. 

For this example we'll be using a data table called Dogs with the following attributes: name, breed, age, trait and image, as-well as a Dog model. Our goal is to develop web-based API routes that can be used to receive requests from a front end application in the JSON format.  

```
class Dog < ActiveRecord::Base 
    
end
```
These routes will go in a folder named controller. While not doing this won't kill your app, it is a common pattern in web development followed by many web app developers. This pattern is known as the MVC or Model-View-Controller, which is used to separate the different types of components an app might have.  The include the models which work with the database, and controllers which are in charge of receiving user requests. 
Depending on the front end request the user makes, we will modify our web-API routes. We will mainly focus on the GET, POST, PATCH and DELETE crud methods. We'll start with the GET request. 


**GET Request** 

We first want to let the application controller know this is a get request, instead of using def which is how we begin most ruby methods, we'll start with get.  Then we define what we want our route to be, in our case we'll use **_"/dogs"_**. Thanks to active record we can also access all our dogs from the database using **_Dog.all_**, we then convert these objects to JSON formatted strings and thats it! 

```
class ApplicationController < Sinatra::Base
  set :default_content_type, 'application/json'
  
 
  get '/dogs' do
    dogs = Dog.all
    dogs.to_json
  end

end  
```
We can double check to make sure our web-API route works by making a fetch request, which should return an array of objects with the correct keys corresponding to our column names. Which it indeed it does! 

```
[
  {
        "id": 162,
        "name": "Bella",
        "breed": "French",
        "age": 2,
        "trait": "Curious",
        "image": "https://images.unsplash.com/photo-1616312513065-28cf4313abda?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1yZWxhdGVkfDE0fHx8ZW58MHx8fHw%3D&w=1000&q=80"
    },
    {
        "id": 163,
        "name": "Tony",
        "breed": "Beagle",
        "age": 1,
        "trait": "Couragous",
        "image": "https://images.unsplash.com/photo-1611306133736-56a3b973b2cc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8YmVhZ2xlJTIwZG9nfGVufDB8fDB8fA%3D%3D&w=1000&q=80"
    }
  ]
```
 

**POST** 
If the user wants add a new dog to our database, we need a way to access the data submitted in the body of the request. We can access this data through the [params hash](https://flatironschool.com/blog/how-params-works-in-rails/). 
 To make the post route we can use use the same route used for the patch request, as the user is adding an additional dog instance to our already existing dog database. We are however creating a new dog, instead of using _**Dog.all**_ which lists all our dog instances in the data base, we would instead use **_Dog.create_** followed by our params to match our database attributes to the received data. 

```
post "/dogs" do
    dog = Dog.create(name: params[:name], breed: params[:breed], age: params[:age], trait: params[:trait], image: params[:image])
    dog.to_json
 end
```

**PATCH**

A patch request is similar to a post request but with an added bonus. If a user wants to edit the name of one of dogs in the database, we need a way for our route to specifically edit that particular dog. We'll define our route as "**_/dogs/:id_**" as each of our dog instances has its own id thanks to active record. We start by first finding the specified dog by the user. Once again we use active record, **_Dog.find(params[:id])_**. Now that we have the specified dog, we can update our database accordingly. 

```
 patch '/dogs/:id' do
    dog = Dog.find(params[:id])
    dog.update(
      name: params[:name],
      breed: params[:breed],
      age: params[:age], 
      trait: params[:trait],
      image: params[:image]
    )
    dog.to_json
  end
```

**DELETE** 

A delete response much like the patch request needs the id of the specified dog we want to delete. The route we'll use is **_"dogs/:id"_**, find the dog in our database and then delete said dog, **_Dog.find(params[:id]).destroy_**. 

```
 delete "/dogs/:id" do
    dog = Dog.find(params[:id])
    dog.destroy
    dog.to_json
  end
```

There are many possibilities when accessing the data in our database when making API routes. We can make it so we only return the first five instances in our database Dog.all.limit(5) in a fetch request, or order them alphabetically. We can edit how we want our data to be returned to the user based on the request.  

Being able to set up our own web API is the highlight of this phase for me, although learning active record is a close second. I am very excited to see what new things I'll learn in the ruby on rails section, and what kind of projects I'll be able to create.