LocoPartners 開発ブログ

LocoPartners 開発者達によるブログです

開発1day合宿を開催!来期の改善アクションをロケットスピードで(少し)実践してみた

f:id:loco-dev:20180315154340j:plain
こんにちは、Loco Partnersでエンジニアをしております小貫です。

先日、開発チームで1dayの合宿を敢行しました。合宿になると、環境を変えて、やりたいことに集中できるので定期的に開催するといいですよね。

さて、今回の1day合宿では、来期戦略の発表・議論と来期取り組みたいアクションについて実際に手を動かしてみるということをしました。

それでは、そんなLoco Partnersの1day合宿の模様をお伝えします!

1dayの合宿を開催した理由

今回1dayの合宿を実施した理由は、以下の2つです。

  • チームのビジョンと役割を再確認したい
  • 来期の改善アクションを決めたい

今回はサーバーサイド・フロントエンドチーム、インフラチーム、デザイナーチームにチーム分けし、それぞれが持つ課題やそれに対する改善アクションを合宿前にまずは議論し、実際の合宿日にはチーム内で決まった改善アクションを共有する場としました。

以下が、今回の1day合宿のスケジュールです。
9:30 - 開始
9:40 - 来期戦略発表
10:00 - サーバ・フロントチーム発表
10:30 - インフラチーム発表
11:00 - デザインチーム発表
11:35 - ランチ
12:35 - もくもくタイム
16:40 - 成果発表
17:15 - 片付け完了、打ち上げ会場へ移動

GM 古田より来期戦略の発表です

まずはGM 古田より、主に開発チーム全体の来期戦略についての発表を行いました。

現状、開発チームには以下の課題が存在しており、来期戦略にてこれらを払拭していきたいと考えています。

我々の課題感
■見積もりや実装が効率悪い
■リリースの半分が計画より遅れている
■開発フローで手戻りが発生しやすい
■影響範囲考慮漏れによる想定外の不具合が多い
■セキュリティリスクを抱え過ぎているのではないか
■属人化した運用、自動化できていない作業

これらの課題感を払拭するために、来期はどのような戦略で取り組んでいくのかという話があり、それについてしばらく全体で議論や質疑応答の時間を取りました。

各チームの来期方針発表

f:id:loco-dev:20180315154426j:plain
GM 古田より来期戦略の共有があった後は、各チームがそれぞれの課題感、発表を行い、それに対し質疑応答という流れで進めていきました。

サーバーサイド・フロントエンドチーム、インフラチーム、デザインチームの順番で、各チームが持つ課題、そして来期どのようなアクションを取ることで、現状の課題を解決していくのかについて話をしました。
f:id:loco-dev:20180315154512j:plain

僕がなかでも印象に残ったのは、インフラチームの発表にあがった「インフラのビジネスに対する影響度」の話です。
システムが1分間ダウンするだけで発生する損失を、リアルなReluxの予約金額を例に表現したことで、 インフラを安定して稼働させることが非常に重要であるということを改めて再認識しました。

f:id:loco-dev:20180315154554j:plain
そして、今回の1day合宿では、実際に手を動かしてみることで、来期取り組みたいアクションの規模感や手を動かしたからこそ分かる問題の把握にトライしていきました。

各チームが、来期アクションと照らし合わせて、もくもくする内容を発表し、お昼休憩に入ります。

お昼はやっぱりバーガー

f:id:loco-dev:20180315155222j:plain
もくもくタイムに入る前に、休憩も兼ねてランチをすることに。
ランチはもちろんハンバーガーです。
f:id:loco-dev:20180315155544j:plain
実はLoco Partnersの開発チームでは、もくもく会をするときには、なぜかハンバーガーをみんなで食べるという習慣があります。
みなさん久しぶりのハンバーガーにご満悦です。

そして、もくもくタイムへ

ハンバーガーを食べ終えた後には、みんな各自で決めた課題にもくもくと作業に入ります。
f:id:loco-dev:20180315155508j:plain
皆さん集中モード!!
今回の1day合宿では4時間ほどのもくもくタイムを設けましたが、実際に動くものなどを開発する際には、もう少し時間をとったほうが良いと思いました。
そして、最後にはもくもく会でやったことを各チームで発表し、終了です。

打ち上げではカニを堪能

合宿には打ち上げがつきものですよね。
1日頭を使って、取り組んだ僕らはお腹ペコペコです。そんな僕らはみんなでカニを食べに行きました。
f:id:loco-dev:20180315155952j:plain
美味しそうなカニを目の前にご機嫌な皆さん。
f:id:loco-dev:20180315160042j:plain

まとめ

f:id:loco-dev:20180315160131j:plain
開発合宿というと、1dayだと1日中議論したり、2泊3日でひたすら開発する形式はよくありますが、半分議論、半分開発するというスタイルもかなり有意義だと感じました。

考えるだけでは、実際に取り組んだ時の規模感などを把握しづらいです。それらを把握できるのは、やはり手を動かしたからこそだと思います。

今回の1day合宿で決定したことや、新たに判明した課題は、後日再度議論し、来期どのような戦略で戦っていくのかを決めていきたいです。

最後に

最後までお読みいただきありがとうございます。
弊社では、たくさんの方々の大切な旅行機会のマッチングをするプロダクト開発に挑戦するエンジニアを募集しています!
www.wantedly.com

LocoPartnersでのSRE(Site Reliability Engineering)的な取り組み

こんにちは。

エンジニアの古田です。
ポケgoをいまだに続けてます。希少な黄色です。
今週初めてEXレイドに当選しましたが、人が集まらず倒せませんでした。

この記事はRelux Advent Calendar 2017 19日目の記事です。

qiita.com

表題にある通り弊社でもSRE的なものへの取り組みが動き始めました。
その経緯と、どうやって進めているかについて紹介させていただきます。

SREとは

最初はGoogleが提唱した考え方ですが、日本でも既にメルカリやfreeeなど導入企業が増えています。そのため少しググれば様々な情報がありますし、オライリーからも書籍が出ています。原点は「信頼性はあらゆるプロダクトの基本的な機能である」という考え方にあり、この運用チームが考慮することはインフラに留まらずソフトウェア領域へのアプローチや不要な手作業の自動化まで含まれます。
ベンチャーの多くが、今後も使われるか分からない機能やソースコードのメンテナンスよりもスピードを優先してサービスを構築していきます。そして生き残り、3年ほど運用を続けた頃から技術的負債との付き合いが始まります。Googleは、信頼性を担保するために専属のチームを作りリソースを確保して可用性を向上していくという方針を取り入れました。

なぜやるの?

弊社が運営するReluxというサービスは2013年にローンチしたサービスです。 この4,5年の間、スピードを重視しながら様々なチャレンジもしてきました。その結果、会員数が100万人を突破するまでに成長することが出来ました。

ここまで来るために、開発もスピード重視で進んできました。体制もシステムの内側もなかなかにカオスな状態です。これに対する打ち手として、先日弊社の鈴木が書いたブログにある通り、ここ1、2年で体制を改善してきたことで新しい負債は抑制されてきています。

その他にも、月に1日だけ開発者の判断でやりたいことに取り組むCLEARという日を導入しました。日々の開発タスクではなかなか優先度が上がらない『重要だけど緊急度が低いタスク』に取り組む時間です。今まで15回ほど開催し、多くの改善が生まれ一定の成果を上げています。
ただ、1日ではシステム設計を根本から見直すといった打ち手は実行できず、大きくなった負債の元本まで返済するには至らずでした。。

そんな中で引き続き、会員登録が出来ない・予約に失敗する・メールが届かない、といった致命的な不具合もちょこちょこ起きてしまっています。こういったエラーは0にすべき。これだけ多くの方に使っていただけるサービスになりましたので、これからは今で蓄積されてきた負債を減らしたりうまく付き合いながら信頼されるサービスにしていくことが必要です。ということで、一定の成長を遂げたベンチャーでは運用保守への重要性が高まってくるため、このタイミングでやり方を変えていきます。

Locoの違うところ

SREの考え方では本来、専門のチームを組成します。そしてDevチームとSREチームの意見を合わせるためにエラーバジェットという考え方が提唱されています。バジェットを使い切るまでは通常通り開発し、使い切ってしまった場合には開発を止めるというやり方で、バッファを明確にすることでどの程度開発側の無理を許容するかを事前に合意を取るものです。

今回の取り組み、Locoでは別チームは作りません。一定の工数を意図的に確保するだけです。現状でも運用はみんなでやっています。上記のような認識合わせが必要なのは、立場の違いによる利害関係の不一致です。自分が開発し、それを自分で保守メンテするとなれば、認識を合わせる必要がないのでエラーバジェットは必要ないと考えています。

チーム人数は十数名とまだ少なく、話し合いながら全員の認識を合わせることが可能なのでSRE領域のwhyとwhatを全員で認識合わせて一緒に目指します。人も固定化せず、アクションに対して得意な人がリードしていきます。

どんなことに取り組んでくか

以下のようなことをやっていけたらなーと考えています。

リファクタリング

Reluxでは4つのシステムが動いています。

  • ユーザーが使ういわゆるRelux本体(アプリ用API含む)
  • 外部パートナーと連携するためのAPI
  • 施設様が使うシステム
  • 社内オペレーションのためのシステム

現在は、いずれもCakePHP2系で動いており、一部の共通機能をLaravel5.4で内部APIとして実装しています。

この中でも特にCakePHP側のソースコードには技術的負債が蓄積されています。例えばスピードを重視したためにコピペコードが散見されるだとか、フロントエンドでも不要ファイルや処理の読み込みが残っており、不具合や表示速度低下を招くといったリスクを抱えています。 この状態を打破するために、根幹のアーキテクチャーを見直していく予定です。

具体的には、改めて現在の機能をオブジェクト思考で綺麗に設計した上でLaravel部分へ徐々に移行していきます。検索や施設情報の参照といった機能は同じような動作となるので共通化していきます。

監視

現在はNewrelic,CloudWatchを活用し、通知はSlackへ流しています。Newrelicで無料の機能がいくつかなくなり、今後もどうなっていくのか不明なのでこの機会に別のツールも検討します。

インフラ、DBのメンテナンス

スロークエリも放置すると障害の温床となります。今までは問題が起きてから見ることが多かったのですが、時間を確保して継続監視していきたいと考えています。またスケールアップを省力化したり、プロビジョニングツールを導入したりと管理負荷を下げるといったことも検討しています。

トイルの撲滅

SREでトイルというのは『プロダクションサービスを動作させることに関係する作業で、手作業で繰り返し行われ、自動化することが可能であり、戦術的で長期的な価値を持たず、作業量がサービスの成長に比例するといった傾向をもつもの』だそうです。

弊社でもデータ変更作業をエンジニアが手動でやっているところや、キャンペーンやランキングなど定型開発を自動化できそうです。

ゴールの設定

リファクタリングに関しては、最終的にどんなシステム全体像になるかをチームで話し合って決めました。あと足りないのは具体的な進め方とスケジュールです。
また、それ以外の打ち手も含めてSLO(サービスレベル目標)がまだ決まっていません。この辺りは合宿などを行い話し合います。

やる人が決める。みんなで意見をぶつけてチームが納得感を持って取り組むことを大事にして、Reluxの信頼性を高めていきます。

Sketchの便利ショートカット 備忘録

こんにちわ、デザイナーの唐橋です。 この記事はRelux Advent Calendar 2017 - Qiita5日目の記事です。

備忘録のために、Sketchの便利なショートカットをメモしておきます。

もしよかったら参考にしてください。

ページ、アートボード、オブジェクトの作成

新規ファイルを作成する【command+N】

新しくSketchファイルを作成できます。

ページを作成する【shift+command+N】

新規作成したファイルには、あらかじめページ1つ存在していますが、ページを追加できます。

アートボードを作成する【command+A】

新規作成したファイルにはアートボードは存在しません。 ショートカット後、右側にアートボードのリストがでるので、希望のサイズをクリックしましょう。

シェイブを作成する【R/O/U/L】

シェイプをつくるときに使用します。

R→短形(Rectangele)

O→円形(Oval)

U→角丸の短形(Rounded)

L→線(Line)

テキストを作成する【T】

テキストを入力できます。

オブジェクトの操作

オブジェクトの全選択【command+A】

ページ内にあるすべてのオブジェクトを選択できます。

名前を変更する【shift-command+R】

全てのアートボードを選択できます。 書き出しや、背景色の一括設定に便利です。

オブジェクトの操作

オブジェクトの全選択【command+A】

ページ内にあるすべてのオブジェクトを選択できます。

名前を変更する【command+R】

全てのアートボードを選択できます。 書き出しや、背景色の一括設定に便利です。

移動【↑↓←→/shift+↑↓←→】

選択したオブジェクト、アートボードの位置を移動できます。

リサイズ【command+↑↓←→/shift+command+↑↓←→】

選択したオブジェクト、アートボードのサイズを変更できます。

複製【command+C/command+X/command+V/command+D】

command+C→コピー

command+X→切り取り

command+V→貼り付け

command+D→直前の位置や操作を参照した複製

グループ化【command+G/shift+command+G】

複数選択したオブジェクトをグループ化できます。 Shiftをおすと、グループ化を解除できます。

マージン【option】

オブジェクトが選択された状態でoptionを押すおt、他のオブジェクトやアートボードとのマージンが表示されます。

レイヤー

名前を変更する【command+R】

レイヤーの名前を変更できます。

レイヤーの表示/非表示を切り替える【shift+command+H】

レイヤーにカーソルを合わせると、右にレイヤーの表示切り替えアイコンが出力します。

アートボードやレイヤーを検索する【command+F】

レイヤーリストの下部に検索ボックスが出現して検索できます。

ガイド

Show Rulers【control+R】

ルーラーの表示/非表示を切り替えられます。

Show Rgrid【control+G】

格子線の表示/非表示を切り替えられます。

Show Layout【control+L】

レイアウトグッリドの表示/非表示を切り替えられます。

グリッドの設定したときは「Grid Settings…」をクリックして、グリッドの細かい設定することができます。

以上、Sketchのショートカットでした! 基本的なショートカットではありますが、これだけ覚えておけば随分の作業のスピードがあがると思います。 お役になれば嬉しい限りでございます。

開発部内の勉強会でアウトプット数を2.2倍に増やした話

この記事は Relux Advent Calendar 2017 3日目の記事です。

こんにちは。エンジニアの古田です。

学びの場として、社内・部内で勉強会を開催されている組織はたくさんあります。
立候補や指名により選ばれた人がLTをすることは、よく取り入れられているやり方の一つです。
この場合、学校の授業をイメージしやすく、話す人よりも聞く人が得られる学びにフォーカスしがちだと思っています。(登壇者の方が学びが多いと皆知っていても)
今回は『発表する人が学ぶ』ことにフォーカスして仕組みを回している話です。

はじまりは成長組織を作りたい

そもそもの取り組もうと思った背景。それはチームの技術力向上でした。

弊社のサービス『Relux』はリリースから4,5年経過して運用フェーズにあります。
技術的負債の蓄積により開発効率が悪化しているため、少しずつ時間を増やしながらリファクタリングに取り組んでいます。システムの品質を向上させるには、作る人の腕を上げなけらばなりません。
テックリード人材を採用することも強力な打ち手の一つですが、それ以上に成長するチームでなければならない。多くのエンジニアは勉強熱心ですが、この学習をサポートし加速させられる仕組みを作りたいと考えました。

自動的に改善されるサイクル

最初はシステム思考にヒントをもらいました。 システム思考をご存知の方は多いと思いますが↓のような本に詳しく書いてあります。

学習する組織――システム思考で未来を創造する

なぜあの人の解決策はいつもうまくいくのか?―小さな力で大きく動かす!システム思考の上手な使い方

要は、どこに力を入れれば効率よく改善サイクルが回るかという話。 今回は、以下のサイクルを回すことを考えました。

f:id:loco-dev:20171202223312p:plain

学びの質と量を増やすために学習習慣を作りたかったので、管理できないインプットではなくアウトプットにフォーカスしました。

どうやって後押ししたかですが、運用で決めたことは以下です。

  • 毎週2名以上が発表しようと決める
  • テーマは自由
  • もしやる人がいなかったら自分(筆者)が代わりに発表する(基本、毎回TLの準備しとく)

最初のうちは習慣になっていないので当日になって準備できてない。。ということもありますが『サイクルを絶対に止めない』ことにコミットしていました。
この方針で進める以前は、週に1人すら回っておらず稀に登壇者なしとなるので『この人数だと週1でもLT回すのってしんどいね』という雰囲気だったものが、この2ヶ月ほどは平均して2.2人ずつが何かしら発表できています。

発表された内容は様々です。

うまく回り始めた理由はいくつかあると思います。

  • サービス品質向上のため、技術に関する知識を全メンバーが共通で持たねばという危機感があった
  • 元々インプットが多いメンバーが引っ張ってくれた
  • 自分(筆者)が毎週でも発表できるという姿勢を見せた

また、これまでは周りが『聞かせてもらう』スタンスだったので、発表者はしんどい役割を負う被害者的な気持ちになっていました。
今回はアウトプットにフォーカスしたので『発表者が学びのあった人』という意識の変化もあったと思います。

2ヶ月経過して

メンバーに変化があったかどうか聞いてみました。
正直、インプットの量が増えたり習慣が変わるところまでは至っていないようです。ただ、理解が曖昧では発表で説明できないため、アウトプットを意識することで理解の解像度が上がったという声はありました。

そして、これからのことを考えると、、
現状はこれまでストックされていた知見で回っていました。
しかし、恐らくこれからが苦しい局面で本当にインプットの習慣がない人はアウトプットするものがなくなると思います。吐き出すものがなくなってきて初めて学びの少なさに気づき始めます。

実際、既に個人差も出ています。普段からインプットの多い人は発表回数が多い。また今は質にこだわっていませんが、そこにも差が出ています。ちゃんと意識して学んだり自ら手を動かしたことか、ネットでちょっと調べれば出てくるものか。発表すると分かります。
弊社では、毎月30minの1on1を実施しているので、そこでも会話しながら学習サイクルを加速させるフォローが出来たらと思います。

まとめ

自分は、良い習慣や文化が凄く大事だと考えています。

極端な話、今のメンバー全員が入れ替わったとしても、このLocoに勉強して成長する文化があれば強い組織でいられます。
文化を作ることは時間のかかることです。静止摩擦係数も大きい(突然の物理学)ですが、Tryし続けるしかないです。

そんなチームで一緒に成長してくれる仲間も募集中です。
気になったら気軽に連絡ください!

www.wantedly.com

Photoshopの便利機能を活用した、Relux流バナー作成方法

こんにちわ、デザイナーの唐橋です。

2017年も早いもので3月になりましたが、まだまだ寒い日が続きますね!

さて今回は、Photoshopの便利な機能、

  • 「アートボード」
  • 「スマートオブジェクト」
  • 「ライブラリ」

を活用した、Relux流バナー作成方法をご紹介したいと思います。

私自身もまだ試行錯誤の段階ですが、 以前より作業が効率的に、そしてファイルの管理がとてもスマートになりました!

それでは、紹介していきます。

1 デザインは複数アートボードで並べてつくる

これまでは1つのファイル内で「マスク」を使用してバナーを並べたり、 1バナーごとに別ファイルで管理していましたが、 現在は1ファイルに複数のアートボードを作成して制作しています。

f:id:loco-dev:20170309182855p:plain

メリット

  • バナーデザインを並べて、俯瞰しながらデザインできる。
  • 1ファイルで済むので、管理が楽になる。
  • アートボード名をファイル名にすると、自動的にjpgで書き出してくれる。

デザインの確認が楽になったのが嬉しいポイントです♪

2 画像はスマートオブジェクトに変換する

スマートオブジェクトは、何度も同じ素材を利用する際は、 とても便利な機能です。

メリット

  • 画像を拡大縮小を繰り返しても、劣化しなくなる。
  • 複数使用しても、1画像分の容量で済む。
  • ひとつのオブジェクトを変更すると、すべてのオブジェクトを変更してくれる。

今回は「富士山の写真」と「スマートフォン」の画像をスマートオブジェクト化しています。 デザインを考えるうえで、何度も拡大縮小しましたが、劣化しておりません。

3 ライブラリでよく使うパーツを管理する

ロゴや色など、よく使用するパーツはライブラリに登録しておくと便利です。

今回はReluxのロゴをライブラリ登録しています。

f:id:loco-dev:20170309183117p:plain

メリット

  • 瞬時に呼び出して使うことができる
  • 元ファイルを開く必要がなくなる
  • Adobe製品内で同じライブラリを使用できる

上書きするとまずいロゴデータなど、「元データ」のaiファイルを毎回開かなくてよくなるので、 精神的にも安定します(笑)

さらにライブラリを、Creative Cloudで管理することで、 デザインチームメンバーと同じ環境を同期することができます。

4 jpgへの書き出しは自動化で!

1の「複数アートボードで並べてつくる」でも少し触れましたが、 アートボード名を「xxx.jpg」というように画像ファイル名にすると、 自動的にフォルダが生成され、そこにjpg画像がリアルタイムで書き出されます。

アートボード名だけでなく、レイヤー名にも適用されるので、 自分の好きなレイヤーごとにjpgに書き出すことも可能です。

もう「スライス」は過去の機能となりつつあります。

f:id:loco-dev:20170309183400p:plain

↑今回はアートワーク名に書き出されるファイル名を記述しています。

まとめ

Relux流バナー作成方法、いかがでしょうか?

私もまだまだPhotoshop勉強中の身ですから、もっと効率よくできないか模索中です。

そしてこういったデザインファイルの効率化に興味のあるデザイナーを大大大募集中です!!!!

一緒にReluxのデザインファイルの管理を考えませんか? ぜひお気軽に遊びにきてください♪

↓↓↓↓↓お問い合わせはこちらから!↓↓↓↓↓

www.wantedly.com

大学生のインターンも募集中ですよ!!

www.wantedly.com

CakePHPer が Laraveler に成りたくて Part.1

こんにちは。

Relux でサーバーサイドを担当している山口です。PHP が大好きです。

弊社では近頃一部の処理に Laravel を採用することになりました。今まで主に CakePHP を利用していたこともあり、未だまだ不慣れな箇所も多いですが学んだことを少しづつ当ブログを通じて発信していけたらと思います。

今回は初回ということで、簡単な API を Laravel 5.4.5 で作成し、テストをパスするまでの過程を紹介します。

Larvel でとりあえずコードを書いて試せる環境を用意する

composer の普及や built-in server が組み込まれた PHP の Version を Framework 側が要求するようになったこともあり、最近の PHP Framework はどれも環境を用意するのが非常に楽になりました。Laravel も他のフレームワーク同様に下記の手順を踏むだけで簡単に環境を用意することができます。

# Laravel のインストール
$ composer create-project --prefer-dist laravel/laravel sandbox

~~~ 省略 ~~~

Writing lock file
Generating autoload files
> Illuminate\Foundation\ComposerScripts::postUpdate
> php artisan optimize
Generating optimized class loader
The compiled services file has been removed.
> php artisan key:generate
Application key [base64:yTWzVOqqPVKjXpIxvtgSDLguGC3BDbNbzswrjFi4qaA=] set successfully.
# build-in server の起動
$ php artisan serve
Laravel development server started: <http://127.0.0.1:8000>

上記の URL (http://127.0.0.1:8000) をブラウザで開くと、オシャレなフォントで Welcome と表示され Laravel が動作していることを確認できます。 また、今回 built-in server の起動に利用した artisan コマンドは、他にも migration や各種コードの雛形の自動生成など色々と便利なことを行ってくれます。

もし、composer コマンドの途中でエラーが発生してしまった場合は Installation - Laravel - The PHP Framework For Web Artisans を満たしていないことになるので確認してみましょう。もう少しきちんとした開発環境を用意しないと気がすまない人は Laravel Homestead や Laravel Valet と呼ばれるものもあるのでそちらを試されてみるのも良いかもしれませんね。

Laravel Homestead - Laravel - The PHP Framework For Web Artisans https://laravel.com/docs/5.4/valet

API の仕様を決める

はじめに API の仕様を swagger-editor で作ります。 これは、Laravel とは関係がないので必要のない方は飛ばして頂いて問題ありません。

swagger-editor の install は npm, wget, unzip がインストールされている端末であればあっという間に終わります。 Web の開発をされている方の端末であれば大体はインストールされていると思うので、下記のコマンドを上から順に実行してみてください。

$ npm install -g http-server
$ wget https://github.com/swagger-api/swagger-editor/releases/download/v2.10.4/swagger-editor.zip
$ unzip swagger-editor.zip
$ http-server swagger-editor
Starting up http-server, serving swagger-editor
Available on:
  http://127.0.0.1:8080
  http://192.168.10.254:8080
  http://192.168.33.1:8080
Hit CTRL-C to stop the server

上記の URL (http://127.0.0.1:8080) にアクセスすると swagger-editor の画面が表示されるので、画面内で Swagger Spec V2.0 と呼ばれる決まりに従って json または yaml で仕様書を書いていきます。細かい説明は今回は省略して下記のようにドキュメントを記述しました。

swagger: '2.0'
info:
  version: "1.0.0"
  title: Uniqid API
paths:
  /uniqid:
    get:
      description: uniqid を作成
      produces:
        - application/json
      responses:
        200:
          description: |
            uniqid の作成に成功した場合
          schema:
            properties:
              uniqid:
                description: |
                  uniqid
                type: string

API のテストコードを記述する

それではテストコードからはじめていきたいと思います。 built-in server の起動に用いた artisan コマンドを用いて下記のようにユニットテストの雛形となるコードを生成しましょう。

$ php artisan make:test UniqidControllerTest --unit
Test created successfully.

tests/Unit 配下に UniqidControllerTest.php という下記のファイルが出来上がっているはずです。

<?php

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class UniqidControllerTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testExample()
    {
        $this->assertTrue(true);
    }
}

早速、テストを実行してみましょう。

vendor/bin/phpunit
# 上記で実行出来ない人は下記を試してみて下さい。
vendor/phpunit/phpunit/phpunit

# 実行結果
PHPUnit 5.7.9 by Sebastian Bergmann and contributors.

...                                                                 3 / 3 (100%)

Time: 415 ms, Memory: 12.00MB

OK (3 tests, 3 assertions)

うまく動きましたか?テストをパスした数が 1 ではなく 3 になっているのは予め ExampleTest.php というファイルが存在しているからです。 これで、テストの雛形とテストの実行方法がわかったと思います。

それでは、テストを仕様に沿って記述していきましょう。uniqid() の性質上返される値を特定するのは難しいため、今回は雑ですがレスポンスに uniqid の key が存在するか、そしてステータスコードは 200 かをテストするコードを記述しました。

<?php

namespace Tests\Unit;

use Tests\TestCase;

class UniqidControllerTest extends TestCase
{
    /**
     * Authentication Controller.
     *
     * @return void
     */
    public function testレスポンスにuniqidのkeyが存在する()
    {
        $response = $this->json(
            'GET',
            '/api/uniqid'
        );

        $arrayResponse = (array)json_decode($response->content());

        $response->assertStatus(200);
        $this->assertArrayHasKey('uniqi', $arrayResponse);
    }
}

再度、テストを実行してみると下記のように 1 件のテストに失敗しているはずです。

PHPUnit 5.7.9 by Sebastian Bergmann and contributors.

..F                                                                 3 / 3 (100%)

Time: 459 ms, Memory: 12.00MB

There was 1 failure:

1) Tests\Unit\UniqidControllerTest::testレスポンスにuniqidのkeyが存在する
Failed asserting that an array has the key 'uniqid'.

/Users/kenya/loco/relux_api/tests/Unit/UniqidControllerTest.php:26

これは、テストに対応する実装が存在しないからですね。 次はこのテストをパスするために API の実装を行っていきます。

API の実装

artisan コマンドを用いて下記のようにコントローラーの雛形となるコードを生成しましょう。

$ php artisan make:controller UniqidController --resource
Controller created successfully.

app/Controller 配下に UniqidController.php という下記のファイルが出来上がっているはずです。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UniqidController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

今回は index() の部分しか必要がないのでそれ以外は削り、下記のように実装を行いました。

<?php

namespace App\Http\Controllers;

class UniqidController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $responseValue = [
            'uniqid' => uniqid(),
        ];

        return response()->json($responseValue);
    }
}

Routing を設定する

最後に作ったコントローラーを動かすために Routing を設定します。この設定ファイルは routes/api.php になるので下記の一行を足します。 コントローラー名@アクション名を第2引数に設定することで Laravel 側で UniqidController の index アクションにつなげてくれるようになっています。

Route::get('/uniqid', 'UniqidController@index');

動作を確認する

実装が完了しました。再度テストを実行してみましょう。

PHPUnit 5.7.9 by Sebastian Bergmann and contributors.

...                                                                 3 / 3 (100%)

Time: 421 ms, Memory: 12.00MB

OK (3 tests, 4 assertions)

テストを通過しました!(雑ですが…

ブラウザからも http://127.0.0.1:8000/api/uniqid にアクセスして確認してみましょう。 下記のように結果が返ってくることが確認できたら成功です。

うまく動かない場合は最初に行った server の起動を行えているか再度確認してみてください。

{
  "uniqid": "58905d5e13920"
}

お疲れ様でした。今回はここまでとなります。 簡単な処理と説明ではありますが何となく Laravel を利用した API 作りのイメージを持っていただくことが出来たのではないでしょうか。

冒頭でも述べさせていただいたように自身も未だまだ Laravel に不慣れなので、連載を通じて Laravel について知り、皆さんのお役に立てるような記事を書けていけたらなと思っておりますので今後共宜しくお願いします。

最後になりますが、弊社では PHP が大好きな方や、「山口に俺が Laravel を教えてやるよ!」という技術的に熱い人を大募集しています。 会社見学とかも気軽に行えるので良かったら下記のリンクから気軽にお申込み下さい。

www.wantedly.com