ポケット糖質量にスマホ向けAPIを追加
こんにちは。さくらです。
www.pockettoushituryou.com
ポケット糖質量でスマホのクライアントアプリを作りたいなと思っています。
サイトの横幅を縮めると下の画像のように縦長で間延びして見辛い印象です。
とりあえず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
フォルダはこのような構成です。
コントローラーはこんな感じです。
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を使用しました。下の画像のように入力します。
サーバーに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
|
|
|
|
|