Goalist Developers Blog

【求人情報ビッグデータ】HR EXPO 2018出展しています

こんにちは、開発部の飯尾です。
昨日7月11日水曜日、タイトル通りHR EXPOに参加してきました!

www.hr-expo.jp

企業の人事担当者さま向けに、サービス紹介・商談を行うイベントです。
ゴーリストもHR Tech領域で自社サービスを紹介してきました。

日本中の求人情報ビッグデータから、採用を読み解くHRogシリーズ

f:id:y-iio:20180712120616p:plain

https://chart.hrog.net/chart.hrog.net

map.hrog.net

ブースの様子
自社メディアのキャラクター「ふろぐん」カラーのTシャツで目立つ…

f:id:y-iio:20180712113445j:plain

私は現在、HRogチャートHRogマップの開発・運用を担当しています。
ときおり既存ユーザーの営業訪問に同行することはありますが
ど新規の営業イベントに参加するのは初です!

あんまり力になれてるわけでは無いですが

  • 呼び込みスクリプトの考案
  • とりあえず声出して足を止めてもらう

などなど、自分にもできることをがんばりました〜
普段営業メンバーがさらっとサービス紹介していることのすごさを実感ですね。

とはいえ「アルバイト採用担当されてるんですか?私が作ったサービスでこういうのあるんです!よかったらデモ触っていきませんか!」の最高の流れが実現できたので
個人的には満足です、ガハハ


このHR EXPOは明日13日金曜日まで開催中です。
ぜひゴーリストブースへ遊びに来てください!
\カワイラシイふろぐんうちわも配ってます/

こういうお祭り的なイベントもオモチロイものですね。
窓の外に出ると己の姿もよく見えると思います。

技術ブログとはいえ、採用のためにやってるものなので
社内エンジニアがどんな仕事してるかとか会社の雰囲気もこんなかんじで紹介していきます💪('ω'💪)

Gitがやばい!(1/3)

最近初めての開発者が多いプロジェクトに参加しました、そのためgitの強さがよ〜くわかりました(やらかしながらね)。シンプルから複雑な動き:つまり、「自分一人でバージョ二ングだけのために使ってる」場合(シンプル)から「ヤベー、いろんな人がいるし、ギットからデプロイされてるし、何が起きてる?!」(複雑)な状況に便利なものを軽く通しておくと便利かなと思いました。(以外と長かったため、この記事には基本:Level 0 とLevel 1を書いて見ました)

https://assets-cdn.github.com/images/modules/open_graph/github-mark.png

Level 0: init, .gitignore, status, remote

まずは環境設定みたいなものですね。プロジェクトフォルダーに git initを書きますとそのフォルダーがレポジトリとして初めて使えるようになります。 最初の状態で何も「トラッキング」されてないです。

status

git statusは現在の状況を確認するためのコマンドです。 git status を打ちますと、そのフォルダーの内容が全部出て、”untracked files”としての一覧になってます。 f:id:c-pattamada:20180705160140p:plain

.gitignore

このファイルの中に、gitを無視して欲しいファイル・パスなどを書きます。特に、プロジェクのlibフォルダーのような、外部ライブラリーのファイルを普通はのぞいて欲しいために、そういうパスを入力すれば良いです。 また、個人エディタ用のフォルダー(.ideaなど)も含めた方がいいかと思います。 この場合は ‘fileToIgnore.txt’を無視しましょう、ご覧の通り、lsには見えますがgitの方がむししているのです。

f:id:c-pattamada:20180705160159p:plain

入力後、またgit statusを打つと、ちゃんと無視してると確認できます。

f:id:c-pattamada:20180705160213p:plain

remote

Gitが複数の人たちが同じプロジェクトに開発できるために作られてますのでオンライン上にも置かれてるケースが多いです。ローカルのgit repositoryをオンラインに繋ぐのに githubでrepositoryを作る必要があります。 これを行うために、githubでのrepositoryも存在する必要があります。以下の記事のstep 2の画像を参考にしてください)

Deploying an Angular app to GitHub Pages - Goalist Developers Blog

Repository のurl をコピーして、
git remote add origin <url>
のようにローカルのgitのremoteを設定できます(originがそのサーバーの名前になりますが、他の名前でも大丈夫です)。

Level 1: Add, Commit, push, checkout, reset/revert.

残りのファイルを「トラッキング」したいと思いますので一旦プロジェクトフォルダから git add . を打ちましょう、そして、git statusで…. 緑! (ファイル一個ずつもadd できます。git add <ファイル名>)

f:id:c-pattamada:20180705160239p:plain

現在の緑のファイルをcommit する準備が整ってる。

と言っても… commitとは?

Commitはギットの基本技です。「add」されたファイルの状況を保存するようなことです。まさにゲームでボスの前に保存してから、ボスを倒した後でまた保存するように使うイメージです。何かがうまく行かなかった場合に、ボスの前のコミットに戻せます。

Commitするとどういう情報が保存されてるでしょう? それは以前のコミットと比べて、変更したファイル(何行目を変更したなど)の情報です。後に現れる「Merge」でこれが重要となります

Commitするために: git commit -m "コミットについての一言" を使えば便利だと思います -m は 「メッセージ」(コミットについての一言)を追加するためにあります。

Commitがそれぞれユニークなhashをもつ、これによってギットがコミットを管理します(英語ですが、How is git commit sha1 formed · GitHub で、そのハッシュがどうやって作られてるのかを調べた人もいました)

では、git log でコミット歴史を見ましょう

f:id:c-pattamada:20180705160518p:plain

黄色文字列が今回のコミットハッシュです。あとでハッシュを使うものも見ましょう! (ボーナス:githubのコミットの管理画面からいかの画像のようなコミットが見れます、そこで右側の青いものをクリックするとhashをコピーできます ^^) f:id:c-pattamada:20180705160748p:plain 

Commitしました!で..?

ローカルのgitを定期的にオンラインにpushしましょう!これで、バックアップとなり、他の人とシェアしたり共同開発ができるようになります! 先ほどのlevel 0で設定したoriginがpush先になります。 では、pushしましょう! git push -u origin masterを打てば、現在使ってるmasterのbranch(後で詳細書きます)がオンラインにも現れます。 -u が最初の時に使った方がいいですが、その後でgit pushでできます。

これでオンライン上のgit repositoryに行きますと、自分のpushの結果が見れます。

あー間違いました!

だいたい二つの状況があるかと思います。

コミットする前に、やっぱりいまの変更が失敗だと判断して、前のセーブに戻りたい

つまり、ボスに倒されて、直前のセーブの状態にresetをしたい。 まだコミットしてない状態なら、 git checkout <ファイル名> を使って、ローカルの変更を捨てられます。 注意:捨てられた変更は失われます。

一つのファイルではなく、全ファイルの場合に git checkout .が使えます。(両方ともremoteが設定されてる前提です。)

コミットをした後で後悔中です!

こういうのもよくあるかと思います。間違ったファイルをcommitしたり、アップしたら他の人が作ってる部分がなぜか壊れたりするケースもあるかと思います。ボスに負けたのに、間違って保存しちゃった気分って最悪ですが、gitの場合には問題ありません。

手段1: git reset そのままに使うと、「add」されたファイルが全てaddされてない状態になるのですが、ローカルの内容を全て捨てたい場合もあります(他の人とかぶりがありました!など)。

git reset --hard origin/<branch_name> [(branch_name_)を確認するために git branch を書いて、*がついてるのが現在のブランチ] 
注意:このやり方でローカルのものが無くなります。 十分注意してください。

手段2: もし、すでにプッシュされた、昔のものであれば、git revert <commit hash> で昔にあったコミットを戻すような新しいコミットを作成します。このやり方では何も無くなりませんが、実装がちょっとめんどいです。 例えば、今回のコミットをrevertしたい場合には git revert 0e7cfc6b8cac249f8fd2445c86660d6805045b9d を書きますと....

f:id:c-pattamada:20180705161159p:plain

あら...コミットが消えましたね。今回作成したファイルも消えました!

まとめ

今回Gitの基本コマンドについて書きました。init, status, add, push, commit, resetなどを使って見てください! 以外と説明が長くなってしまいました。そのため、全部一つに記事に打っ込むよりみつに分けることにしました!続きも楽しみにしてください!今度はLevel 2: branch, merge, fetch, pullなどについて書きますね!

IaC by Terraform ~DAY5: Terraform Commands (4)~

どうも,エンジニアのナカノです.

今月は梅雨の時期でしたね。洗濯物を外に干せないことが多く、悶々としておりました.

天気予報を見ると今週から天気が良いみたいなので、少しホッとしております.

さて,今回も前回の記事の内容の続きとなります.

前回はterraform.tfstateの管理/運用コマンド (1)に関する内容でした.

今回の内容は,terraform.tfstateの管理/運用コマンド (2)に関してです.

目 次
  • `terraform.tfstate`の管理/運用コマンド (2)
    • taint
    • untaint
    • refresh
    • workspace
      • list
      • select
      • new
      • delete
  • 最後に

terraform.tfstateの管理コマンド (2)

taint

Terraformを使っていると,applyの実行でエラーが出てしまって適当なリソースが想定とは異なる形で作成されることがしばしばあります.

そういった時は,まずはエラー箇所を修正し,次にそのリソースを作り直して想定通りの状態でデプロイしたい欲求に駆られるでしょう.

taintというコマンドはその様な時に役に立ちます.例えば,訳あって作成済みのリソースxxxxxxxxを作り直したいとします.

そのためにterraform taint xxxxxxxxを実行すると,terraform.tfstateに記載されているxxxxxxxxの項目taintedの値がfalseからtrueに変わります。

taintedの値がtrueになると,xxxxxxxxはまずTerraformによって削除され,次にxxxxxxxxが再作成されます.

こういった状況ではゴリ押しでapplyを実行しまくるのも一つの手ですが,taintコマンドを上手く使う方が得策かもしれません.

www.terraform.io

  

untaint

untaintコマンドは,文字から分かる様に,taintとは反対の挙動を起こすコマンドです.

まずはtaintの挙動を思い起してみましょう.このコマンド実行すれば,指定されたリソースがtaintedな状態になります.

一方,untaintを実行すると,指定されたリソースがuntaintedな状態であるとしてterraform.tfstateに記録されます.

taintedなリソースはTerraformにより再作成されるのですから,untaintedなリソースはそのままの状態で保持されます.

このことをterraform.tfstateの観点で言えば,taintはtaintedの値をtrueに変えるがuntaintはtaintedの値をfalseに変えます.

www.terraform.io

  

refresh

一般に,Terraformで管理されているリソースの情報はterraform.tfstateで管理されています.

しかし,Terraform以外の手段によってTerraformの管轄対象のリソースが更新された場合,`terraform.tfstate‘の内容は古いものとなります.

この様な状況では,applyの実行の際に思わぬ挙動が起きて痛い目を合うことがあります.そういう時こそrefreshコマンドの出番です.

このコマンドは,Terraformが管轄するリソースに合わせてterraform.tfstateの内容を更新してくれます.

例えば,何らかの問題が起こって,管理コンソールでTerraformに管理されているリソースの更新を行うことがあります.

そんな時にrefreshコマンドを実行すると,実態のリソースたちとterraform.tfstateの間に差分が生まれない様にすることが出来ます.

このコマンドは,問題が起きた時に威力を発揮することが多いので,覚えておくべきものかと思います.

www.terraform.io

  

workspace

workspaceを使うと,terraform.tfstateの切り替えを実現することが出来ます.このことをもう少し具体的に説明します.

初めはdefaultというworkspaceしかないのですが,新しく作成してworkspace1workspace2というworkspaceを作ったとします.

そして,workspace1workspace2の各々でリソースを作成すると,各々のworkspaceに応じた‘terraform.tfstate`が生成されます.

これらのファイルは,ローカルでは

  • ./terraform.tfstate.d/workspace1/terraform.tfstate
  • ./terraform.tfstate.d/workspace2/terraform.tfstate

の様に配置されます.一方で,バックエンド設定をしている場合でも殆ど同様な感じで各々のterraform.tfstateが格納されます.

この時,workspace毎のterraform.tfstateは互いに独立しており,リソース作成の状態の上書きは起こりません.

よって,このコマンドを使えば,リソース作成の状態を適切に管理/運用することが出来る様になります.

しかし,.tfファイルの内容はworkspaceでは切り替わらないため,現状では共通の設定をステージ毎に管理する場合に役立つという感じでしょうか.

さて,以下はworkspaceのサブコマンドlistselectnewdeleteの説明となります.

  

list

このサブコマンドは,存在する全てのworkspaceをリストします.また,現在のworkspaceには*が付いています.

例えば,存在するworkspaceがdefalutworkspace1workspace2であり,現在のworkspaceがworkspace1であるならば,listの実行結果は下記の様になります.

$ terraform workspace list
  default
* workspace1
  workspace2

www.terraform.io

  

select

現在のworkspaceから別のworkspaceに切り替えたい時に,このサブコマンドを使用します.

例えば,存在するworkspaceがdefalutworkspace1workspace2であり,現在のworkspaceがworkspace1であるとします.

この時に,現在のworkspaceからworkspace2に切り替えたい時は,以下の様に実行します.

$ terraform workspace select workspace2
Switched to workspace "workspace2".

www.terraform.io

  

new

これを実行すると,新しいworkspaceを作成することが出来ます.例えば,new_workspaceというworkspaceを作成する場合は下記を実行します.

$ terraform workspace new new_workspace
Created and switched to workspace "new_workspace"!

You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.

www.terraform.io

  

delete

workspaceを削除する場合は,このサブコマンドを利用します.ただし,以下の点に注意する必要があります.

  • 削除対象のworkspaceがそもそも存在する
  • 削除対象のworkspaceに対応するterraform.tfstateの内容が空である
  • 削除対象のworkspaceは現在のworkspaceではない

これらの点を守った上で,例えばworkspace_to_deleteを削除したい場合は以下を実行します.

$ terraform workspace delete workspace_to_delete
Deleted workspace "workspace_to_delete".

もしterraform.tfstrateの内容が空ではない場合にworkspace_to_deleteを削除したいならば,-forceオプションを使えばよいです.

ただし,このオプション付きでdeleteを実行すると,workspace_to_deleteの場合でTerraformにより作成されたリソースはTerraformの管理外となってしまいます.

www.terraform.io

  

最後に

今回はterraform.tfstateの管理/運用コマンド (2)を紹介させて頂きました.

前回と同様で,使い所を適切に考えれば割と役に立つコマンドばかりです.

直近はTerraformコマンドを紹介してきましたが,コマンドの紹介は今回で終わりです.

次回からは,また別のトピックを扱おうかと思います.

それでは,今回はこの辺りで筆を置かせて頂きます.

次回に乞うご期待下さい.

Deploying an Angular app to GitHub Pages

Being a programmer I can't stop myself greeting you with Hello World so

f:id:vivek081166:20180620155225p:plain

Do you want to tell the world about all the great things you are building?
Well, GitHub Pages might help you to do that.

In this blog, I would like to share the process of bringing your Angular app from local to the internet

http://localhost:4200 ==> https://<username>.github.io/<repository-name>

Let's walk through the following steps to deploy our test-app on GitHub Pages

f:id:vivek081166:20180620142950p:plain

So let's get started...

Step 1 : Build your Angular app

With Angular CLI, using the following command; build your Angular app

ng build

After building your app all we need is the contents of the dist folder

f:id:vivek081166:20180620130056p:plain

Step 2 : Create a repository

For the purpose of demoing your app, it is good idea to have a separate repository.
So, let's create one for our test-app and name it as test-app-demo

f:id:vivek081166:20180620143918p:plain

Step 3 : Initialize repository for file upload

The simplest way to initialize files upload via GitHub will be to add .gitignore to your repository.

f:id:vivek081166:20180620155443p:plain

and commit your file

f:id:vivek081166:20180620155529p:plain

Step 4 : Upload your build files

Having done the previous step you can now upload the build files via GitHub

Click the Upload Files button on master branch

f:id:vivek081166:20180620155853p:plain

Drag your build files here or simply click choose your files

f:id:vivek081166:20180620155938p:plain

Go to the project source folder and choose dist folder

f:id:vivek081166:20180620160410p:plain

f:id:vivek081166:20180620160656p:plain

Select all the build content and upload

f:id:vivek081166:20180620161209p:plain

Commit your uploaded file to mater-branch

f:id:vivek081166:20180620161629p:plain

Step 5 : Update the base URL

Since we uploaded build files into the separate repository, we need to update the base URL to let angular know about the root directory

Update index.html file

f:id:vivek081166:20180620162455p:plain

Change base tag from
<base href="/">
to the name of the repository
<base href="/test-app-demo/">

f:id:vivek081166:20180620162627p:plain

f:id:vivek081166:20180620162704p:plain

Step 6 : Set up the GitHub Pages

This is the final step and we are almost done!

Navigate to the Settings tab of the repository for setting up a GitHub Page for our Angular app

Settings option is only visible to the owner of the repository

f:id:vivek081166:20180620162851p:plain

scroll down a little and you are almost there...

f:id:vivek081166:20180620163319p:plain

f:id:vivek081166:20180620163456p:plain

Select master-branch as the source of GitHub Pages

f:id:vivek081166:20180620163835p:plain

Save the changes and you are done!!

f:id:vivek081166:20180620163958p:plain

しばらくお待ちください。。。
Wait while GitHub sets up everything for you and holla!! your app is live

f:id:vivek081166:20180620164139p:plain

Your app will be live on the web address shown in the GitHub Pages' section. https://<username>.github.io/<repository-name>
Yes!! we did it.

f:id:vivek081166:20180620164542p:plain

Thank you very much for reading all to the end.

I'll be coming back soon with another such topic. Till then
Happy Learning :)

VPCピアリングして別AWSアカウントのセキュリティグループを使う

こんにちは
Webの開発者だけどインフラも知りたいお年頃のイイオです

やりたいこと

  • とあるEC2たちを別AWSアカウントに移し、そっち側からssh接続したい
  • このEC2たちは生まれては消えるさだめなので、セキュリティグループのソースにIPアドレスとかいちいち設定できない
  • というわけでセキュリティグループのソースに別AWSアカウントのセキュリティグループ指定したい

f:id:y-iio:20180614181210p:plain

手順

いいからVPCピアリングだ!

docs.aws.amazon.com

0. 前提

アカウントA

  • VPC CIDR 10.0.0.0/16
  • サブネット 10.0.10.0/24, 10.0.20.0/24

アカウントB

  • VPC CIDR 172.30.0.0/16
  • サブネット 172.30.10.0/24, 172.30.20.0/2

VPCのCIDRが被っているとピアリングできないよ
最初てきとうにVPC切ってしまってたいへん後悔したよ
このあたりをちゃんとべんきょうしてからやるべきだったよ

dev.classmethod.jp

リージョンも同じじゃないといろんな制限をくらうよ

1. アカウントAでVPCピアリングの申請

VPC > ピアリング接続 > ピアリング接続の作成

f:id:y-iio:20180614182341p:plain

AWSのアカウントIDはアカウント設定画面からみれる

2. アカウントBでVPCピアリングの許可

VPC > ピアリング接続

f:id:y-iio:20180614182806p:plain

f:id:y-iio:20180614182910p:plain

f:id:y-iio:20180614182932p:plain

3. アカウントBでルートテーブルを指定

VPC > ルートテーブル

送信先は相手のVPC全体にもできるし、もっと小さくサブネットとかIP単位にも絞れる、ゴイス〜

f:id:y-iio:20180614183259p:plain

4. アカウントAでルートテーブルを指定

VPC > ルートテーブル

こちらでもルートを追加、これ忘れてて詰まってたことは内緒

f:id:y-iio:20180614183316p:plain

5. アカウントAのセキュリティグループの設定

EC2 > セキュリティグループ

向こうのアカウントのセキュリティグループを入力できるようになっている!

f:id:y-iio:20180614184215p:plain

アカウントBのサーバーから接続確認だ〜〜〜

ssh ec2-user@ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com(パブリックDNS)

沈黙

ssh ec2-user@54.xxx.xxx.xxx(パブリックIP)

繋がらないよ〜〜〜〜

はい

qiita.com

www.skyarch.net

セキュリティグループでセキュリティグループを許可する(セキュリティグループのソースにセキュリティグループ指定する)方法は、プライベートネットワーク内でのみ有効…!!!

VPC Aの中でディグる

dig ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.55.amzn1 <<>> ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37867
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com. IN A

;; ANSWER SECTION:
ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com. 20 IN A 10.0.10.123

VPC Aの外でディグる

dig ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com

; <<>> DiG 9.10.6 <<>> ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8580
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com. IN A

;; ANSWER SECTION:
ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com. 589434 IN A 54.xxx.xxx.xxx

ピアリングしたVPC Bの中でディグる

dig ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.57.amzn1 <<>> ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34546
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com. IN A

;; ANSWER SECTION:
ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com. 60 IN A 54.xxx.xxx.xxx

今まで完全に同じVPC内でしか使ったことなかったから
接続先にパブリックDNSやパブリックIP指定しても、プライペートIPとして解決されていてたけど
VPCピアリングだとその解決できないから、プライペートIPを直指定しないとダメだったんだね、ハム太郎!へけ!

というわけで
アカウントBのサーバーから再度接続確認だ〜〜〜

ssh ec2-user@10.0.10.123

これでよろし〜〜〜なんだか全てにおいて己の知識不足って感じだ!へけ!

Play Frameworkで画像・アセットをユーザーに届ける

Play Frameworkが非常に便利ですので、Apiサーバーとして使ってます。この度、自分のサーバーに持ってる画像などなアセットをそのまま返したい場合(例え、アンギュラーのフロントで表示したいなど)にどうすればいいかを説明します。 それぞれの状況に合わせて、二つの方法を説明します。

とりあえず、…image.jpgに画像を出したい!

つまり、誰でもそのurlにいくとその画像がみれるような場合です。 この方法は割と簡単です。

conf/routesのファイルに

GET     /assets/*file               controllers.Assets.versioned(path="/public/images/", file)

これで、/public/images/のディレクトリーをベースにして、「ファイル」というパス変数に当てはまるファイルをそのまま出せます。

www.example.com/assets/cats/myCat.png/public/images/cats/myCat.pngにあるファイルを出します。(なかったら、404エラーが出ます)

ちなみに、Idea使ってる方々はこのようなdeprecatedという知らせを見ることもあると思いますが、Ideaのバグらしいです。(link: https://github.com/playframework/playframework/issues/7521)

このように、Angularのクライアントで、<img src="www.example.com/assets/cats/myCat.png" />

このイメージのアクセスを制限したいですが…

アクセス制限、何かのトラッキング・編集などのことがやりたい場合もあると思います。その場合は直接routesから返したらできなくなるかと思いますが、別な方法もあります!

では、routesにこう追加しましょう

 GET       /getImage                controllers.HomeController.getImage

getImageの中でバリデーションやアナリティクスなど、でもできます。 欲しいイメージや、アクセス権限の情報がGET変数で送られてるとしますと、FormFactoryとDynamicForm を使って、コントローラーからその変数のアクセスができます。

public class MyController extends Controller {

@Inject
private FormFactory formFactory;

public Result getImage() {
...
}

}

まずは、FormFactoryをInjectionで使えるようになる。そして、getImageの書き方は...

DynamicForm dynamicForm = formFactory.form.bindFromRequest();
// 適切なログインチェックを行う
if(!isLoggedIn(dynamicForm)) {
    // もしユーザーがログインしてない場合には、対応する。
        return ....; //アクセス制限する。
}

まずは、バリデーションができる、そしてアクセス制限したい場合にはふさわしい風に行える。 その後、ユーザーが頼んでるイメージの正式なパスを作成し、Resultを返す。

// ユーザーが送ってるファイル名的なパスと実際のサーバーのパスが違うのはず。
String path = getRealImagePath(dynamicForm.get("")); 
java.nio.file.Path deliveryPath = Paths.get(path);
// これはPlayFrameworkに存在する、ファイルをだす方法:
return new Result(
          new ResponseHeader(200, Collections.emptyMap()),
          new HttpEntity.Streamed(FileIO.fromPath(deliveryPath), Optional.empty(), Optional.of("image/png"))
);

こんな風に、画像や他のアセットのアクセスを制限することもできます。

App Analyticsについてまとめてみた

こんちは、渡部です。
久しぶりの投稿です。
今回はiOSアプリのAnalyticsについてです。
「GoogleAnalytics仕込むの面倒!」という俺のためのiOSエンジニアのための記事です。
記事を書いてる途中でiTunesConnectがアップデートされて焦りましたw

f:id:watabe1028:20180605204659p:plain

目次

App Analyticsとは?

自分が管理するアプリのApp Storeページが
・どのくらい見られているか(PV)
・どのサイトから遷移してきたか(リファラー)
・そのうちどれくらいダウンロードされたか(ダウンロード率)
・ダウンロードした翌日以降も使ってくれている人の割合(使用率)
などが見れる解析サービスです。
Apple純正なので、特別なSDKを導入する必要がないのが面倒臭がりにはすごくいい!
計測データに含まれるのは iOS 8以上のデバイスのみらしいです。
閲覧にはAdmin, Finance, もしくは Sales権限が必要になります。

 

どんなデータが見られるのか

App Analyticsは、「概要」「メトリックス」「ソース」「使用率」の4つの画面から構成されてます。
 

1. 概要

全期間および過去30日間の各データを閲覧できます。それぞれの項目を解説していきやす。

App Store閲覧数
アプリのApp Storeページが閲覧された回数。

Appユニット数
アプリがApp Storeページからダウンロードされた回数。
アップデートや、同じApple IDからの再ダウンロード数はカウントされない。

売上
アプリの売上。有料アプリ, app bundles(複数のアプリをまとめて売れるやつ良くわからない), In- App Purchasesを合わせた金額。

セッション数(オプトインのみ)
セッション数とは、アプリが少なくとも2秒間フォアグラウンドにされた回数のこと。
その後、アプリがバックグラウンドになって、再び使用されると別のセッションとしてカウントされる。
診断データおよび利用情報を App 開発者と共有することに同意したユーザのデータのみ。

アクティブなデバイス数(オプトインのみ)
指定した期間内に少なくとも1セッションとしてカウントされたデバイスの数。
診断データおよび利用情報を App 開発者と共有することに同意したユーザのデータのみ。

テリトリー別の集計
各国ごとの閲覧数、ユニット数、売上、インストール数、アクティブなデバイス数が見れる。

使用率(オプトインのみ)
アプリを初期インストールし、その後 App を使用したユーザの割合。
1日目 7日目 14日目 21日目 28日目の使用率が見られる。

プラットフォーム別の集計
プラットフォームごと(iPhone/iPad/iPod)の閲覧数、ユニット数、売上、インストール数、アクティブなデバイス数の割合が見れる。

 
※オプトインとは
加入や参加、許諾、承認などの意思を相手方に明示することらしいです。 e-words.jp

 

2. メトリックス

1日ごとの各データをグラフにして表示してくれます。
・App Store 閲覧数
・App ユニット数
・App 内課金数
・売上
・有料ユーザ
・インストール数(オプトインのみ)
・セッション数(オプトインのみ)
・アクティブなデバイス数(オプトインのみ)
・過去30日のアクティブなデバイス(オプトインのみ)
・クラッシュ数(オプトインのみ)
それぞれのデータを同時に表示して、比較することもできます。

 

3. ソース

「トップWebサイト」「トップキャンペーン」の2つから構成されます。

トップWebサイト
どのサイトから自分のアプリのApp Storeページヘ流入しているかがわかります。
・流入元ドメイン
・閲覧数
・ユニット数
・売上
・セッション数

トップキャンペーン
キャンペーンリンクを作成することで、どのキャンペーンからの流入が多いかを計測できます。

 

4. 使用率

指定した日にアプリをインストールして、翌日以降にアプリを使用したユーザの割合を詳しく確認できます。

 
 

おまけ

こちらは弊社アプリ「HRog」の実際のデータです。
毎週記事を更新しているのでパターンがあります。
(数値は見せられません)
すでにパターンが見て取れますが何をどうして良いやら。。。
f:id:watabe1028:20180608112231p:plain

 

まとめ

App Analytics、SDKの導入が必要ないのでとても助かります。
GoogleAnalytics、AppsFlyer、App Analyticsで数値を比べてみたいですね(自分ではやらないけど)。
App Annieのデータとの関係性も気になります。
 
また、ファネル分析やコホート分析もできます。

コホート分析
時間の経過に伴うユーザー行動の変化を可視化する  
ファネル分析
入口ページから目的達成までの離脱率を把握する

実はグロースハッカーになりたいのでこの辺も勉強してブログに書けたらな、と思ってます。(書くとは言ってない)