APIにGolangを導入しました

こんにちは、Cluexの高橋です。

社内で開発を進めているモバイルバックエンドのAPIに初めてGolangを導入しました。

Cluexでは創業から現在に至るまでの3年間、Webアプリケーションの開発にRuby on Railsを使用してきました。 Golangの導入自体はそこまで真新しいものでも無くなりましたが、Golangに関して社内に開発ノウハウはまだなく、Gopherももちろんいません。

そうした状況の中でGolangを導入した理由や、実際にGolangで開発をスタートしてからの事などを、複数に分けて書いていきます。

今回はGolangの導入に至る背景や、導入に際して考慮した事などを簡単にまとめていきます。

公式ブログによると、

1. 簡潔さ

2. 並行処理

3. 処理速度

Golangの盛り上がりを支えているようです。

f:id:cluex-developers:20170428200508p:plain

Go 2016 Survey Results - The Go Blog

本番環境のインフラストラクチャ

実際に本番環境で使用するにあたって、 インフラの構成やデプロイ周りは必ず考慮しなければなりません。

これまで本番環境にはAWSのEC2を使用していましたが、今年の3月にAWSのECSによるDockerでのサーバー運用にインフラを全面移行しました。

cluex-developers.hateblo.jp

Dockerによるサーバー運用に切り替えたことで、従来のEC2での運用に比べてサーバーの運用・管理が楽になりました。

Infrastructure as Codeの浸透

これまでもChefやAnsibleのようなInfrastructure as Codeを導入してインフラの構築を行なっていましたが、 徐々にコードが管理されなくなってしまったり、どうしても障害発生時の急な対応などからサーバー間の環境差異が発生していました。

今回の移行によってサーバー環境も全てDockerfileとyamlによる管理になり、常にコードでインフラ環境を管理するようになりました。

本番環境と開発環境の差異

開発環境も全てDocker及びDocker Composeによる管理にしたことで、コマンド一発でポータブルな開発環境の構築が可能になり、 本番環境との差異も以前に比べて格段に無くすことができていると思います。

本番稼働系も全てDockerで管理している為、別の(新しい)言語に移る時もインフラ構築の障壁が低くなったことがGolangの導入を後押しする大きな要因となっています。

モノリシックサービス化の予兆とマイクロサービス化

これまで運営しているサービスが一つだったということもあり、1つのRailsアプリケーションに全てのソースコードが入っていました。 しかしコードベースが増えていくにつれて全容の把握が難しくなり、エラーやバグを生む温床となっていきます。

複数サービス間での連携を踏まえたサービスの多角化を行う上では、このような状況はより一層好ましくありません。

小さなアプリケーションの集合体として全体のアプリケーションを管理していく為にも、 今回は別アプリケーションとしてAPIのアプリケーションを組むことにしました。

APIとしての実行パフォーマンス

ちょうど今日、バージョン5.1が正式に発表されましたがRuby on Railsは依然として、とても素晴らしいフレームワークです。コミュニティも非常に盛んで、欲しい機能はgemを探せば大体見つかりますし、スタートアップにおけるwebアプリケーション開発には欠かせない、非常に頼もしい存在です。

ですが、今回のようなモバイルバックエンドのAPIだとRuby on Railsはパフォーマンスの面でデメリットが大きくなってきます。 マイクロサービス化していく中で今回のAPIも別アプリケーションにするので、慣れ親しんでいるという理由の他にRuby on RailsAPIを組む大きな理由がそこまでありません。 Rubyだとマルチスレッド処理の実装が大変である故にマルチプロセスで処理を行なったり、メモリの消費量が多くなったりという事がずっと言われており、言語自体の処理パフォーマンスにおいてGolangが良さそうです。

ライブラリ選定

WebアプリケーションフレームワークにはEcho、ORMにはgormを採用しました。

GitHub - labstack/echo: High performance, minimalist Go web framework

GitHub - jinzhu/gorm: The fantastic ORM library for Golang, aims to be developer friendly

またrevelなどフレームワークに入っているようなホットリロードの機能がない為、開発環境にはfreshを使用したホットリロードを行なっています。

GitHub - pilu/fresh: Build and (re)start go web apps after saving/creating/deleting source files.

フレームワーク

Webアプリケーションフレームワークに関しては、APIを構築するということで、フルスタックな機能は必要ありません。 とはいえhttpサーバーとしての機能やルーティングなど、基本的なリクエストとレスポンスの処理はフレームワークに任せたいところです。スター数や更新頻度、issueなども勘案して今回はEchoを選びました。

GolangフレームワークRubyでいうSinatraRailsのような、立ち位置が定まっているフレームワークがまだはっきりしていない状況です。 またirisのような、スター数は多くてもOSSでの開発方針として、一般的な方針とは乖離が大きいフレームワークもあったりします。

ORM

ORMに関しては、現状Golangの主なWebアプリケーションフレームワークにはORMが入っていません。 ORMのライブラリとしてはいくつも候補がありますが、gormはActiveRecordに近い書き方で実装出来るようになっている為、Railsエンジニアも比較的手をつけやすいと思います。

サードパーティパッケージ

フレームワークやORMを含めて、GolangサードパーティのパッケージはGemに比べるとまだまだ発展途上で、似たようなものが乱立している状況です。

下手にアプリケーションに取り込んで後に更新が止まったりしてしまうと、負債となってしまいそうなので、可能な限り少ないライブラリで対応するようにしています。

ライブラリもフレームワークも、別のパッケージに乗り換えやすいようなコードベースへの配慮が必要かと思います。

まとめ

Golangの導入の背景や、導入に際して考慮した点などを簡単にまとめました。

また近いうちに、実際に開発していく上で良かった面や大変だった面などを記事にしていければと思います。