Laravel5.8から6.4にバージョンアップしました

f:id:kubotak:20191114171317j:plain

こんにちはkubotakです。 弊社プロダクトはPHPフレームワークであるLaravelを採用しています。 私が入社した時点(2019/11)は利用しているバージョンがLaravel5.8でした。 現在ではLaravelのバージョンは6を迎え、長期サポートの対象となっています。

LaravelはOSSオープンソースソフトウェア)であり、有志によりサポートされています。 メンテナンスやセキュリティのサポートなどは各バージョンで特定の期間で実施されていて次のようなスコープになっています。

Version Release Bug Fixes Until Security Fixes Until
5.5 (LTS) August 30th, 2017 August 30th, 2019 August 30th, 2020
5.6 February 7th, 2018 August 7th, 2018 February 7th, 2019
5.7 September 4th, 2018 March 4th, 2019 September 4th, 2019
5.8 February 26th, 2019 August 26th, 2019 February 26th, 2020
6 (LTS) September 3rd, 2019 September 3rd, 2021 September 3rd, 2022

5.8はすでにバグフィックスサポートの期限を迎え、セキュリティサポートも来年の2020/02/26に期限を迎えます。 そこで、弊社では6系へのバージョンアップを実施しました。

ちなみにLaravel5系では5.xというバージョンがメジャーバージョンでしたが6系からセマンティックバージョニングになり、{メジャー}.{マイナー}.{パッチ}という形で管理されています。 現時点(2019/11)では6.4が最新バージョンとなります。

5.8から6.xへのバージョンアップは公式でアップグレードガイドが出ているのでそれを参考にすることができます。

Upgrade Guide - Laravel - The PHP Framework For Web Artisans

弊社で引っかかった項目は以下でした。

URLの生成に関しての変更

URLの生成が以下のように変更されていました。

Route::get('/profile/{location}', function ($location = null) {
    //
})->name('profile');

// Laravel 5.8: http://example.com/profile/active
echo route('profile', ['status' => 'active']);

// Laravel 6.0: http://example.com/profile?status=active
echo route('profile', ['status' => 'active']);

第2引数に渡す配列で、ルーターで指定した名前と一致しない場合はクエリパラメータとして扱うという変更です。 むしろ今まで名前が一致していないのにパスパラメータに変更していたのが驚きですね。 弊社ではこのパラメータが、例えばルーターuserIdとしているのにURL生成時の引数では['id' => xx]のように扱っていて想定していたURLと違うURLを生成していました。

JobWorkerのインスタンス引数が変更されていた

これはアップグレードガイドに載っていないものですが、Laravel Jobを実行する際のWorkerのインスタンス引数が変わっていたのでエラーになりました。 変更はこちら

github.com

ドキュメント通りにLaravelを使っている際はおそらく心配ないかと思いますが、弊社ではこのWorkerの生成を独自に行なっている処理がありました。 引数が一つ増えていたので見事に死・・・静的解析が求められますね・・・

さいごに

無事、Laravel6系に追従できました。

最後に宣伝です。 弊社では来年の2020年3月21日(土)に開催されるLaravel JP Conference 2020にゴールドスポンサーとして協賛しています。

conference2020.laravel.jp

私もコアスタッフとして参加しているのでLaravelを使っている、興味があるという方はぜひご参加ください。

弊社久保田がShizuoka.js#4で発表しました

2019/11/16(土) エニシア静岡マルイ店で開催されたShizuoka.js#4で弊社久保田が「Vue.jsの状態管理」というタイトルで発表しました。

connpass.com

発表資料はこちら speakerdeck.com

前職に在籍していたときに参加・発表させていただいたShizuoka.php#1の際にお誘いいただき、Shizuoka.jsでも発表の機会をいただきました。 Shizuoka.jsは発表内容のレベルが高く、静岡のJavaScriptの勢いを感じました。

弊社ではフロントエンドの開発に力を入れていくためにフロントエンドエンジニアを募集しています。 静岡の勢いに負けないように頑張りたいと思います!

www.wantedly.com

Amazon CloudSearchからElasticsearchへ移行した話(会社のフェーズと技術選定)

f:id:yamotuki:20191114142408p:plain

こんにちは。M&Aクラウドのエンジニアの鈴木智也です。 「自分たちのプロダクトが市場にまだ受け入れられておらず、開発チームが小さく、さらに作ろうとする機能が実際に使われるか分からない。」
そういう時にどういう技術選定をしてきたか、というM&Aクラウドの開発チームの歴史についての話です。

概要

ざっくりいうと

  • サイト立ち上げから4ヶ月目の2018年8月。サイト内検索を作るのに Amazon CloudSearch というAWSにロックされた導入が楽チンなソリューションを選択してしばらく運用していた
  • それから1年弱たった2019年7月。諸々の問題が発生した。全環境で可能な限りインフラ構成を合わせようと Elasticsearch を使うように変更する

当時のイメージ図でいうと以下のパーツだけです。

f:id:yamotuki:20191113140858j:plain
サイト内の買い手企業が検索できるようにする機能

現在の検索は以下のような形で高機能になってきました

f:id:yamotuki:20191113141752p:plain
2019年10月時点での買い手検索

最初にAmazon CloudSearchを導入した。その時何を考えていたか?

Amazon CloudSearch (以下CloudSearch)は超ざっくりいうと「全文検索エンジンを細かい設定とか気にせずすぐに使えるAWSフルマネージドのサービス」です。 CloudSearchの裏では OSS の Elasticsearch が動いているらしく、だいたい同じことができますが、CloudSearchの方は細かいこと気にしなくていいです。自分で ElasticSearch 立ち上げてクラスタ設定して、細かい日本語形態素解析設定とか、そういうことを気にしなくていいのは良いです。

CloudSearch導入時に考えていたこととやったこと

当時の状況

  • 開発チームはエンジニアが2人だけ
  • プロダクトはローンチしたばかり
  • そもそもプロダクトに何が求められているか手探り状態。検索ワードを取得すればニーズを探ることができるのでは???
  • 買い手検索機能が求められているかどうかも分からない。精度は低くてOK

技術調査

当時の状況に合わせて最適な解を探しました。

  • そもそもサイト内検索であればGoogleサイト内検索を組み込めばいいのでは?
    • => 必ず広告が表示されることが判明。苦労して集めた顧客に対して競合の広告が出るのは望ましくないのでNG。広告なし有料プランは直前まで提供されていたようだが廃止されていた。
  • Yahooのサイト内検索(カスタムサーチ)は?
    • => 「閲覧などを制限したり、パスワードを要求するサイト」は使用NG。M&Aクラウドは会員登録が必要なサービスなのでNG
  • 専用のソリューション
    • => いい感じのがありそうでしたが、初期導入費用に数十万、月額で数万かかるものだったのでNG。ベンチャーはお金ないのだ。
  • Elasticsearch は頑張れが導入できるけど、使われるか分からない機能のためにインフラ設定を初期投資としてがんばるの??
    • => 今はやめておこう。NG
  • AWS に Elasticsearch っぽいいい感じに使えるのがあるっぽいぞ?
    • => これが CloudSearch でした。1インスタンス4000円安い!(上記の専用ソリューションに比べたらだけど)

構成を考える

  • 本番環境と開発環境の2つのCloudSearchインスタンスを作る
  • 開発者が当時2人だけ。だからLocalで開発するときも開発環境のCloudSearchインスタンスに繋げれば OK。Localの環境整えるのも手間だしね
  • Localと開発のデータ差異もプロジェクトが始まって間もなく、そんなにないのでDBの内容と CloudSearch の Index が多少食い違ってもOK
  • サイト内検索の精度は、最初はその機能がどう使われるかの検証するレベルなのでそんなに高くなくて良いし、導入コストをたくさん払いたくない

会社が大きくなってくると最適解も変わる

より高機能な検索が必要だ

2019年も半ばになって、プラットフォームの売り上げも上がってきて、買い手も増えた。どういう機能が顧客に求められているかも徐々にはっきりしてきた。 例えば、買い手が100件超えそう。売り手は全ての買い手の記事に目を通すのができなくなってきた。絞り込みをする必要がある。買い手検索を高機能にしよう。 というわけで雑に作ってあまり使われていなかった買い手検索に光が当たることになりました。

起こるトラブル

高機能な買い手検索の開発にあたりいくつかトラブルが起こりました。

  • LocalからCloudSearch繋げないと検索周りの確認ができないが、env設定変更が面倒
  • 面倒がゆえに、開発中に一時的にCloudSearchに繋げないでメソッド内部で固定値を返すように無理やり変更。これがうっかりプルリクエストに入ってマージされて本番でも固定値しか返らないようになるトラブル
  • 無理やり固定値を返さなくても良いようにLocalではDBから検索するように分岐をするようにした(LaravelのServiceProviderでの分岐)。本格的なサイト内検索を作ろうとすると、CloudSearch叩く方とDBから検索する方と両方の開発を同時に進めなくてはならず、コストが膨らんでいった
  • ちゃんと検索機能を開発しようとするとDBとの整合性も大事なので、手元で書いて開発環境にデプロイして確認、また書いてを繰り返すのがコスト

インフラアーキテクチャがいけてないからトラブルが起こるんだ・・・!

根本対応をしたい。環境差異を無くそう。 エンジニアも3人になった(注: 2019年11月時点ではエンジニア4人デザイナ1人)。Localと開発環境のDBデータの差異も大きくなってきた。もう環境差異があってはやっていけない! ということでこの二つの環境を合わせることに。

環境を合わせる選択肢は以下のものが現れました

  • CloudSearch を各開発者向けに1台ずつ立ち上げる
    • 10人いたら10台*4000円? 無駄じゃね
  • 裏で ElasticSearch 動いているんだから ElasticSearch 動かせばよくない?
  • EC2 に ElasticSearch 立てて自分たちでマネージしていくの? きつくない?

こんな話があり、しかしちょっと調べてみると ElasticSearch は思ったよりも簡単に導入できそうだということがわかりました。

  • Localに関しては、Laradock で docker-compose up するときに elasticsearch を追加したらすぐに立ち上がることがわかりました。しかもkibanaも同様に簡単につけられる
  • 開発/本番環境に関しても、フルマネージドのAWS Elasticsearch Serviceがある

というわけで、Elasticsearchが導入されました

そこらへんの技術記事は以下のような形で qiita に断片的にまとまっているので参照してください

終わりに

問題が起こった時に気合いで解決せず、あるべき形の判断材料を並べてチームで判断できたのはよかったと思います。 みんなでスクラム組んで、より生産性を高い状態にしようということを努力しているチームです。

そういうわけで、私たちと一緒に四苦八苦しながら最高のプロダクトを作ってくれる仲間を募集しています。

www.wantedly.com

www.wantedly.com

Qiita記事を書くための取り組みについて

f:id:zacky2:20191111181015j:plain Webエンジニアの津崎です。

弊社のプロダクトチームでは、 社内での知見共有と、知見の正確性を担保するためにQiitaへの記事投稿を積極的に行なっています。

今回は、Qiitaの記事を定期的に書けるようにする、記事を書きたくなるようなTipsを紹介します。

運用の成果について

本取り組みは、記事数を増やすことが目的ではないため、投稿数などの定量的な目標は設定していませんが、取り組みを始めることで以下のような効果がありました。

記事がバズってランキング上位に掲載

ある記事がバズり、デイリーランキング1位、900いいね & 30,000viewまで伸びました🏅

qiita.com

Organizationランキング(週間)上位に載る

Qiitaトップページに表示されるOrganizationランキング(週間)上位10件に何度か掲載されました🎉

週6ポストほどでトップページに会社名が載るので、チームでのモチベーションに繋がりました。

f:id:zacky2:20191107181716p:plain

チームでの記事投稿頻度が増えた

過去1ヶ月の実績では、1人あたり3記事/1ヶ月。

だいたい週に1回弱くらい記事を投稿できています🤔

Qiita記事を書くための取り組み

取り組みの内容について紹介します。

毎週リマインダーを設定する

Qiita記事をたくさん書こうと思っても、日々の業務を行なっていく中ですっかり忘れさられてしまうことがあります。

Slackには簡単にリマインダーを設定する機能があるので、それでQiita記事を書くようにリマインド設定しました。

@channelでチャンネルメンバーみんなに見せればプレッシャーが上がります😈

スクリーンショット 2019-08-30 14.52.18.png

以下の文字列をSlackのチャット欄に貼り付けるとリマインダーが設定できます

/remind @channel 今週Qiitaの記事書いた? at 14:00 every Friday

Qiitaスタンプを導入する

いざ記事を書こうと思っても、ネタが思いつかないなことや、書こうと思っていたネタがあったのに失念してしまうことは往々にしてあります。

そんな問題を解決する方法として便利なのが、Slackのカスタム絵文字機能です。

カスタム絵文字機能を使ってQiitaアイコンの絵文字を作ります。

Qiitaのネタになりそうなチャット内容があったら、Qiitaスタンプを押しておきます。 他人のチャットにも、ガンガンQiitaスタンプをつけて、Qiita記事をかく圧力をかけましょう😈

こんな感じでスタンプします。

f:id:zacky2:20191108143033p:plain

QiitaスタンプをつけたSlackの投稿を検索する

has::qiita: というキーワードで検索するとqiitaスタンプついたチャットを検索できます。 記事を書くときは、ここからネタを振り返ると便利です。

f:id:zacky2:20191108140547p:plain

おわりに

Qiita記事を書くために行なっているTipsを紹介しました。

これからもチームのアウトプットを多くするために工夫をしていきたいと思います。

【kubotak】中途入社しました。

こんにちは、こんばんは、おはようございます。

今月からM&Aクラウドにジョインしましたkubotakこと久保田です。

ツイッターはこちらです。宜しくおねがいします。

kubotak (@kubotak_public) | Twitter

 

前職では国内最大級のコスメのクチコミサイトを運営する会社でよくわからないエンジニアをやってました。

ときにはPHPでWebアプリケーションを作り、GolangでコンソールアプリケーションやREST APIアプリケーションを作ったり、ScalaRDBMSからHDFSに挿入するスクリプトをSparkを利用して作ったり、JavaScriptで社内イベントで遊ぶゲームアプリ作ったり、HHVM/Hackも書いたりしました。

知ってますか?Hackいいですよ(今はやってないですが)

 

今回M&AクラウドのCTOである荒井さんにお誘いいただいてジョインする運びとなりました。どういったところに惹かれたのかと言うと・・・

 

まだまだ実装したい機能がいっぱいある

この辺は人手不足と、成長の幅を感じました。

やりがいがありそう!

 

フロントエンド力を高めていきたい

フロントエンドを手探りで学びながらやっているみたいです。

私もフロントエンドエンジニアではないし、前職でもあまりやってないんですが趣味でJavaScript(Vue/Nuxt,Svelte)などを書いていたりフロントエンドへのモチベーションは高いので頑張ってやっていきたいと思います。

 

設計をちゃんと考えていきたい

設計やアーキテクチャなんかは僕も大好物です。みんなで学んで考えて最適解を見出してより変化の強いコードをかければいいなと思ってます。

 

他の社員もスキルアップのモチベーションが高い

毎週UIや設計、フロントエンドのトレンドなどを追って勉強会をしています。

とても向上心のあるメンバーだなぁと感心しています。

 

採用も強化していきたい

作りたいものは多いんですがそれを作るメンバーが足りていません。

絶賛募集中です。 

PHP系の勉強会ではちょくちょく参加させてもらっているんですが、外部の勉強会を通してこの会社をアピールしていけたらいいなと思っています。露骨な宣伝はしませんが、自分が所属していることで認知されていくと嬉しいなと思います。

 

入社後

この会社の事業ドメインを理解するのは大変だと思います。M&Aなので専門用語が多い!それは日々覚えていくよう頑張っています。

で、いきなりドメイン知識の必要な実装はできないので整備されてないものをちょっとずつやるようなタスクを消費してます。

今まではデプロイを各作業者の端末からAWSのebコマンドでElasticBeanstalkを利用したデプロイを採用していましたが、CircleCIによるCI/CDができるように変更したり、途中で放置されていたプルリクエストのLaravel mixをやめて自前のWebpackタスクでJavaScript/CSSのビルドをできるようにする・・・などなどやっております。(この辺は別記事で詳しく紹介できればと思います)

 

イマドキな開発ができる環境を作りつつ、事業ドメインをキャッチアップしていい感じに実装できるマンになりたいと思います。

 

最後に

現在、M&Aクラウドではエンジニアの募集をしております。興味のある方は、是非下記からご応募お願い致します!


https://www.wantedly.com/projects/159995

https://www.wantedly.com/projects/275331

弊社津崎がLaravel/Vue.js勉強会#11で発表しました

f:id:kazuhei0108:20191029224254j:plain

こんにちは。株式会社M&Aクラウドの荒井です。

先日10月28日に行われたLaravel/Vue.js勉強会#11にて弊社の津崎がLT発表を行いました。

登壇内容

「PhpStormからLaradock上の PHPUnitを動かしたら開発が捗った話」

弊社で実際に使っているPhpStormからLaradock環境内でのテスト実行とその設定方法についての発表でした。以下に実際のPhpStormの設定方法についてもQiitaの記事としてまとまっていますのでぜひご覧になってください。

qiita.com

Laravel/Vue.js勉強会#11

株式会社ROXX様が主催されているLaravel/Vue.jsについての勉強会で大体2,3ヶ月に一度行っていてもう11回目とのことでした。 会場は株式会社FABRIC TOKYO様のオフィスでした。とってもきれいなオフィスでした!

開発者ブログを開設しました。

この度M&Aクラウドの開発者ブログを開設しました。ブログを開設する目的はずばり、チーム作りです!

チーム作りに力を入れる理由 

良いプロダクトを作るための条件ってなんでしょうか。

f:id:kazuhei0108:20191025190155p:plain

私達は良いプロダクトを作るためには、仲間集めが大事だと考えています。簡単に図示すると下図のようになると考えていて、良いチームがInputで良いプロダクトがOutputになるということです。

また、InputからOutputまでの過程も大事だと思っています。

f:id:kazuhei0108:20191025110649p:plain

f:id:kazuhei0108:20191025110701p:plain

仕組みの部分への取り組みを強化することで、メンバーが増えて、メンバーの多様性が広がってもそれをプロダクトの成長に繋げられる、スケーラビリティのある開発組織になると考えています。 

チームメンバーの集め方

ではプロダクトには良いチームが必要だとして、どうやってチームメンバーを集めればよいでしょうか?それは社内の 

  • 良い仕組み
  • 良い企画
  • 良いデザイン
  • 良いコード

といった良いプロダクトを作るまでのチームの活動を広く発信していくことだと思います。

f:id:kazuhei0108:20191025190323p:plain

これによって弊社のプロダクトチームの考え方への賛同者が自然と集まってくる状態を目指します。
弊社には知見共有を重視する文化があり、技術については日頃からチームメンバーがQiita上で記事を書いていますので、この開発者ブログではQiitaとは違って、より開発チーム自体について外部から分かるような内容を書いていこうと思います。 

最後に

現在、株式会社M&Aクラウドではエンジニアの募集をしております。興味のある方は、是非下記からご応募お願い致します!


https://www.wantedly.com/projects/159995

https://www.wantedly.com/projects/275331