Androidはワンツーパンチ 三歩進んで二歩下がる

プログラミングやどうでもいい話

ポケット糖質量にスマホ向けAPIを追加

こんにちは。さくらです。
www.pockettoushituryou.com

ポケット糖質量でスマホのクライアントアプリを作りたいなと思っています。

サイトの横幅を縮めると下の画像のように縦長で間延びして見辛い印象です。

f:id:sakura_bird1:20170408191353p:plain

とりあえずAndroid版を作って(iOS版も作りたいけどスキルがないのだった)みようと思っています。


今日はそれ用のAPIを追加しました。
最初grapeというgemを使ってAPIを書こうと思っていたのですが、自分のアプリにはいらない気がしてrailsデフォルトのまま作っています。

/api/v1/kinds
のような形でアクセスできるようにnamespaceをこのように定義しています。

config/routes.rb

Rails.application.routes.draw do

  namespace :api, format: 'json' do
    namespace :v1 do
      resources :kinds, :foods
    end
  end

フォルダはこのような構成です。
f:id:sakura_bird1:20170408192005p:plain


コントローラーはこんな感じです。
app/controllers/api/v1/kinds_controller.rb

module Api
  module V1
    class KindsController < ApplicationController
      include Authentication

      before_action :authenticate

      def index
        @kinds = Kind.all
        j = @kinds.to_json(only: [:id, :name, :type_id])
        render json: j
      end
    end
  end
end

include Authentication としているのは、上のフォルダの構成の画像で言えば
app/controllers/concerns/authentication.rb
のAuthentication Moduleになります。
HTTPヘッダーに付加するトークンで認証処理をしています。
こちらを参考にさせていただきました。ありがとうございます。
qiita.com

ソースはこんな感じです。

app/controllers/concerns/authentication.rb

module Authentication
  # you might need to include:
  # include ActionController::HttpAuthentication::Token::ControllerMethods

  def authenticate
    authenticate_token || render_unauthorized
  end

  def authenticate_token
    authenticate_with_http_token do |token, options|
      token == ENV['HTTP_HEADER_TOKEN']
    end
  end

  def render_unauthorized
    # render_errors(:unauthorized, ['invalid token'])
    obj = { message: 'token invalid' }
    render json: obj, status: :unauthorized
  end

end

これで特定のトークン文字列がヘッダーに付加されていなかったらアクセス拒否されます。

確認はコマンドラインから次のように叩きます。成功するとJsonが表示されます。

curl -X GET -H 'Authorization: Token hogehoge' -H 'Content-Type:application/json' http://localhost:3000/api/v1/kinds

ブラウザから確認する場合はChrome Extensionなどのツールでヘッダーを付加できるツールがあるので活用しつつURLのところに
http://localhost:3000/api/v1/kinds
と入力します。私は教えてもらったModHeaderを使用しました。下の画像のように入力します。

f:id:sakura_bird1:20170409003942p:plain


サーバーにHTTP_HEADER_TOKENの環境変数を設定するのを忘れないようにします。

私の使っているサーバーはherokuなのでこのようなコマンドになります。

$ heroku config:set HTTP_HEADER_TOKEN="hogehoge" --remote staging

$heroku config:set HTTP_HEADER_TOKEN="hogehoge" --remote production

あとはデプロイしてstaging,productionのドメインでテストします。



2017/04/17追記
jsonを作る箇所をこのように定義していましたが、これだと思ったようなJsonの形にならないので変更しました。

        @kinds = Kind.all
        j = @kinds.to_json(only: [:id, :name, :type_id])
        render json: j

結果は↓のように、配列には名前が付いていません

[{"id":1,"name":"穀類","type_id":1}
,続く]

↓のように配列にkindsという名前を付けたいのでした。

{"kinds":[{"id":1,"name":"穀類","type_id":1},続く]}

このように変更して望みどおりになりました。

        kinds = Kind.select('id, name, type_id')
        hash = { :kinds => kinds }
        render :json => hash



>Ruby on Rails 5アプリケーションプログラミング [ 山田 祥寛 ]

価格:3,888円
(2017/4/9 00:57時点)
感想(0件)



>Ruby on Rails 5 超入門 [ 掌田津耶乃 ]

価格:2,916円
(2017/4/9 00:55時点)
感想(0件)



>実践Ruby on Rails 4 [ 黒田努 ]

価格:3,780円
(2017/4/9 01:01時点)
感想(0件)



>パーフェクトRuby on Rails [ すがわらまさのり ]

価格:3,110円
(2017/4/9 01:00時点)
感想(0件)



>はじめての「Ruby on Rails」5 [ 清水美樹 ]

価格:2,484円
(2017/4/9 01:00時点)
感想(0件)