Web API The Good Parts 1~2章の自分的まとめ

自分は本を読むのが遅いほうだが、最近は読んだ後に自分の中にあまり内容が残らないことが多くなってきた。。。
なので、これからは読んだ本があれば、随時自分の中でまとめたことをアウトプットとしてまとめていきたい。

今回、読んでいる本はこちら!

Web API: The Good Parts

Web API: The Good Parts

1. Web API とは何か

1.1 WEB API の重要性

まあつまりAPIを開発していたら公開したほうがよいということ。
利用者がサービスに付加価値を与えてくれ、コアとなるサービスがより発展するから。

ほんとにその通り。
ただここでは触れていないが、公開するならセキュリティとか気になるところ…
6章で紹介されるので一旦、おあずけw

1.3 何をAPI で公開すべきか

サービスのコアの価値のある部分をすべて利用可能なように公開すべき。
そこに価値があるため。

公開したAPIの運用の方法はいくつかある。
多くはレートリミット、つまりアクセス数の制限を設けている。
それ以上のアクセスがあれば有料とするなどの運用もあり。
レートリミットについても6章で紹介されるので一旦、おあずけw

API を公開することで、優先順位をさげていた機能や全く思いつきもしなかった新しい機能を誰かが作ってくれるかもしれないという効果がある。
このように、(直接サービスを使うのではなく、)API を提供し、それを複数組み合わせたアプリケーションがユーザにサービスを行う”間接販売”モデルになっていく。

1.4 Web API を美しく設計する重要性

設計の美しいWeb API

  • 使いやすい
  • 変更しやすい
  • 頑強である
  • 恥ずかしくない

当たり前だけど超重要!
この章はしっかり読んだ置いたほうがよい!

1.5 Web API を美しくするには

そのためには

デファクトスタンダードを決める際に参考になるサイトはProgrammableWeb。

http://www.programmableweb.com/

(世界中のAPI が集められているサイト。
なんかアプリ作ろうとしたらここからAPI を選定するといいかも)

1.7 対象となる開発者の数とAPI の設計思想

  • LSUDs(large set of unkown developers)
    対象が不特定多数のため、さまざまなユースケースを想定して汎用的にすべき。
  • SSKDs(small set of kown developers)
    特定の開発者にとって便利で使いやすくすべき。

2.エンドポイントの設計とリクエストの形式

2.2 API エンドポイントの考え方

覚えやすく、どんな機能をもつURI なのかが一目でわかるのがよい。
そのためには

  • 短く入力しやすいURI
  • 人間が読んで理解できるURI
    • むやみに省略しない
    • 正しい英語を使う
  • 大文字小文字が混在していないURI
  • 改造しやすいURI
  • サーバ側のアーキテクチャが反映されていないURI
  • ルールが統一されたURI

自分の情報のエイリアス

idではなく、me, self を使う。

2.3 HTTP メソッドとエンドポイント

正しくHTTPメソッドを使いましょう!

メソッド 用途
GET 情報の取得
POST 情報の登録
PUT 情報の(全体)更新
DELETE 削除
PATCH 情報の一部更新

get,postメソッドしか使えない環境のために、X-Http-Method-Override を使えるようにしておくべき。

2.4 API のエンドポイント設計

リソースをURIにする。

ex.ユーザ情報

 https://api.example.com/v1/users
 https://api.example.com/v1/users/:id

それ以外の注意点。

  • 複数形の名詞を利用する
  • 利用する単語に気をつける
  • スペースやエンコードを必要とする文字を使わない
  • 単語をつなげる必要がある場合はハイフンを利用する

2.5 検索とクエリパラメータの設計

クエリパラメータで絞込みをする。

 https://api.example.com/v1/users?name=ken

クエリパラメータとパスの使い分けは以下の2観点。

  • 一意なリソースを表すのに必要な情報かどうか
  • 省略可能かどうか

ページネーションはper_page/page or limit/offsetのいずれかを推奨。
page は1始まり、offsetは0始まり。

2.6 ログインとOAuth2.0

OAuth は認可を行う。
例えばFacebook の情報を自サービスで使う場合、以下の図のようにトークンのやり取りを行い、認可をもらう。
重要なのはconsumers(ここでは自サービス)ではログイン情報(ID,パスワード)は持たず、
ユーザはservice Providers(ここではFacebook)にログインするだけでよく、
その際にconsumers にどのような権限を与えるか制御できる。

f:id:AHA_oretama:20160627013911j:plain

自サービスでログインを行う場合、OAuth2.0 のGrant Type=Resource Owner Password Credentials で実装する。

参考

Grant Type 用途
Authorization Code サーバサイドで多くの処理を行うウェブアプリケーション向け
Implicit クライアントサイドで多くの処理を行うアプリケーション向け
Resource Owner Password Credentials consumers を利用しないアプリケーション向け
Client Credentials ユーザ単位での認可を行わないアプリケーション向け

ここら辺は実際に実装してみないとよくわからない。

2.9 HATEOAS とREST LEVEL3 API

HATEOAS
hypermedia as the engine of application state
API の返すデータの中に、次に行う行動、取得するデータなどのURI をリンクとして含めること。

REST LEVEL3 API
HATEOAS の概念の導入。
LEVEL0~2はそれぞれHTTP、リソース、メソッドの導入。

Spring でもプロジェクトがあるので、使ってみるといいかもしれない。
http://projects.spring.io/spring-hateoas/

ここまでの所感

API 設計の基礎の基礎となる部分であり、
今まで使っていたAPI がここで学んだAPI の基本設計を自然と取り入れられていたことに気づいた。

今まで自然と使っていたが、気づいていなかったことが多かったので非常に勉強になった。
そういう意味だけでもAPI 開発者としては読んでおくべき本かな、と思った。

また仕事で作っているAPI もこの基本設計は守っていつつ、
足りない部分もあったので反映していきたい。

シェルスクリプトの本を読んでシェルを書いてみた

シェルスクリプト 基本リファレンス」の本について

今回、読んでみた本は以下の「シェルスクリプト 基本リファレンス」だ。

[改訂新版] シェルスクリプト基本リファレンス  ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)

[改訂新版] シェルスクリプト基本リファレンス  ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)

総評

まず対象としてる読者はLinux で基本的なコマンド(ls, cp, mv など)を使うことができる人となっているが、 一から説明してるので初心者でも大丈夫だ。

内容としてはBシェル系、Cシェル系の違いや「#!/bin/sh」の説明など基本的なことから、 シェルの文法、シェルのコマンドなど基礎的な事柄をしっかり説明している。 ノウハウなど一部、実践的なことも書いてある。

総評としてはシェルを書き慣れていない人にはオススメの一冊である! 是非とも読んでみてほしい。

シェルスクリプト解説

#!/bin/sh, #!/bin/bash の意味

正直、シェルスクリプトの一行目に「#!/bin/sh」を書くのは慣例だと思っていた。 が、違った!ちゃんと意味があった。

単純に言えばシェルスクリプトに何を使うか、だ。

  #!/bin/sh

と書くと、Bourne Shell が使われる。 「#!/bin/bash」ならBourne-Again shell だ。bash のほうがsh より高機能。

では、ターミナルを開いたときにどのシェルと使ってるかは以下のコマンドで調べられる。

  echo $SHELL

パラメータ展開

パラメータは$をつけることで表される。 主なところはこんな感じだ。

書き方 説明
"{$HOME}" 変数の値を参照
"$1","$2",.. シェルスクリプト、シェル関数の引数を参照
$0 シェルスクリプト名を参照
"$@" シェルクリプト、シェル関数の引数全てを参照
$# シェルスクリプトの引数の個数
$? 直前のコマンドの終了ステータスを参照

ついでにダブルクォートで囲んでいるのは パラメータ展開をしたあとの文字列をパラメータ展開などを行わずに 文字列として展開することを示している。

例えば

  file=*
  echo $file
  # 現在のディレクトリの全ファイル、フォルダが表示
  echo "$file"
  # * が表示

のように、ダブルクォートで参照した文字列を再度、展開することを避けてくれる。

$#,$?などは数字の文字列が返ってきて、パラメータ展開などされる心配がないので、 ダブルクォートで囲んでいない。

シングルクォート、ダブルクォート、バックスラッシュ、バッククォートの違い

正直これはこの本を読むまで全く分からなかった。 これが分かっただけでもこの本を読む価値がある。

ここでは簡単なまとめを表にする。

パラメータ展開 コマンド置換 説明
シングルクォート × × 文字通りの意味として解釈される
ダブルクォート ○(``で囲む) $,`,\ の特殊文字が解釈される
バックスラッシュ - - 次の文字が特殊な意味を失う
バッククォート × 囲まれた部分がコマンドとして実行される
  echo '$HOME'
  # $HOME
  echo "$HOME"
  # /home/aha_oretama
  echo \$0
  # $0
  echo `expr 1 + 1`
  # 2

役立つテンプレート

他の人のシェルを見てると使い方、初期チェックなど お決まりの定型句があるように見えるが、 その定型句が人によってバラバラだったので全然覚えられなかった。

ここでは自分が一番良いと思った定型句を書く。

#!/bin/sh ← 何のシェルスクリプトを使うかを指定

# 使い方を指定
usage () {

cat <<EOT
Usage:
  "$0" [-o outputPath] targetFile
Description:
  Unzip file.
  File extension includes .tar .tar.gz .tar.Z .tar.bz2 .zip 
Options:
  -o  output-directory
EOT
## ヒアドキュメントで記載
## <<HOGEで始まり、次にHOGEが出るまでヒアドキュメントとなる

exit 1
}

# オプションの設定
# o: のようにコロンはオプションに引数があることを示す
while getopts ho: option
do 
  case $option in
    o)
      OUTPUT_PATH="$OPTARG"
      ;;
    h)
      usage
      ;;
    \?)
      usage
      ;;
  esac
done

# オプションを除く
shift `expr "$OPTIND" - 1`

# オプション以外の引数を確認
if [ $# -lt 1 ]; then
  usage
fi

最後に

この本はシェルスクリプトを学びたい人にとっては 基礎を固める最良の本となる。

この本を読んで作った簡単なUtil シェルを GitHub にあげたのでぜひ参考にしてほしい。

github.com

Oracle XE processes、SPFILE の設定

Oracleでは、けっこうprocesses数が問題になることが多いので、ここでやり方をまとめておきたい。

環境

  • Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

processes

ここではprocessesの変更を行うため、以下の権限を持ったユーザで実行する。

  • ALTER SYSTEM

確認

select * from  v$parameter where name = 'processes';

設定

ALTER SYSTEM SET PROCESSES=150 SCOPE=SPFILE; 



SCOPE 説明
MEMORY インスタンスのメモリ上に変更を加えるだけで再起動時には設定は破棄され前の状態に戻る。
PFILE サーバー・パラメータ・ファイル (SPFILE) に変更を加えるだけで現インスタンスには反映されない。再起動後に有効となる。
BOTH 現行インスタンス、および、サーバー・パラメータ・ファイル (SPFILE) に変更を加える。再起動時にも有効となる。




SPFILE の設定

案の定、上記を実行したときにエラーが発生した。
SPFILE でOracle XE を起動していなかったのだ…

ここではSPFILE の作成、設定も追記する。

SPFILEの作成のためにSYSDBA,SYSOPER のどちらかの権限のユーザで実行する。

SPFILE 確認

select * from  v$parameter where name = 'spfile';

Value に値があればSPFILE で起動している。逆にnull であればPFILE で起動していることになる。

SPFILE 作成

CREATE SPFILE [= filePath] FROM PFILE [= filePath];

もし必要であればfilePath を指定することで、SPFILE の格納場所、PFILE の参照先を指定できる。

Groovy on Grails をインストールして使ってみた

会社でGroovyを使っているので、勉強していたらGrailsというものがあり、
GrailsならWebアプリケーションを簡単に作れるっぽいのでインストールしてみた。

環境

インストール

Grails

Grailsは以下からインストールできる。
The Grails Framework

Posh-GVM (POwerSHell Groovy enVironment Manager) というGroovy の環境ツールがあるので、
せっかくなのでPosh-GVM を使ってインストールしてみた。

まずはPosh-GVM のインストール。
管理者権限のPowerShell で以下を実行。

  1. (new-object Net.WebClient).DownloadString('https://raw.githubusercontent.com/flofreud/posh-gvm/master/GetPoshGvm.ps1') | iex
  2. Import-Module posh-gvm
  3. gvm help

以下の画面が表示されればPosh-GVM のインストールは完了。
f:id:AHA_oretama:20151224195204j:plain

途中、PowerShell の実行ポリシーに引っかかった場合、以下をPowerShell 上で実行すれば解決した。

Set-ExecutionPolicy RemoteSigned


それではPosh-GVM を使用してGrails をインストールしてみよう。
といっても、以下コマンドをPowerShell で実行するだけだ。

gvm install grails

GGTS

Groovy/Grails Tool Suite というEclipse のGroovy/Grails 版があるのでインストールしてみた。
といっても、以下からダウンロードしてインストールするだけだ。
Groovy/Grails Tool Suite™ (GGTS)

インストールが終わってGGTS を開いてみるとなにかあやしい予感が…
おそるおそる「Preferences」→「Groovy」→「Grails」を見てみると…

f:id:AHA_oretama:20151224210304j:plain

GGTS に含まれてるやないか!!Grails !!
せっかくインストールしたのに…!!

しかもバージョンが違ってる…
しょうがないのでPosh-GVM を使用してGrails をバージョンして入れ直し。

gvm install grails 2.4.4

Grails コマンドを使用して「Hello,World!」

せっかく入れたGrails だけをつかって「Hello,World!」アプリケーションを作る。
PowerShell で以下のコマンドを順に実行する。

  1. grails create-app HelloWorld
  2. cd .\HelloWorld
  3. grails create-controller HelloWorld
  4. エディタで .\grails-app\controllers\helloworld\HelloWorldController.groovy を開き、編集する
package helloworld

class HelloWorldController {

    def index() {
        render "Hello,World!"
    }
}

  5. grails run-app

うん、なんか大丈夫そうだな。
アプリケーションが起動したというメッセージが出た。
f:id:AHA_oretama:20151224225808j:plain

GGTS を使用して「Hello,World!」

先ほど作ったプロジェクトを「Grails Project」としてインポートし、
あとはRUNするだけでOK!

これでうまくいくと思ったらエラーがバンバン出た…エラーが止まらない!

java.lang.reflect.InvocationTargetException
	at sun.reflect.GeneratedMethodAccessor58.invoke(Unknown Source)
…
Caused by: java.lang.IllegalArgumentException: Can not copy a non-root Method
	at java.lang.reflect.Method.copy(Method.java:151)
	... 390 more

さっそく調べてみると、ここに書いてあった。
Incompatible JVM in GGTS (Eclipse) and JAVA 1.8 - Stack Overflow

JDKのバージョンが対応していないとのこと。
JDK:1.8.0_60 をインストールして実行してみると成功した。

f:id:AHA_oretama:20151224225123j:plain

まとめ

Groovy on Grails の良さまでは今日はたどり着けなかった。
ただGrails の環境はこれでできたので、次からはGrails をいろいろ触ってみたい。

Java8から追加されたラムダ式についてまとめてみた。

Java8から追加されたラムダ式に触れる機会が増えてきたので、ここらへんで自分の知識をまとめておきたいと思う。

まずラムダ式とはなにか。関数型インターフェース(1つのインターフェースに実装が必要なメソッドを1つだけ持つインターフェース)に対して、以下のような形式で記述する文法である。

(引数) -> {処理};


では、実際にどのようになるか見てみよう。まずはjava.util.function.Functionインタフェースに対して、ラムダ式を使わずに匿名クラスで記述した場合。

	public void testMethod() {
		Function<Integer, Double> function = new Function<Integer, Double>() {
			@Override
			public Double apply(Integer t) {
				return (double) t / 2;
			}
		};
		System.out.println(function.apply(1));
	}


では、上記をラムダ式で記述するとどのようになるか。

	public void testMethod() {
		Function<Integer, Double> function = (Integer t) -> {
			return (double) t / 2;
		};
		System.out.println(function.apply(1));
	}

慣れないと分かりにくいが、匿名クラスの作成やメソッド部分が省略され、ずいぶん記述量が減った。


ここから若干、駆け足で説明したいと思おう。まずは引数の型は定義されているため、記述を省略できる。(ここではジェネリックス型なので左辺で定義されている。ジェネリックス型以外であればインタフェースに定義済みである。)

	public void testMethod() {
		Function<Integer, Double> function = (t) -> {
			return (double) t / 2;
		};
		System.out.println(function.apply(1));
	}


さらに引数が一つであれば括弧()が省略できる。

	public void testMethod() {
		Function<Integer, Double> function = t -> {
			return (double) t / 2;
		};
		System.out.println(function.apply(1));
	}


また戻り値が一つであれば return を省略できる。

	public void testMethod() {
		Function<Integer, Double> function = t -> (double) t / 2;
		System.out.println(function.apply(1));
	}

最初の匿名クラスの場合と比較してみてほしい。たった一行でインターフェースの実装が完了してしまった!!

これがラムダ式の力である。


もちろん慣れるまで意味を把握しにくいかもしれないが、この記述量の削減には素晴らしいものがある!
それにJava8から追加された「Stream API」ではラムダ式が多用されるため、
ぜひとも早く慣れて使いこなせるようになっておいたほうがいい。


最後にいくつか補足を付け加える。

まずは引数がない場合、どのようになるか。答えは ()-> {処理}; となる。
ここではjava.util.function.Supplierについて例を記載する。

	public void testMethod_Supplier() {
		Supplier<String> supplier = () -> "supplier";
                // supplierと表示。
		System.out.println(supplier.get());
	}

またメソッド参照ができるので、このような記載も可能。
ここではjava.util.function.Consumerについて例を記載する。

	public void testMethod() {
		Consumer<String> consumer = System.out::println;
                // consumerと表示。
		consumer.accept("consumer");
	}

Windows10にアップグレードしてみた② ~アプリ削除~

引き続きWindows10にアップグレードした後に気づいた便利な点、不便な点について触れたいと思う。2回目は不要なアプリの削除についてである。

 

■不便①

Windows10にアップグレードするとすぐに入れた覚えのないアプリがインストールされていることに気づく。WindowsのPCを買ったときと同じで、いらないアプリを削除するというお決まりの作業が発生するのである。ここら辺はMicrosoftさんに改善してほしい点だ。

基本はメニュー画面で右クリックからアンインストールができるが、いくつか削除できないアプリがあることに気づく。例えば「3D Builer」や「People」、「モバイルコンパニオン」などだ。

そのようなアプリを削除する場合はひと手間必要である。Windows PowerShellを管理者権限で開き、Window8から搭載された「Remove-AppxPackage」コマンドで削除する必要があるのだ。

それでは具体的な使い方だ。ここでは例として「People」を削除してみよう。

まずは対象アプリの具体的な名称の特定だ。Windows PowerShellに「Get-AppxPackage *people*」と入力してみよう。アプリの詳細情報が表示される。

f:id:AHA_oretama:20151011113503j:plain

対象のアプリが分かったなら「Remove-AppxPackage 'PackageFullName'」コマンドだ。

f:id:AHA_oretama:20151011114429j:plain

これで不要アプリを削除できる。削除したアプリを復活させたい場合はWindowsストアから再度インストールすることで復活できる。

このようにひと手間加えなければアプリを削除できないのはMicrosoftさんに改善してほしいところである。

ついでにこれでも削除できないアプリ(「Edge」など)があるが、それについては今のところ削除する方法が分かっていないので、 知っている人がいれば教えてほしい。

Windows10にアップグレードしてみた① ~仮想デスクトップ~

初めての記事はWindows10へアップグレードした後に気づいた便利な点、不便な点をまとめてみたいと思う。

 

■便利①

まずは何と言っても仮想デスクトップであろう。この機能がWindowsにできたとMacユーザの同僚に話した時に「Macだとだいぶ前から標準搭載してますけど、やっとできたんですねw」と鼻で笑わられた…orz

仮想デスクトップはあたかもデスクトップが複数あるかのように振る舞う機能で、別々の作業をするときに便利な機能だ。基本的にショートカットキーしか使わないので、ショートカットキーの紹介だ。

まずは仮想デスクトップと起動アプリの一覧表示、Win + Tabだ。

 

f:id:AHA_oretama:20151010222644j:plain

選択は方向キーで移動可能。Tabで仮想デスクトップ、アプリの選択を切り替えられる。

仮想デスクトップ間の移動はWin + Ctrl +方向キーだ。よく使う機能なので、覚えておいて損はない。

あと仮想デスクトップの追加はWin + Ctrl + D。仮想デスクトップの削除はWin + Ctrl + F4。

仮想デスクトップの機能は基本Win + Ctrlでできるので、Windows10ではこのキーたちを押しておけば間違いない。

ついでに何もアプリが起動していない仮想デスクトップでWinボタンを押してメニューを表示し、WinボタンまたはEscボタンを押してメニュー表示を閉じたときに、アプリが起動している仮想デスクトップに強制的に戻されるのはWindowsのバグだと思うが、仕様だと言い張るだろうw

・ショートカットキーまとめ
  • 仮想デスクトップの一覧表示 Win + Tab
  • 仮想デスクトップ間の移動 Win + Ctrl +方向キー
  • 仮想デスクトップの追加 Win + Ctrl + D
  • Win + Ctrl + F4