Web API the Good Parts2章

前置き

近況


ざっくりと書くと、お前エンジニアなのに勉強しなくていいの?という状態

  1. 免許が取れたので単車を乗り回している(運転が楽しくて毎日、運転しているような)
  2. 昨年よりも比較的、仲がいい友人(男女問わず)と遊ぶ機会が多くなったかも…
  3. 気の合う仲間と組んで、(Swiftで)アプリ作っている
  4. その気の合う仲間への技術指導していたり…

なんだか、教えることが多くなって自分が学習している時間が比較的減ってきているそんな感じががが

そういう訳なので


本屋でざっくりと見かけてツボに嵌った本を読んでいこうかと

「Web API The Good Parts」

なのですが、上記3,4が結構あるので中々進まないという(ぉぃ

ということなので、なるたけ気になるところ(覚えておくべきところ)だけまとめていこうかなと

斜め読みした感じでは、結構ツボに嵌る内容なので自分のバイブルに入選してもいいかなと思ってたり。

エンドポイント設計

  1. 公開する機能を先に設計する
  2. 覚えやすく、どんな機能を持つURIかひと目で分かるようにする
  3. HTTPメソッドの活用
  4. 設計の注意点
  5. クエリパラメータ
  6. ログインや認証
  7. ホスト名とエンドポイント

1に関して


どんなAPIが必要かどうかを先に洗い出しておく

2に関して


  • 短く入力しやすいURI
  • 人間が読んで理解できるURI
  • 大文字、小文字が混在しないURI
  • 改造しやすいURI
  • サーバ側アーキテクチャが反映されていないURI
  • ルールが統一されたURI

3に関して


HTTPメソッドを有効活用

  • Restfulな形で活用すれば、一般的な形

4に関して


  • 複数形の名詞を利用する
  • 利用する単語に気をつける((ProgramableWeb)[http://www.programmableweb.com/]等、他のサービスを参考に)
  • スペースやエンコードが必要な文字は避ける
  • 単語をつなげる場合はハイフンにする(SEO的に有利なことも)

5に関して


  • 相対位置を使用する場合、データ数が多くなると取得件数が減ること、更新頻度が高いものは不整合が起きやすくなることに注意
  • 絶対位置を使用する場合、クエリパラメータが「x以降」,「この日付よりも古いもの」という形でクエリパラメータをもたせたほうがよい
  • 日付の形式は、RFC3339に規定されている「1970-01-01T00:00:00Z」の形にする
  • 絞り込みのパラメータは、「q」のような形は曖昧検索に取られやすいので完全一致の場合は適切なパラメータにすること
  • 一意なリソースを表すのに必要な情報: パス
  • 省略可能: クエリパラメータ

6に関して


  • OAuthを使用して、標準的な形にする

標準的なOAuthに則るとエラーメッセージ(RFC6749, RFC6750)は、以下のような形式となる (当然ながらhttpステータスは401)

1
2
3
{
  "error": "invalid_token"
}

7に関して


  • ホスト名にapiを入れるのが主流
  • 企業で複数のサービスをホストする場合、例外的なホスト名
  • サービスとしてのapiの場合はホスト名にapiをいれたほうがよい(外部から使われるため)
  • プラットフォームの場合、service等をホスト名にいれる

まとめ


  • 一般的なURI設計がそのまま適用できる
  • APIならではのルール、デファクトスタンダードがある
  • URIはリソースを表すものなので、URIとHTTPメソッドの組み合わせで処理の対象と内容を設計をする

Good

  • 覚えやすく、どんな機能を持つかが一目で分かるようにエンドポイントにする
  • 適切なHTTPメソッドを利用する
  • 適切な英単語を利用し、単数形、複数形にも注意する
  • 認証はOAuth2.0を使う

iOSで複数のmodalを同時に閉じる

こんな状況


[A→B→C→Dの順で画面を開いた状況で、D->Aへ戻りたいという状況

やり方


戻りたいところのmodalを指定すると、その前のものは全て閉じることができました

1
self.presentingViewController?.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)

画面遷移の状態を覚えてないと辛い感じですね

元ネタ


https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/index.html#//apple_ref/occ/instm/UIViewController/dismissViewControllerAnimated:completion:

Emacsを再起動せずに設定を反映させる

やりたいこと


Emacsを再起動せず、設定内容を反映させたい

解決編


追加した部分だけ、評価する

1
M-x eval-region

今、現在実行している全てのバッファの式を再評価する

1
M-x eval-buffer

そもそもの設定ファイルを読みなおす

1
M-x load-file RET ~/.emacs.d/init.el

jQueryが見つからないよエラーの解消法

はじめに


今更ながら、Rails3.2のアプリをRails4までアップデートしました。
そのとき出たエラーと解消方法を残します。

当該のエラー


それがこれ

1
couldn't find file 'jquery'

正直、なんで?という感じ

解消方法


Gemfileの記述が変わってたことが原因でした
(asset compile周りの仕様変更)

Rails3.x系は、Gemfileに以下がありました

1
2
3
4
5
group :assets do

ここにasset compileで使用するgemがある

end

ところが、Rails4系になるとasset groupは無くなる仕様に変わったみたいです。
代わりの設定は、config/application.rbになるようです。

メジャーアップデートの前に、移行ガイドに目を通せってことですねw

Android Bazaar and Conference 2014 Springに行ってきた

はじめに


もう殆ど、Androidをやっていない身ですが情報追っかけ程度に参加してきました。

因みに、当日は寝坊してやべぇって言ってたのは内緒w

興味が湧いたセッションは2つぐらいだったので、それさえ聴ければいいかなーぐらいの感覚で行ってきました。

というわけで、当日のメモに加筆修正したものを残します。

UI/UXデザイントレンド 2014


デザイントレンド

  • 質感がわかるようなデザインに変わりつつ
  • スキュモーフィズムからフラットデザインへ
    • 装飾を外してシンプルに
    • flatvsrealism.com
  • フラットのほうが意図が伝わりやすい
    • Androidのデザインガイドラインもフラットなものに変わっている
    • Googleも力を入れていることがわかる

Androido UI

2011年のTrend
  • 派手
  • 白いテキスト
  • リアルで立体的なアイコン
  • この当時はiPhoneが流行っていたので、似たようなデザインになるような感じ
2012年のTrend
  • 黒やダークな背景
  • ダークやマットな色
  • 水色や白のテキスト
  • レイアウトがグリッドスタイル
  • ON/OFFボタンなど、ルールが破綻してるところもあった
  • ボーダレスUI(ひと目でボタンなのかわからないようなものを指す)
2013年のTrend
  • 白や明るい背景
  • カードスタイル(Googleの殆どのアプリが対応)
  • 影を入れたりして立体感を出している
    • (GooglePlayでの)評価が上がりやすい
    • platformとの統一感が重要
  • ボーダレスUIは健在・・・
  • シンプルなアイコンやイラスト

2014年(1Q)のTrend

  • Yahoo weatheアプリのような感じになりつつある
    • カードスタイルから変わる
  • 端末のスペックが上がってきたから対応できるようになってきた
    • 写真やグラデーション

Android wear

  • サークルUI
    • アイコンが丸くなっているものが増えてきた
    • フラットで押したりする領域が分からないという問題への回答かも
  • より大きな書体
  • 写真やビジュアルリッチに

webサイトデザインとの違い

  • スケーラブル、モニターによっての情報量が違う
    • スマホ向けは、シンプル・単機能・担当直入な処理デザインに

QAメモ

  • アプリのUIデザインはどうするの?
    • ゲームUIとアプリUIとは全く違うので、機能を入れ過ぎないようにする
  • インタラクションにもデザイナーが関わってやっていくほうがよい
    • ダサいものになりづらい
    • エンジニアも積極的にデザイナーと一緒にやっていく
  • 流行を追っかけるためのデザインサイト
    • Android niceties
  • デザインにも事業戦略が必要
    • 古い端末もサポートするのか?など
      • 2.x系はもう切ってもいいかも
      • 1つで全部の対応は難しいので避けたほうがよい

トレンドの変遷(最近のAndroidアプリのトレンドについて)


はじめに

  • セッションはAndroid Pattern Cookbookの解説&補足
  • AndroidPatternCoockbookのデモアプリあるので確認しながらだと理解進むかも
  • 最近の開発は、タブレット対応も必須

ダッシュボードデザイン

  • メインコンテンツが複数ある場合、機能が視認しやすいので優位
  • 1回操作挟むのは、ダメじゃね?

タブ

  • スワイプでタブ間の行き来ができるように
  • 各コンテンツのスワイプはできない・・・

NvigationDrawer

  • ガイドライン化
  • メジャーなものは大体NvigationDrawerを使ってる
  • アイコン左、カウンターは右

アプリの世界観も重要

  • FeedlyやEvernoteが筆頭
    • 出しすぎなところもあるけど・・・

上部にユーザー情報を表示が多い

  • アカウント切り替えが難しいタイプも・・・

オリジナリティを出す

  • 黒はデザインが難しい

アクションバー

  • アクションバーとコンテンツの配色は雰囲気になる
    • 白だと明るい、清潔感が出やすい
    • 白+黒だと引き締まる
  • アクションバーの背景
    • 下に影をつけるものも多い
  • フレームワークのアクションバーを使ったほうがよい
    • アプリの世界観次第で独自路線があるならいいけど。

フォント

  • ライセンス問題になりやすいので、フォントはアプリに内蔵しないほうがいい
  • fontFamilyを使うと改善できる可能性がある
    • font同士を組み合わせて使うほうといい

ヘルプポップアップ

  • 注目させたい場合、アニメーションを使うと注目させやすい

インストラクション

  • 「ここを押す」などの表示を入れやすい

チュートリアル

  • 読む?テキスト量は減らしたほうがいい
  • 画像で伝え、1行ぐらいがいい
  • 無くてもいいかの検討も重要

viewpager

  • スクロールできるタブ
  • タイトルストリップ
  • インジケータ
    • ページの移動でアイコンが変わるもの
  • ページ切り替えでエフェクト

タブレット対応

  • スケールアップは微妙な対応
    • データ量が無ければ、それでもいいかも
    • 画像入れるなりで、余白を減らす
  • macroreflow
    • グリッドの並び替え
      • 数も重要になる
    • スマホはリストで対応してやるといい
  • master/detailパターン
    • gmailアプリとかgoogle playアプリ

Railsで定数を定義する

はじめに


Railsで定数を作るとき、いつもどうしてたっけ?っていう個人まとめをつくってみました。

決定版みたいなものが無い感じというのもあったりするので参照用という感じです。

グローバルな定数定義


以下のような感じの内容で、「config/initializers」に適当なRubyファイルを作成して定義します

1
2
HOGE = "HOGE"
FUGA = "FUGA"

もしくは、yamlに定数を切り出して、実行タイミング(Rails起動時)にロードという方式でもいいかもしれません。
# yamlに切り出すと管理が大変になるかも・・・という欠点は無きにしもあらずですね。

欠点は以下が考えられます。

  • namespaceの概念が無いので少々使いづらい
  • 環境ごとに値を変更したい場合、切り替え処理を自前でやる必要がある

特に、環境差分とか無ければこれでいいかもしれませんね。
# 尤も、namespaceを使わなくて済む程度という前提が付きますが・・・

コントローラー内で共通な定数定義


以下のような感じで、app/controllers/application_controller.rb 内で定義します

1
2
3
4
class ApplicationController < ActionController::Base
  HOGE = "HOGE"
  FUGA = "FUGA"
end

単にApplicationControllerがすべてのcontrollerのスーパークラスになっているから参照できるというだけの話です。 # あまりここに定義はしたくないですね。

rails_configを使って環境ごとに変更する


rails_configというgemを使う方法ですね。

以下をGemfileに記述し、インストールします。

1
gem 'rails_config'

rails_configを使うように初期設定をします(ただのインストールですが)

1
$rails g rails_config:install

ファイルに関しては以下の通り

環境 ファイルパス
全ての環境で共通 config/settings.yml
ローカル環境 config/settings.local.yml
開発環境 config/settings/development.yml
テスト環境 config/settings/test.yml
本番環境 config/settings/production.yml

YAMLの記述は以下のような感じで行います

1
2
3
hoge:
  fuga: 'fugafuga'
  test: 'test'

使用する場合は、以下のようなコードで出来ます。

1
2
3
Settings.hoge[:fuga]
Settings.hoge['fuga']
Settings[:hoge][:fuga]

他に、同じようなことをする有名なgemに、「settingslogic」があります。
以下の感想でsettingslogicはあまりつかわないです。

  • 一つのファイルで全て定義なのでファイルが肥大化しそう
  • クラス定義も作る必要があるので若干面倒(シンプルに使えない)

RubyでSolrを使うときに気をつけること

はじめに


タイトルは釣り臭が半端ないですねw

正確なことを言うと使用ライブラリは、
特性を理解の上で使いましょうということが言いたいだけです

RubyでSolrを使う際のライブラリと言えば


大体、以下の2つになると思います

前者は、シンプルな機能に対して、後者は多機能になっています

RSolr


ここら編は、ドキュメントを見たほうがよいですが自分の理解をダラっと

  • 接続やプロキシは、自分で設定できる(タイムアウトやリトライ設定も可能)
  • 上記の為、(実装に応じるが)自由に検索先のスキーマを変更できる
  • 検索クエリ(ファセットクエリ等も含む)は自前で実装しないといけない
  • rowsやstartなども自前で実装する必要がある
  • 更新や削除(クエリベースやidベースで)もできる上にメソッドとして用意してある
  • responseはハッシュになっているので、自前で検索結果を整形(ActiveRecordオブジェクト等)する必要がある
  • ページングも対応している

一声で言うと・・・

  • クエリ構築は自前でやる必要がある
  • 検索結果の整形も自前でやる必要がある
  • 実装次第で、接続先のSolrも自由に変更することができる

シンプルとか言っておきながら、結構ありますね^;;

実際、使うとわかりますがかなりシンプルですよ

sunspot


こちらもドキュメントを見たほうがよいのですが・・・

  • 検索クエリ(facetクエリなら)をDSLライクに記述できる
  • 検索はdismaxで行ってくれる
  • 検索クエリの結果はActiveRecordオブジェクトで取得できる
  • 全文検索も直感的に記述できるうえにboost値も設定できる
  • ページングやグルーピングにも対応している
  • 緯度、経度のデータも検索できる
  • 検索ハイライトやスキーマデータの結合にも対応している
  • indexingもsunspotのみで完結することができる(削除もできます)
  • 勿論、手動でクエリを構築することも可能
  • sunspot自体がRSolrに依存しているので、その気になればRSolrの機能も一応使うことができる

これだけ、高機能なので当然の如く欠点もありまして・・・

  1. Solrのスキーマ定義がsunspotに依存した形になってしまうこと
  2. indexするデータの一部もsunspotに依存した形になってしまうこと
  3. Solrのフィールドに対応する形でActiveRecordのmodelクラスに定義が必要になること
  4. sunspotが吐き出すクエリを理解しないと使いづらいこと
  5. sunspot自体がmethod_missingを使った実装なのでコードが読みづらいこと・・・

日本語を扱う場合の注意点


基本的に、検索文字列の処理はSolr側のtokenizerで行われます。

ところがsunspotで日本語を使う場合だと、全文字列がエスケープされてしまいます。

例えば、「あいうえお」を検索したい場合だと「\あ\い\う\え\お」になってしまいます。

因みに、英語検索は問題ありません。

原因がどこにあるかと言うと、 restriction.rbにあります。

具体的な箇所は、このmodule内で使用されているescapeメソッドが原因です。
このescapeメソッドの実装は、char.rbですね。
つまり、RSolr側の不具合に近いでしょう。
また、RSolrを使って自前で実装するときもこのescapeメソッドを使用しないほうがいいです。

sunspotの依存gem側の問題なので、簡単に修正するのも難しいですね。

対処方法は?


モンキーパッチを使えば、対処できました。

escapeメソッドを使っているところを全部上書き実装すればいいだけです。

Railsで使う場合だと、「config/initialize/sunspot.rb」みたいなのを作ればいいですね。
その中で、上記の処理を使えば対応可能です。

まぁ、根本解決ではないなと思いますが・・・

MacにSolrをインストールして動かしてみる

はじめに


Solrといえば、全文検索システムですね。

で、これをMacにインストールしてみようということやってみます。

とはいえ、普通にtarballダウンロードして解凍→java -jarだと面白くないですね。

折角、Homebrewを使ってるのでパッケージ管理の上で実施してみます。

インストール


Homebrew使いであれば、お馴染みのコマンドでスンナリインストールされます。

1
$brew install solr

Solrの起動


ぶっちゃけ、こいつが若干の癖ものだったりします。

# 記事書くキッカケw

一言で言うと、solrの設定(solr.xml)があるパスをフルパスで渡して上げる

実はこれだけです、インストールしたSolrはサンプルが同梱してあるので起動してみます。

1
$solr /usr/local/Cellar/solr/4.7.0/libexec/example/example-DIH/solr/

スキーマレスのサンプルなら

1
$solr /usr/local/Cellar/solr/4.7.0/libexec/example/example-schemaless/solr/

マルチコアのサンプルなら

1
$solr /usr/local/Cellar/solr/4.7.0/libexec/example/multicore/

正しく動いていれば、「http://localhost:8983/solr/」で管理画面にアクセスできます

自分でスキーマや設定を作成したい場合、このあたりの設定をコピー&修正して同様の手順で実行してやれば良さそうですね

Homebrewでバージョンを指定してパッケージをインストールする

はじめに


某モバイルアプリでですね、要求しているビルド用のパッケージが
今、インストールされているものよりも古いバージョンでした。

そのままだと、ビルド出来ないのでバージョンを古くしようとしたのがキッカケです。。。

# 某モバイルアプリはAndroidで、ビルドパッケージはGradleなんですけどw

インストール(される|した)バージョンを確認


バージョンを確認します。

1
$brew info gradle

するとこんな感じで結果が出ます

1
2
3
4
5
gradle: stable 1.10
http://www.gradle.org/
/usr/local/Cellar/gradle/1.10 (143 files, 42M) *
  Built from source
From: https://github.com/Homebrew/homebrew/commits/master/Library/Formula/gradle.rb

インストール可能なバージョンを調べる


古いバージョンと言いつつも、バージョンがあるかどうかも調べないといけません。
という訳で、バージョンを調べます。

1
$brew versions gradle

すると、こんな感じでズラズラとバージョンと対応するgitのハッシュ値が出てきます。

1
2
3
4
5
6
  https://github.com/Homebrew/homebrew-versions
1.10     git checkout 2b10422 Library/Formula/gradle.rb
1.9      git checkout 5bab5e9 Library/Formula/gradle.rb
1.8      git checkout 9214e60 Library/Formula/gradle.rb
1.7      git checkout f826cc9 Library/Formula/gradle.rb
...

これで、一つ前のバージョンがあることが分かりますね。
このタイミングでパッケージは削除しましょう。

1
$brew remove gradle

古いバージョンをインストールするよ


ハッシュ値がわかったので、そのFormulaだけ前のバージョンに戻せばいいわけです。
戻した後にインストールすれば、古いバージョンのパッケージがインストールできるという・・・

1
2
$ cd /usr/local/Library/Formula
$ git checkout 5bab5e9 gradle.rb

バージョンを確認してからのインストール

1
2
3
4
5
6
7
$brew info gradle
gradle: stable 1.9, devel 1.10-rc-1
http://www.gradle.org/
Not installed
From: https://github.com/Homebrew/homebrew/commits/master/Library/Formula/gradle.rb

$brew install gradle

と、簡単にできましたとさ