Diverse developer blog

株式会社Diverse(ダイバース) 開発者ブログです。

🔰 JanusGraphのチュートリアル「GraphOfTheGods」をローカルに構築する

これはなに

  • JanusGraphとはオープンソースのGraphDBです
  • 今回はGraphOfTheGods(神々のグラフ)を使って、GraphDBをローカルで試す方法を紹介します
  • この内容は主に https://docs.janusgraph.org/ の公式情報を日本語で簡略化したものです
  • GraphDBに興味のある方は絶賛採用中なので、こちらのブログも参照してください!

🤝 恋愛を「友だちの繋がり」で技術的に支援するサービスのバックエンド開発に力を貸してください! - Diverse developer blog

GraphOfTheGodsとは

GraphOfTheGods(神々のグラフ)はJanusGraphが公式で紹介している代表的なチュートリアルです。文章で説明するより、公式サイトの図を見る方が理解しやすいので、下記にその図を引用します。

GraphOfTheGods(神々のグラフ)の図
f:id:kurotyann:20210622142719p:plain https://docs.janusgraph.org/getting-started/basic-usage/

図によれば、hercules(ヘラクレス)の父はjupiter(ゼウス)で母はalcmene(アルクメーネー)です。そして、herculesはhydra(ヒドラ)とギリシャのサロニコス湾付近(北緯37.7 東経23.9)で戦っています。人間関係だけでなく、出来事までデータが関連しています。GraphDBの特徴を理解できる素晴らしいチュートリアルです。

セットアップ

1. Docker

まずはDocker Desktopをローカルにインストールします。https://docs.docker.com/get-docker/ から対応するプラットフォームを選んでインストールしてください。以後、ここからはMacで説明を進めます。

Docker Desktopをインストールできたら、Docker DesktopからDockerを起動してください。

2. janusgraph-docker

docker専用のJanusGraphのリポジトリをローカルにクローンします。

$ git clone git@github.com:JanusGraph/janusgraph-docker.git

3. コンテナを起動

janusgraph-dockerのmasterブランチで下記のコマンドを実行します。

$ docker run --name janusgraph-default -p 8182:8182 janusgraph/janusgraph:latest

しばらくすると、下記のコンテナとイメージが作成されます。

Docker Desktopで見えるコンテナとイメージ
f:id:kurotyann:20210622143919p:plain

4. Gremlin Consoleに接続

ターミナルで操作している場合、もう一つ別のタブを開いてjanusgraph-dockerのmasterブランチで下記のコマンドを実行します。

$ docker run --rm --link janusgraph-default:janusgraph -e GREMLIN_REMOTE_HOSTS=janusgraph --name gremlin-console -it janusgraph/janusgraph:latest ./bin/gremlin.sh

実行すると、Gremlin Consoleが起動するので、ターミナルからGraphDBにクエリを実行することが可能になります。

$ docker run --rm --link janusgraph-default:janusgraph -e GREMLIN_REMOTE_HOSTS=janusgraph -it janusgraph/janusgraph:latest ./bin/gremlin.sh
Jun 22, 2021 3:42:27 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.

         \,,,/
         (o o)
-----oOOo-(3)-oOOo-----
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/janusgraph/lib/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/janusgraph/lib/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
plugin activated: tinkerpop.server
plugin activated: tinkerpop.tinkergraph
03:42:32 WARN  org.apache.hadoop.util.NativeCodeLoader  - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
plugin activated: tinkerpop.hadoop
plugin activated: tinkerpop.spark
plugin activated: tinkerpop.utilities
plugin activated: janusgraph.imports
gremlin>

ここでGremlinという聞き慣れない名前が出ました。Gremlinとはグラフデータベース操作言語です。RMDBのSQLと似たようなものです。詳細な説明はこちらのサイトを参照してください。

5. GraphOfTheGodsをロードする

起動したGremlin Consoleに下記のコマンドを実行して、GraphOfTheGodsのデータをロードします。今回はGremlinをすぐに実行してデータ構造を理解するために、インデックス無しでデータをロードします。

gremlin> graph = JanusGraphFactory.open('conf/janusgraph-inmemory.properties')
==>standardjanusgraph[inmemory:[127.0.0.1]]
gremlin> GraphOfTheGodsFactory.loadWithoutMixedIndex(graph, true)
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[standardjanusgraph[inmemory:[127.0.0.1]], standard]
gremlin>

これでGraphOfTheGodsのデータがローカルで確認できるようになりました。

クエリを実行してみる

1. 簡単なクエリ

まずはGraphOfTheGodsのデータが正しくロードされたのか確認します。

gremlin> g.V().count()
04:19:21 WARN  org.janusgraph.graphdb.transaction.StandardJanusGraphTx  - Query requires iterating over all vertices [()]. For better performance, use indexes
==>12
gremlin>

g.V().count() とは、頂点(vertex)の数です。最初の図で言うと、赤丸の数と同じです。RMDBだと行みたいなものです。さらにデータを見てみましょう。

gremlin> g.V().values('name')
04:26:52 WARN  org.janusgraph.graphdb.transaction.StandardJanusGraphTx  - Query requires iterating over all vertices [()]. For better performance, use indexes
==>sky
==>hydra
==>cerberus
==>neptune
==>alcmene
==>jupiter
==>pluto
==>sea
==>saturn
==>hercules
==>nemean
==>tartarus
gremlin>

それぞれの頂点から name プロパティを取得しました。神やモンスターや場所の名前が一覧で出てきましたね。 より詳細に確認するならスキーマを見ると良いでしょう。

gremlin> mgmt = graph.openManagement()
==>org.janusgraph.graphdb.database.management.ManagementSystem@62b09715
gremlin> mgmt.printSchema()
==>------------------------------------------------------------------------------------------------
Vertex Label Name              | Partitioned | Static                                             |
---------------------------------------------------------------------------------------------------
titan                          | false       | false                                              |
location                       | false       | false                                              |
god                            | false       | false                                              |
demigod                        | false       | false                                              |
human                          | false       | false                                              |
monster                        | false       | false                                              |
---------------------------------------------------------------------------------------------------
Edge Label Name                | Directed    | Unidirected | Multiplicity                         |
---------------------------------------------------------------------------------------------------
father                         | true        | false       | MANY2ONE                             |
mother                         | true        | false       | MANY2ONE                             |
battled                        | true        | false       | MULTI                                |
lives                          | true        | false       | MULTI                                |
pet                            | true        | false       | MULTI                                |
brother                        | true        | false       | MULTI                                |
---------------------------------------------------------------------------------------------------
Property Key Name              | Cardinality | Data Type                                          |
---------------------------------------------------------------------------------------------------
name                           | SINGLE      | class java.lang.String                             |
age                            | SINGLE      | class java.lang.Integer                            |
time                           | SINGLE      | class java.lang.Integer                            |
reason                         | SINGLE      | class java.lang.String                             |
place                          | SINGLE      | class org.janusgraph.core.attribute.Geoshape       |
---------------------------------------------------------------------------------------------------
Vertex Index Name              | Type        | Unique    | Backing        | Key:           Status |
---------------------------------------------------------------------------------------------------
name                           | Composite   | true      | internalindex  | name:         ENABLED |
---------------------------------------------------------------------------------------------------
Edge Index (VCI) Name          | Type        | Unique    | Backing        | Key:           Status |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
Relation Index                 | Type        | Direction | Sort Key       | Order    |     Status |
---------------------------------------------------------------------------------------------------
battlesByTime                  | battled     | BOTH      | time           | desc     |    ENABLED |
---------------------------------------------------------------------------------------------------

gremlin>

なんとなくデータの構造が見えてきますね。 いくつかの簡単なクエリで、データがロードされてることが確認できました。

2. 任意のデータ(vertex)だけ取り出す

もう少しクエリを実行してみます。

gremlin> g.V().has('name', 'jupiter').values('age')
==>5000
gremlin>

jupiter(ゼウス)の年齢を取得しました。5000歳です。今度はjupiterの頂点(vertex)そのものを取得してみます。

gremlin> jupiterV = g.V().has('name', 'jupiter').next()
==>v[4208]
gremlin> g.V(jupiterV).valueMap()
==>[name:[jupiter],age:[5000]]
gremlin>

少し複雑になってきました。 g.V().has('name', 'jupiter') はjupiterを指定して .next()jupiterV に入れました。このように変数へ代入するような書き方が、グラフDBでは一般的な書き方のようです。公式では、これを「エントリーポイントを指定する」と表現しています。

The typical pattern for accessing data in a graph database is to first locate the entry point into the graph using a graph index. That entry point is an element (or set of elements) — i.e. a vertex or edge. https://docs.janusgraph.org/getting-started/basic-usage/#global-graph-indices

3. 関係(edge)をたどる

グラフDBの強みであるデータ同士の関係をたどってみます。

gremlin> g.V(jupiterV).out('father').values('name')
==>saturn
gremlin> g.V(jupiterV).in('father').values('name')
==>hercules
gremlin> 

jupiter(ゼウス)を起点に考えます。jupiterの父はsaturn(サートゥルヌス)です。さらに、hercules(ヘラクレス)の父はjupiterです。上記の図で言うと、outin がjupiterに関係する矢印の向き(関係= edge)と対応しています。そして、saturnはherculesの祖父であり、herculesはsaturnの孫とも言えます。この関係をクエリで書くと以下のようになります。

gremlin> saturn = g.V().has('name', 'saturn').next()
==>v[4336]
gremlin> hercules = g.V(saturn).repeat(__.in('father')).times(2).next()
==>v[8432]
gremlin> g.V(hercules).valueMap()
==>[name:[hercules],age:[30]]
gremlin>

saturnを起点にして、孫のherculesのプロパティを取得して表示しました。

終わりに

チュートリアルをなぞっただけですが、これで自分のPCにGraphDBのデータベースを構築できました。興味のある方はローマ神話とGraphDBを学べるお得なチュートリアルなので是非トライしてみてください。最後に、Gremlin Consoleを閉じておきましょう。

gremlin> :exit

しかし、実際にサービスで利用するには、チュートリアルだけでは終われません。任意の初期データの投入や、各種クラウドサービスとの連携などが必要です。

次回はGraphOfTheGodsではなく、任意の初期データの投入してGremlin Consoleを起動して接続する方法を紹介します。

もし、このようなGraphDBに興味のある方は絶賛採用中なので、下記のブログも合わせて読んで応募してください!

developer.diverse-inc.com

🤝 恋愛を「友だちの繋がり」で技術的に支援するサービスのバックエンド開発に力を貸してください!

これはなに

  • LINEの友だちを活用して恋人を見つけるサービス(HOP)のバックエンド開発について紹介します。
  • GraphDBを利用して「友だちの友だち」や「友だちの友だちの友だち」などの人間関係を構築しています。
  • 現在、この「友だちの繋がり」の改善に協力してくれる新たなエンジニアを探しています!!

技術から見た「友だちの繋がり」

「友だちの繋がり」をクライアント(iOS,Android)に提供するバックエンドは以下の構成になっています。HOPでは基本的にFirebaseを利用し、Firebaseで賄いきれない機能(友だちの繋がり)をAWSで補完する構成になっています。gRPCなどのコードはGoで書かれています。

HOP Backend
f:id:kurotyann:20210603115041p:plain

そして、クライアントの画面がこちらです。LINEの友だちを活用して恋人を見つけるサービスのイメージがざっくりと掴めると思います。

HOPの探すと繋がりの画面
f:id:kurotyann:20210603115848p:plain

「友だちの繋がり」を表現する技術的なおもしろさ

HOPはリリース当初から「友だちの繋がり」を表現するために技術的リソースを多く割いてきました。 これは、「友だちの繋がり」がHOPが提供するサービスの重要な価値になると考えていたからです。

しかし、「友だちの繋がり」の表現は一筋縄ではいきません。主にプライバシーを守るために多くの要件を考慮に入れる必要があります。また、HOPを開発するに当たり性能劣化の問題にも直面しました。

GraphDBは2hop, 3hop, 4hopとGraphのhop数(友だち同士の距離)が増すにつれ、処理数が指数関数的に増大します。多くの課題を乗り越え、実現可能な方法を提供するところにも技術的難しさとおもしろさがあります。

どうして新メンバーが必要なのか

上記の構成を開発したメンバーが抜けたことで、AWSやGraphDBを専任するメンバー(バックエンドのエンジニア)がいないからです。

先程書いたように、HOPのバックエンドはほぼFirebaseで構成されています。一方、「友だちの繋がり」は運用コストを抑えるためマネージドなGraphDBであるNeptuneを利用しています。したがって、「友だちの繋がり」を除けばエンジニアのリソースは十分にあります。

しかし、さらにサービスを発展させ、他社のサービスとの差別化を図る上で「友だちの繋がり」は増々重要な機能になっています。ここに注力したく、新しいメンバーを探しています。

どのように改善したいのか

現在、3つの改善パターンを想定します。

  • ① 現在の構成を維持しつつ改善する(AWSパターン)
  • ② JanusGraphとBigTableで新たな基盤を構成する(GCPパターン)
  • ③ 上記以外の改善策(その他)

①AWSパターンと、③その他については違和感のない改善案だと思います。では、なぜ②GCPパターンを想定するのか。それは他の技術との親和性を考慮したいからです。

HOPは良くも悪くもGoogleのサービスに強く依存しています。クライアントではFlutterを利用し、バックエンドはFirebase、各種GCPのサービスも多数利用しています。一方、AWSに強いメンバーは不足しています。

もし、「友だちの繋がり」をGCPパターンに移行できれば、既存メンバーの技術スタックを活かしつつ、ツールを集約してスピーディーな開発が可能になります。現在、この構成の技術検証を須藤(id:kurotyann, @kurotyann9696)が1人で行っています。近日、この技術検証の過程をこのTechブログに公開予定です。

GraphDBの経験は問いません。AWSやGCPなどの各種クラウドサービスの運用経験のあるバックエンドエンジニアの方、一緒に「友だちの繋がり」を開発してみませんか?

少しでも興味のある方は、弊社採用ページや私のTwitterへ連絡 ストクロ (@kurotyann9696) | Twitterでも構いません。興味のある方、お待ちしています!

「Flutterをきっかけに、前向きな人が仲間になってほしい」リードエンジニアが語る、Flutterの導入とこれから。

f:id:diverse-tech:20210518154911j:plain

エンジニア界隈で注目を浴びているアプリ開発ツールFlutter。 少し前ですが、2019年に当社はFlutterを 「youbride」に導入し、運用を開始しました。

当時はFlutterを用いたプロダクト実装の 運用事例が少なく、 導入までには約1年の歳月を要しました。

今回は、Flutter導入プロジェクトの 中心となったエンジニア・菊池さんに

  • 導入までの経緯

  • Flutterのメリット

  • 今後の展望

について聞きました!

f:id:diverse-tech:20210518155314j:plain

慢性的なリソース不足を解消できる「使い勝手の良さ」が決め手

ーFlutter導入までの経緯を教えてください。

菊池:もともと、Flutter導入のきっかけは「開発チームのリソース不足」です。エンジニアが3名、デザイナーが2名対して圧倒的に業務量が多かったんです。これを何とか解消したいと。そこで、効率化のためのフレームワークを探していました。 業務量が多い理由の1つが、プラットフォームが複数存在し、それぞれのフロントエンドのコードベースが別れていたことです。

1つの機能を追加する場合、ウェブサイト(PC用・スマホ用・ガラケー用※当時、現在は閉鎖)、iOSアプリ、Androidアプリの全てに開発の手を入れる必要がありました。 当然、それに付随してデザインにかかるコストも増えます。コードベースを一元化し、複数のフォームファクタに対応することが最大の課題でした。

もちろん、Flutter以外にも導入候補はありました。PWAとReactNativeもそれぞれコードベースの統合は可能でしたが、マッチングアプリ、というプロダクトに照らした時に不適でした…。

ー最初からFlutter一本で候補を絞っていた訳ではないのですね?

菊池:そうですね。最初からFlutterの採用を決めていた訳ではありませんでした。最有力候補だったのはPWAで、メンバーの期待も大きかったのですが、iOSへはプッシュ通知を送信することができない、というマッチングアプリとしては致命的な制限があり、やむなく却下に……。

PWAを候補から除いてしまうと、当時はウェブサイトのコードは統一できませんでした。そこで、iOSとAndroidのアプリを一本化して、マッチングアプリとしての機能も維持できる。この2つの要素が不可欠です。そしてその両方を高い水準で満たすのがFlutterだ、という結論に至りました。

今では大手アプリでも採用されているFlutterですが、導入を決めた2018年当時、日本だとCARTUNEさんくらいしかプロダクション採用事例は無かったです(笑)

海外では中国のテンセントが使用していることを知り、それならやってみよう、方向性が固まりFlutterの導入が決まりました。

f:id:diverse-tech:20210518154959j:plain

生産性と品質管理の向上へ繋がった

ーFlutter導入する際に苦労した点などはありましたか?

菊池:当時、Flutterの日本での導入事例が限りなく少なかったので、手探りで進めていった部分はありましたね。Flutterは新しいツールなので、バグや不具合なども発生するんです…(笑) その辺りをチームで確認しながら、問題点を洗い出していきました。

ちなみに、Flutterは「Dart」という言語を使用するのですが、公式のLanguage Tourはかなり丁寧で、「この言語を読み解いていくのはすごく簡単だな」という所感でしたね。昔からエンジニアをやっていて、JavaとJavaScriptがわかるのであれば、Dartは1日学習すればある程度は読み書き出来ます。ストレスなく扱いやすい点も、Flutterの良さのひとつだと思います。

ー新しいツールだけど、そこまで構える必要はない、と言うことなんですね。 実際、導入後のメリットはどこにあると思いますか?

菊池:メリットは、リソース不足の改善につながったことです。1つのプロダクト開発にかかる時間的コストも大きく下がりました。Androidアプリの新規開発をする場合を例にすると、Flutterを使用せずに開発した場合と比べて1~2割ほど時間が削減されるのではないでしょうか?

Flutterは、宣言的UIを採用しているため、従来のアプリケーションよりもUIを組み易くなっています。1つの機能を実装する場合、違うプラットフォームであっても、同じ機能を提供しなければならないのですが、その時も別々に作り込むより開発は楽ですし、統一感を持たせることもできます。

特にマッチングアプリは、メンバーさんが「使いやすい仕様であること」がマスト。その点、Flutterは欲しい機能、必要な機能をつくり込むのも簡単にできますし、自由度が高いです。

また、ひとつのコードで動いているので、試作や品質管理をする際に確認が楽になったことも大きいですね。コードベースの一元化は、管理側のコストを下げることにもつながる。これは、運用して初めて分かりましたね。

f:id:diverse-tech:20210519134600j:plain

Flutterと言えば、Diverse

ー今後もFlutter導入が予定されているのですか?

菊池:当社は、企業としてもエンジニアにしても、Flutter導入にかなり前向きなこともあり、他にもFlutter導入を進めているアプリケーションがあります。しかし、Flutterにすべて置き換える、ということにはならないと思います。 新規に開発する機能であればiOSやAndroidの画面単位でもFlutterを追加できる「Add-to-app」という機能があるので、部分的な使用は今後も進んでいくかなとは…。

ーチームとしての今後の目標は?

菊池:大きく分けて2つあります。 1つは、Flutterコミュニティを大きく拡大していくことですね。2019年当時に比べて、現在は導入企業も増えてきています。日本でもユーザーのコミュニティがあるのですが、チームとしてはコミュニティに積極的に関わっています。Flutterのプラグインを開発したり、ライブラリにバグの報告をしたり、改善をしたりなど。大きな輪となって、Flutterのより良い活用を見出していきたいですね。

これからコミュニティもまだまだ大きくなっていくでしょうし。海外では大きなカンファレンスが開催されているので、Diverseがミートアップなどを開催できたらいいな、とも考えています。

もう1つは、Flutterに興味を持ち、前のめりになって活動してくれる方が入社してくれることですね。実際、開発チームの渡邉さんは、Diverseは数年前からFlutterを採用していてノウハウがありそうだから、という理由で入社を決めたそうで、今は自分でどんどんいろんなチャレンジをしてくださっています。

新しく、また勢いもあるフレームワークを使った開発に先陣を切って携われるチャンスはそこまで無いと思います。新しいモノが好きなエンジニアさんには、魅力的に映るツールです。

ぜひ、私を含む開発チームのみんなと、Flutterの未来を切り拓いていきたい、なんて大きな野望も持っています(笑)。

f:id:diverse-tech:20210519134627p:plain

菊池さん、ありがとうございました!

Diverseはエンジニアドリブンの精神で、 エンジニアにとって働きやすい開発環境、 はたらき方を積極的に導入しています。

現在は下記の職種を 鋭意募集しています!

herp.careers herp.careers herp.careers

ぜひご興味がありましたら お気軽にエントリーください!

お待ちしております!

【後編】イベント『Flutter開発者必見!あの有名ライブラリの内部実装を解説』を公開します【Meetup #2】

こんにちは!Diverse広報担当です!

先日、Diverse Meetup #2となる『Flutter開発者必見!あの有名ライブラリの内部実装を解説』を開催いたしました。 本ブログではイベントの様子をお伝えしております。 f:id:diverse-tech:20210511121408j:plain

今回は、前編・中編に続いて、いよいよラストの「コードリーディング」の内容をお届けいたします!

【前編】「事前知識の確認」と【中編】「widgetとElementの関係〜providerの登場人物」をまだご覧になっていない方はまずこちらをご覧ください。

developer.diverse-inc.com

developer.diverse-inc.com



▼目次

  • 当日の資料と動画を公開中!
  • 続・イベントルポ大公開【後編】
    • ▼一緒にコードリーディングをやってみよう!(00:10)
    • ▼ChangeNotifierProviderのライフサイクルを追ってみよう!(02:48)
  • さいごに
    • ▼Diverseの情報発信について


続きを読む

【中編】イベント『Flutter開発者必見!あの有名ライブラリの内部実装を解説』を公開します【Meetup #2】

こんにちは!Diverse広報担当です!

先日、Diverse Meetup #2となる『Flutter開発者必見!あの有名ライブラリの内部実装を解説』を開催いたしました。 本ブログではイベントの様子をお伝えしております。

f:id:diverse-tech:20210322093104j:plain

今回は、前編の「事前知識の確認」に続いて、中編の「widgetとElementの関係〜providerの登場人物」の内容をお届けいたします。

【前編】の「事前知識の確認」をまだご覧になっていない方はまずこちらをご覧ください。

developer.diverse-inc.com



▼目次

  • 当日の資料と動画を公開中!
  • 続・イベントルポ大公開【中編】
    • ▼Flutterが管理する3つのツリーとは?(00:00)
    • ▼Elementのライフサイクルについて(03:55)
    • ▼Providerの登場人物(05:20)
  • さいごに
    • ▼次回イベント予告
    • ▼Diverseの情報発信について


続きを読む

【前編】イベント『Flutter開発者必見!あの有名ライブラリの内部実装を解説』の資料×動画を公開します【Meetup #2】

こんにちは!Diverse広報担当です。

先日、Diverse Meetup #2となる『Flutter開発者必見!あの有名ライブラリの内部実装を解説』を開催しました!

f:id:diverse-tech:20210304114916j:plain

diverse.connpass.com

Diverseのリードエンジニアとして活躍する菊池 紘さんがご登壇。
Providerとはそもそも何かという基本の解説から、MultiProviderが何をしているのかコードリーディングしたり、予定の1時間をオーバーするほどの熱気でお話いただきました。

今回は、そんなイベントの様子を前編・中編・後編に分けてお伝えしたいと思います。
まずは前編、事前知識の確認の部分からどうぞ!

▼目次

  • 当日の資料と動画を公開します
  • イベントルポを大公開します
    • ▼Providerとは?(00:00)
    • ▼InheritedWidgetのキホン(03:43)
    • ▼InheritedWidgetを使う(06:36)
  • さいごに
    • ▼次回イベント予告
    • ▼Diverseの情報発信について


続きを読む

【後編】イベント『Cloud Functionsについて開発担当が徹底解説』の資料×動画を公開します【Diverse Meetup #1】

こんにちは!Diverse広報担当です。

先日、Diverse Meetup #1となる『Cloud Functionsを開発担当が徹底解説!』の前半の模様を公開しました!

developer.diverse-inc.com

マッチングアプリHOPの開発に携わる村本 章憲さんがご登壇。Cloud Functionとは何かという基本的内容から、参加者からの高度な質問への回答まで、たっぷり1時間かけてお話いただきました。

こちらの記事では、そんなイベントの後半の模様、主に質疑応答パートを余すところなくお伝えします!

続きを読む