【Ruby on Rails】簡単なAPI作ってみた

## はじめに
どうも、未経験からエンジニア転職を目指しているもきおです。

現役エンジニアに入社してから初期段階でどう言ったことをするのかを聞いたら「まずはAPI開発をやったよ」と言われ、APIってどうやって作るの？と思うと同時に作ってみたい！思いました。

今回は簡単なAPIをRailsで作成したのでここに記載したいと思います。

##そもそもAPIとは？
APIに関しては以下記事で概要を掴みました。
[WebAPIについての説明](https://qiita.com/busyoumono99/items/9b5ffd35dd521bafce47)

本当にざっくりしたイメージだとWEBアプリのViewがないバージョンみたいだなーと感じました。もちろんViewがあるのもありますし、本当にざっくりとしたイメージなのですが。
あとはリクエストに対して返却値を返すという点では関数とかのイメージにも近いかもしれません。

## 作成物概要
今回はカテゴリーとアイデアという二つのテーブルを用意しアソシエーションはカテゴリ：アイデア=1：多の関係で作成しております。

リクエストに対する一覧表示と以下の場合分けによるデータ登録も目指します。

リクエストのcategory_nameがcategoriesテーブルのnameに存在する場合 ・categoryのidをcategory_idとして、ideasテーブルに登録。
リクエストのcategory_nameがcategoriesテーブルのnameに存在しない場合 ・新たなcategoryとしてcategoriesテーブルに登録し、ideasテーブルに登録するような設定
![スクリーンショット 2021-10-27 8.06.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1089852/1389e1c2-eab1-72b9-87d7-c15d2e8ff784.png)


## 1. Rails新規プロジェクトの作成

今回は**APIモード**でRailsプロジェクトを作成しました。
APIモードで作成するとAPIには不要ないViewなどがインストールされません。
APIモードでRailsプロジェクトを作成するには、`rails new`するときに、`--api`オプションを付けることで作成できます。
今回はmyappというプロジェクトで作成しました。

```bash:プロジェクト作成
$ rails new myapp --api
```

## 2. 各モデル、コントローラー作成
続いてモデル、コントローラーを作成します。
今回はCategoryとIdeaの二つのみそれぞれ作成しました。

```bash:Categoryモデル作成
$ rails g model Category id:bigint name:string
```

```bash:Ideaモデル作成
$ rails g model Idea id:bigint category_id:bigint body:text
```

モデルを作成したらmigrationファイルの内容をDBに反映する為次のコマンドを打っていきます。

```bash:migrate
$ rails db:migrate
```

モデルのアソシエーションを記述します。

```ruby:models/category.rb
class Category < ApplicationRecord
  has_many :ideas
end
```

```ruby:models/idea.rb
class Idea < ApplicationRecord
  belongs_to :category
end
```

次にカテゴリーとアイデアのコントローラーをターミナルコマンドで作成します。

```bash:Categoryコントローラー作成
$ rails g controller categories
```

```bash:Ideaコントローラー作成
$ rails g controller ideas
```

続いてルーティングを設定していきます。

```ruby:routes.rb
Rails.application.routes.draw do
  resources :categories, only: [:index, :create]
  resources :ideas, only: [:index, :create]
end
```
今回は一覧取得と作成のアクションのみとしています。

続いてコントローラー内を記載していきます。

```ruby:categories_controller.rb
class CategoriesController < ApplicationController
  def index
    categories = Category.all
    render json: categories, each_serializer: CategorySerializer, include: [:ideas]
  end

  def create
    category = Category.new(category_params)
    if catgory.save
      render json: { status: 'SUCCESS', data: category }
    else
      render json: { status: 'ERROR', data: category.errors }
    end
  end

  private

  def category_params
    params.require(:category).permit(:name)
  end
end
```

```ruby:ideas_controller.rb
class IdeasController < ApplicationController
  def index
    ideas = Idea.all
    render json: ideas, each_serializer: IdeaSerializer, include: [:category]
  end

  def create
    category = Category.new(category_params)
    idea = Idea.new(idea_params)
    if Category.exists?(name: params[:category][:name])
      idea_body.save
    else
      render json: ideas
    end
  end

  def idea_params
    params.require(:idea).permit(:body)
  end
end
```
今回のindexの一覧表示ではactive_model_serializersというgemを使用し、表示を整形化しております。以下記事が参考になりました。

https://qiita.com/onikan/items/d24ce08adf144c326812

この記事をもとにgem追加、モデル生成、controllerにシリアライザーを指定、出力する属性を指定を行いました。

```rb:Gemfile
gem 'active_model_serializers'
```

```bash:モデル生成
$ rails g serializer Category
$ rails g serializer Idea
```

モデル編集

```app/serializers/category_serializer.rb
class CategorySerializer < ActiveModel::Serializer
  attributes :id, :name, :created_at
  has_many :ideas
end
```

```app/serializers/idea_serializer.rb
class IdeaSerializer < ActiveModel::Serializer
  attributes :id, :body
  belongs_to :category
end
```

## 3. 事前データの作成

今回はseedファイルとFakerというgemを使用し、事前にランダムなサンプルデータを格納しておきます。

#### seedについて
seedファイルは、データベースにあらかじめ入れておきたいデータを定義しておくものです。
データをあらかじめ定義し`rails db:seed`することで、簡単にDBへデータを追加することができます。

#### gem 'faker'について
Fakerとはランダムな値を入れられるgemです。
　Gemfileの中にgem 'faker'を追記し、 bundle installコマンドを実行することで使用出来る様になります。


詳しくは下記の公式ページを参照してください。
【公式】
https://github.com/faker-ruby/faker

### データ格納

```:Gimile
gem 'faker'
```


```:ターミナル
$ bundle install
``` 

seedsファイルに記載します。

```ruby:db/seeds.rb
5.times do
  name = Faker::Construction.subcontract_category
  Category.create!(name: name)
end

10.times do
  category_id = rand(1..3)
  body = Faker::Food.dish
  Idea.create!(category_id: category_id, body: body)
end
```
今回あまり適しているFakerがなかったのであまりアイデアに、につかわしくないデータを格納してしまっていますがご了承ください。

記載したファイルをデータベースへ反映させます。

```:ターミナル
$ rails db:seed
``` 
実行してターミナルに特に何も表示されなければ成功です。
エラーが表示された場合は以下コマンドを打ってから再度rails db:seedを実行すれば反映されるかと思います。

```:ターミナル
$ rails db:migrate:reset
``` 

データが反映されているか確認するため、rails cを使用しデータを見てみましょう。

rails cを実行し、カテゴリーデータ一覧を見るためCategory.allと記載しターミナル上で実行すると
![スクリーンショット 2021-10-27 6.28.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1089852/51e59c2d-4347-9988-e186-a0418dcc0a5a.png)
無事ランダムなサンプルデータが格納されていました。

## Postmanを使用したAPI動作の確認
今回はAPIの動作確認にPostmanを使用しました。
[こちら](https://www.getpostman.com/downloads/)のURLからダウンロードして、インストールします。

Postmanの使い方は以下記事が参考になりました。

https://qiita.com/zaburo/items/16ac4189d0d1c35e26d1

まずターミナルでrails sを実行し、ローカルでサーバーを立ち上げます。
次に[postman](https://www.getpostman.com/)を開き以下の動作の確認を行います。

### Get(http://localhost:3000/categories)
先ほどseedファイルに登録したデータを取得する事ができました。

![スクリーンショット 2021-10-27 7.19.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1089852/f6b4e84b-c657-78a4-6baf-d008df6f4f5d.png)

※新規投稿(Post)に関してはまた追記して参ります。

## あとがき
Httpリクエストを送って値が返ってくるのは面白いですね。
API作成やAPIを叩くのにハマりそうな風潮を感じました。

また作成したら記事にしていきたいと思います。
この記事が少しでも良いと感じていただけましたらLGTMポチッとしていただけますと幸いです。