はじめに
どうも、未経験からエンジニア転職を目指しているもきおです。
現役エンジニアに入社してから初期段階でどう言ったことをするのかを聞いたら「まずはAPI開発をやったよ」と言われ、APIってどうやって作るの?と思うと同時に作ってみたい!思いました。
今回は簡単なAPIをRailsで作成したのでここに記載したいと思います。
##そもそもAPIとは?
APIに関しては以下記事で概要を掴みました。
WebAPIについての説明
本当にざっくりしたイメージだとWEBアプリのViewがないバージョンみたいだなーと感じました。もちろんViewがあるのもありますし、本当にざっくりとしたイメージなのですが。
あとはリクエストに対して返却値を返すという点では関数とかのイメージにも近いかもしれません。
作成物概要
今回はカテゴリーとアイデアという二つのテーブルを用意しアソシエーションはカテゴリ:アイデア=1:多の関係で作成しております。
リクエストに対する一覧表示と以下の場合分けによるデータ登録も目指します。
リクエストのcategory_nameがcategoriesテーブルのnameに存在する場合 ・categoryのidをcategory_idとして、ideasテーブルに登録。
リクエストのcategory_nameがcategoriesテーブルのnameに存在しない場合 ・新たなcategoryとしてcategoriesテーブルに登録し、ideasテーブルに登録するような設定
1. Rails新規プロジェクトの作成
今回はAPIモードでRailsプロジェクトを作成しました。
APIモードで作成するとAPIには不要ないViewなどがインストールされません。
APIモードでRailsプロジェクトを作成するには、rails new
するときに、--api
オプションを付けることで作成できます。
今回はmyappというプロジェクトで作成しました。
$ rails new myapp --api
2. 各モデル、コントローラー作成
続いてモデル、コントローラーを作成します。
今回はCategoryとIdeaの二つのみそれぞれ作成しました。
$ rails g model Category id:bigint name:string
$ rails g model Idea id:bigint category_id:bigint body:text
モデルを作成したらmigrationファイルの内容をDBに反映する為次のコマンドを打っていきます。
$ rails db:migrate
モデルのアソシエーションを記述します。
class Category < ApplicationRecord
has_many :ideas
end
class Idea < ApplicationRecord
belongs_to :category
end
次にカテゴリーとアイデアのコントローラーをターミナルコマンドで作成します。
$ rails g controller categories
$ rails g controller ideas
続いてルーティングを設定していきます。
Rails.application.routes.draw do
resources :categories, only: [:index, :create]
resources :ideas, only: [:index, :create]
end
今回は一覧取得と作成のアクションのみとしています。
続いてコントローラー内を記載していきます。
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
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を使用し、表示を整形化しております。以下記事が参考になりました。
この記事をもとにgem追加、モデル生成、controllerにシリアライザーを指定、出力する属性を指定を行いました。
gem 'active_model_serializers'
$ rails g serializer Category
$ rails g serializer Idea
モデル編集
class CategorySerializer < ActiveModel::Serializer
attributes :id, :name, :created_at
has_many :ideas
end
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
データ格納
gem 'faker'
$ bundle install
seedsファイルに記載します。
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と記載しターミナル上で実行すると
無事ランダムなサンプルデータが格納されていました。
Postmanを使用したAPI動作の確認
今回はAPIの動作確認にPostmanを使用しました。
こちらのURLからダウンロードして、インストールします。
Postmanの使い方は以下記事が参考になりました。
まずターミナルでrails sを実行し、ローカルでサーバーを立ち上げます。
次にpostmanを開き以下の動作の確認を行います。
Get(http://localhost:3000/categories)
先ほどseedファイルに登録したデータを取得する事ができました。
※新規投稿(Post)に関してはまた追記して参ります。
あとがき
Httpリクエストを送って値が返ってくるのは面白いですね。
API作成やAPIを叩くのにハマりそうな風潮を感じました。
また作成したら記事にしていきたいと思います。
この記事が少しでも良いと感じていただけましたらLGTMポチッとしていただけますと幸いです。