Ruby on RailsでつくってみるAPI(2日目)

やぎすけAdventCalendar2016 Rails

Posted on Dec 22


こんにちは、やぎにいです。 やぎすけ Advent Calendar 2016の22日目です。
今日が終わればもう25日まで祝休日ですね。頑張っていきましょう。

昨日は僕がRuby on RailsでつくるAPI(導入編)を書きました。

今日は無事jsonデータを返すところまで作れたものに機能を追加します。


機能の追加

昨日はデータベースに流したアイマスのキャラ情報をすべて返すAPIを作ることが出来ました。
正直言えば、あとは使う側が要らないキャラ情報を使わなくすればいいのでこれで完成!と言っても良いのですが、データ通信量等々を考えると現実的ではありません。アイマスのキャラは300人位いますし、楽曲に至っては600曲くらいありますし今も増えてます(昨日も増えましたね)。
それに対して要素があるとしたらすべてを返すAPIを使おうとすると膨大なデータ量のやりとりになります。
使う側が欲しい分だけをリクエストして、それを返す形が理想です。

というわけで、今回は昨日作ったAPIに「絞り込む」機能を追加したいと思います。

完成形としては

  • URIのクエリで名前をつけるとそれに合致した物を返す(複数合致したら複数返す)
  • でも全件ほしいときは全件返して欲しい

これを目指していきます。


ルーティングを設定する

今回は「絞り込み」の機能を実装するわけですが、同時に全件返す昨日作った部分も残しておく形になります。
同時に2つの機能を両立させるためにURIを考えましょう。
僕がGitHubに立てたIssueはこれです。

いや、これは良くない設計だろうと思われるかもしれませんが、ペーペーなので許してください。
僕は以下のように作ろう!と決意しました。

  • characters/
    昨日まではこれを叩くと全件返ってきていたが、これを叩くとcharacters/から始まるAPIの使い方、リクエストとレスポンスの仕様などがHTMLで表示されるページを出す
  • characters/search
    このsearchで絞り込みをできるようにする、例えば名前で絞り込むならcharacters/search?name="なまえ"とか
  • characters/all
    これを叩くと昨日までと同様の全件返ってくる。クエリは無し、否応なしに全件返す

このような形にしたいと思います。
ではルーティングを設定してあげましょう。
それぞれGETで叩き、それらはすべてcharacters_controllerに飛ばします。

config/routes.rbがルーティングの設定を記述する場所です。

1
2
3
4
5
Rails.application.routes.draw do
  get '/characters',        to: 'characters#index'
  get '/characters/search', to: 'characters#search'
  get '/characters/all',    to: 'characters#all'
end
  • /charactersにGETリクエストが来たらcharacters_controllerindexに飛ばす
  • /characters/searchにGETリクエストが来たらcharacters_controllersearchに飛ばす
  • /characters/allにGETリクエストが来たらcharacters_controllerallに飛ばす

そんな感じです。
これでルーティングは完成です。


コントローラーをつくる

先ほどルーティングでcharacters_controllerに飛ばす部分は作りました。では次はそのコントローラーで受け取り、処理して返却する機能部分を作りましょう。

まずは/charactersにアクセスが来た時。
これはAPIの仕様を記述したHTMLを出力するようにする予定ですが、HTMLファイルを用意していないので、現時点では404エラーを返すようにしましょう

1
2
3
def index
  head 404
end

このdef indexindexが先ほどルーティングの設定で記述したto: characters#indexの部分になります。
これで/charactersにGETが来たら404が返ってくるようになりました。確認しましょう。

chromeで確認してみるとちゃんと404が返ってきていますね。
head 404はヘッダーで404コードを返しておいてという記述です。

では次に先に全件返す/characters/allを書きましょう。これはコントローラーのallに飛ばされてきます。

1
2
3
4
def all
  @characters = Character.all
  render json: @characters
end

Character.allでデータを全部取得し、それをjsonとして返却する。
そんな感じの記述です(おそらく@はつけないほうが良い気がしている)
これも確認してみましょう。

どうやらちゃんと昨日追加した765プロのアイドルが全部返ってきていますね。大丈夫です。

それでは最後に絞り込む/characters/searchを作ってみましょう。
現在の仕様としてはnameというパラメータ(必須)で名前(一部でもOKだし漢字でもふりがなでもOK)を与えるとそれに合致した物を返す。という仕様で行きましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
def search
  if params[:name].blank?
    render json: [{"error": "100", "msg": "必須パラメーターがありません", "required": {"key": "name"}}]
  else 
    @result = Character.where("name like ?", "%" + params[:name] + "%")

    if @result.empty?
      @result = Character.where("phonetic like ?", "%" + params[:name] + "%")
    end

    render json: @result
  end
end

こんな感じにとりあえず作ってみました。
まず最初に必須パラメータのnameがあるかチェック、ない場合はエラーなjsonを返却。
次にデータベースのnameにパラメータのnameで検索し、当てはまったものを@resultに持っておく。
もしそれが空なら、ふりがなでも検索してみる。という形を取っています。

正しく動いているか確認してみましょう。

  • パラメータを渡さないときにエラーなjsonが返ってきているか

    大丈夫ですね、ベタ書きしたjsonが返ってきています。

  • 名前で検索できているか


    試しに天海で検索してみました。
    天海では天海春香さんしか居ないわけですので、1件返ってきています。
    では天海春香さんと、名前に海が入っている双海亜美双海真美姉妹もいるので、合計3件返ってきています。

  • ふりがなで検索できているか


    試しにあまみまみで検索してみました。天海さん大人気ですね。
    あまみでは合致するのがあまみはるかさんのみなので1件返ってきています。
    まみではあまみはるかまみふたみまみまみで2件返ってきています。

  • どれにも当てはまらないときは空で返ってきているか

    試しに事務員である音無小鳥で検索してみますと、ちゃんと空が返ってきていますね。

これで確認が完了しました。
絞り込むことに成功です、これで任意のアイドルの件数分だけ使う側は引っ張ってくることが出来ます。


次は

ある程度APIの形が出来てきたので、次はテストなり、Railsについてなりここまでの悪い点の修正なりを明日やりたいと思います。
個人で使うレベルにはさくっとAPIを作れるので大変ステキなフレームワークですね。Railsを普通に触るのは初めてですが、とても楽しいです。
ちゃんとレスポンスが返ってくるのを自分で作って見れるのは成果がわかってモチベーションの向上にもつながりますね。

以上、やぎにいでした!



comments powered by Disqus

<< Ruby on RailsでつくってみるAPI(まとめと考察)     Ruby on RailsでつくるAPI(導入編) >>



2016 やぎ小屋