Retty Tech Blog

実名口コミグルメサービスRettyのエンジニアによるTech Blogです。プロダクト開発にまつわるナレッジをアウトプットして、世の中がHappyになっていくようなコンテンツを発信します。

Retty裏入社式2017を行いました!

みなさん、こんにちは。 新卒エンジニアとして4月から入社しました新卒エンジニアの田松、竹野、Brenton(ブレントン)です。 今回はRettyの伝統行事になりつつある「裏入社式」というものについて紹介します。

f:id:rettydev:20170522164423j:plain

Retty裏入社式とは

裏入社式と聞いてピンと来ない方も多くいらっしゃると思いますが、決して怪しいことをしている訳ではありません(笑) Retty裏入社式とは、2016年の新卒が企画し実行したことが始まりとなった行事で、新卒全員で社員を巻き込む行事を企画、運営し、実際に行っているものとなります。 去年の裏入社式の様子はこちらに記事が挙がっています。

今年はこんな新卒が入ってきたんだよ!と全社を巻き込む最初の機会であり、入社後の新卒同士、他社員との繋がり強化や、伝統作りとして今年も開催させて頂きました。また、入社式で社員さんに祝ってもらった僕たちが今度は社員さんに恩返しという意味も込めて楽しい行事を考えてみました。

今年の裏入社式のテーマ

さて、今年の裏入社式ですが新卒の総合職が企画を考案し、今年の新卒にはエンジニアがいるので、その企画に合わせて僕たちエンジニアがサービスを一つ作らせて頂きました。

今年のテーマは「修学旅行」です。 社会人の僕たちが学生の頃を思い出せるような内容を企画組が考えてくれました。修学旅行と聞くと誰でもワクワクしますよね!

開発したサービスは、人から探すマップです。Rettyの強みである実名制という性質を使って、信頼できるあの人が実際に行ってオススメしているお店を地図上から探すことができるというサービスです。このサービスを社員向けに作成し、使って頂きました。

実際に行った内容

実際に行なった内容ですが、複数チームに別れて社員とのゆかりある店をクイズ形式で出題し、そこに来店を朝昼夜と行い、クイズの正解数に応じて景品がもらえるとういうものです。また、途中のレクリエーションでは花屋敷に伺いみんなで遊び、面白い写真大会を行いました。ここで面白い写真を撮ったチームにポイントを付与し、そこでもポイントを稼げる形を取りました。

そこで、クイズの選択肢としてエンジニアが作ったマップ内のお店、口コミを使い、そのままマップのルートに従って来店しました。

サービス概要

今回のサービスは、現段階ではリリースされるものではないので、アプリ内には実装せずスマホwebを利用しました。 自分が選択した人の行ったお店リストが地図上に表示され、口コミを見ることができます。 アプリ版のRettyの地図表示に似たような画面になっていますが、現在、Rettyでは自分が信頼できる人の行ったお店をリストから閲覧することが出来ますが、それをマップに表示する機能が備わっていませんので、今回はこの課題を新卒エンジニア3人で解決してみました。

f:id:rettydev:20170524144055p:plain

機能要件

サービス中の機能要件は

  • Google Map APIを利用し、複数店舗の店の地図表示機能
  • 作成された上記の地図の複製・編集機能
  • ユーザーIDを入力としたお店の簡易な検索ロジック

の3点になります。

サービスの構成

今回作成したWebアプリケーションは、特段凝ったつくりでなくシンプルです。

フロントエンド側は

バックエンド側は

開発時間も限られていることから、なるべく危険を犯さずシンプルな作りにして分業をしやすくし 各分担の担当者が使い慣れているようなもの、を使った形です。

tornado(Python)を利用したWebサーバ

tornadoは、スケーラブルでノンブロッキングなWebサーバを 簡単に構築するためのライブラリです。

C10K問題の解決に向けて、スレッドの使い回しを行ってくれます。 今回のサービスは社員向けだったため 、やや過剰性能になりますが 使い慣れている技術を使う、ということで採用しました。

以下のようなコードでWebサーバが構築できます

from tornado import ioloop, httpserver, httpclient


class MainHandler(web.RequestHandler):

    def __init__(self, *args, **kwargs):
       super().__init__(*args, **kwargs)
       logger.debug(self.get_template_path())

    # GETリクエスト
    def get(self):
       # do something ...
       self.render("index.html")

    # POSTリクエスト
    def post(self):
       # do something ...
       fuga = {"hoge" : "fuga"}
       self.render("index.html", data=fuga)


def make_app():
    return web.Application([
          (r"/", MainHandler), # {endpoint}/ -> MainHandler に ルーティング
       ],
       template_path=os.path.join(os.getcwd(),  "templates"),
       static_path=os.path.join(os.getcwd(),  "static"),
       debug=True, # ファイルの更新の自動同期機能等が有効となる
    )


def main():
    port = 10000
    app = httpserver.HTTPServer(make_app())
    app.bind(port)
    app.start(1)  # CPU数. 0:全てのCPU 
    ioloop.IOLoop.current().start()

また簡易なテンプレートエンジン*1も備えており、下記のようなテンプレートの使い回しが可能です.

<html>
   <title> {% block title %}裏入社式プロジェクト 2017{% end %} </title>

   {% block ext_block %}
   <p> デフォルトの表示  </p>
   {% end %}
</html>
{% extends "base.html" %}

{% block title %}Viewモード{% end %}

{% block ext_block %}
  <p>Hello world!</p>
{% end %}

MySQLにおける地図のハッシュIDの生成

今回サービスを構築する上で GETリクエストのパラーメータに ハッシュIDごとに地図を表示/編集します.

例えば、以下のようなURLを発行します

https://[endpoint]?id=7ae63asofmkl23iord

今回、重複がないような新しいハッシュ値の発行をMySQLだけで実現しました. やり方としては、新しいレコードをINSERTするときのAFTER トリガーに 以下のようなSQLを発行し これを各種データと関連づけただけになります

INSERT INTO ura2017_map_hash (map_id, hash) 
VALUES (NEW.map_id, MD5(NEW.map_id))

UNIQUE制約を設けておくことで, 重複する場合には新しいINSERTは失敗します.

裏入社式を終えて

今回の裏入社式が新卒メンバーでの初めてのチーム開発となりました。新卒だけでチームを組み、企画から開発までみんなで行うといった経験はなかなかできるものではなく大変貴重な機会でした。この行事を通して新卒同士はもちろん、普段喋れないような社員さんたちとも深く交流することができ、多くのことを学ばせていただくことが出来ました。裏入社式がRettyの伝統となり、来年以降も続いていくと面白いですね!

*1:tornado.templateに具体的な仕様・利用例があります.