Go歴2年の僕、これまでに使ったライブラリを振り返る

2023/01/26に公開

はじめに

Goを書き始めて早2年の月日が経ちました。
この2年間、業務でもプライベートでもGoばかり書いてきました。

巷でもGoのメリットとして取り上げられることが多いのですが、Goは標準ライブラリがかなり充実していると思います。
言語仕様が貧弱だとかなんとか言われることは多いので、3rdパーティライブラリ(以下ライブラリ)に頼らないと満足のいくコードが書けないと思われる方もいらっしゃるとは思いますが、大体のことは標準で済んでしまうんですよね。
ですが、ややミニマムな言語仕様が故、やや冗長なコードになりがちな処理もあるというのは事実です。ライブラリを使いたくなる場面だってもちろんあります。
そこで本記事では私がこの2年間で使用してきたライブラリを列挙し、ふわっと紹介したいと思います。

Server

gin

  • 多機能なWebフレームワーク
  • ルーティングのグルーピングや、ミドルウェア周りの実装がeasyにできる

https://github.com/gin-gonic/gin

echo

  • gin同様、多機能で、Webサーバー実装時の定型的な処理をeasyに実装できるWebフレームワーク
  • 肌感だが日本語の情報がginよりは少ない気がする

https://github.com/labstack/echo

gqlgen

  • GraphQL サーバーが簡単に立てられる
  • スキーマからリゾルバの自動生成ができて、スキーマ定義に合わせたバリデーションをよしなにやってくれる

https://github.com/99designs/gqlgen

DB

sqlc

  • SQL から Go のコードを自動生成する
  • SQL ファーストなのでORMに有りがちな想定外のクエリが吐かれてバグることが少ないと思う

https://github.com/kyleconroy/sqlc

gorm

  • 多機能かつAPIが非常に抽象的なORM
  • スピード重視でCRUDを実装するのに良いと思う

https://github.com/go-gorm/gorm

xorm

  • 生 SQL 書くのに近い感じのORM
  • 割と薄めなので吐き出される SQL は想像しやすい

https://gitea.com/xorm/xorm

ent

  • Facebook製 ORM
  • スキーマを Go のコードで定義する
  • マイグレーション、CRUD処理はスキーマから自動生成

https://github.com/ent/ent

dynamo

  • aws-sdk-goの DynamoDB 操作のラッパー
  • Marshal系のinterfaceが公開されていてエンコード、デコードの独自実装がやりやすい

https://github.com/guregu/dynamo

redis-go

  • Redis 操作のラッパーです。
  • 取り出した値の文字列受け取り、マッピングのどちらにも対応している

https://github.com/go-redis/redis

SDK

aws-sdk-go

  • AWS の SDK
  • リソースにアクセスする関数は、引数が~Inputで返り値が~Outputの形になっていて、~Outputから欲しい値を取り出すのが結構難しい

https://github.com/aws/aws-sdk-go

stripe-go

  • Stripe の SDK
  • Web API 利用をラップした抽象度の高い関数だけでなく、割と自由が効かせられるような関数も提供されていて拡張性は高い

https://github.com/stripe/stripe-go

minio-go

  • Minioという S3 互換のオブジェクトストレージのSDK
  • S3 へのアクセスにもそのまま使えるのが良い

https://github.com/minio/minio-go

Util

blackfriday

  • Markdownプロセッサ
  • MarkdownからHTMLを吐き出したい場面でお世話になった

https://github.com/russross/blackfriday

lo

  • MapやFilterなどのスライス加工関数をはじめとする便利関数が多数提供されている
  • 3項演算子っぽく書ける関数とかあって面白い
  • ジェネリクス対応

https://github.com/samber/lo

mo

  • 関数型っぽくコーディングできる関数が提供されている
  • メソッドチェーンで数珠繋ぎにして、最後にエラーハンドリングみたいなコードが書ける

https://github.com/samber/mo

do

  • ジェネリクス対応DIコンテナ
  • 依存関係が階層構造になっているオブジェクトも一度定義しておけば、関数一つで簡単に呼び出せる
  • ジェネリック対応で型安全なのが強いです
  • 自動生成コードがないのでコード量も増えない

https://github.com/samber/do

go-funk

  • loと同じくスライス加工関数などの便利関数が提供されている
  • 汎用的に使用できますが、基本的にはinterface{}からの型アサーションが必要
  • ジェネリクス対応は現在進んでいるよう

https://github.com/thoas/go-funk

cli

  • CLIツールを簡単に作ることのできる関数が提供されている
  • 引数とかヘルプが作りやすい
  • 雛形も自動で生成できる

https://github.com/urfave/cli

decimal

  • 固定小数点が扱える
  • 誤差を許容できない厳密な計算時に活躍

https://github.com/shopspring/decimal

zorolog

  • 多機能なロガー
  • JSONログを簡単に組み立てることができる

https://github.com/rs/zerolog

jwt

  • JWT操作関数が提供されている
  • Cognito のIDトークン検証時にお世話になった

https://github.com/golang-jwt/jwt

jenifer

  • Goのソースコード生成を簡単にできる
  • 関数名がソースコードの部品と対応していて、ブロックを組みたている感覚があっておもしろい

https://github.com/dave/jennifer

pp

  • 構造化データをきれいに整形して出力する
  • 色も付けられてデバッグ時に重宝

https://github.com/k0kubun/pp

dd

  • pp同様、構造化データをきれいに整形して出力する
  • Goのソースコードにそのままコピペできる形式で出力できるのが良い

https://github.com/Code-Hex/dd

air

  • ホットリロードしてくれる
  • 設定ファイルはTomlファイル

https://github.com/cosmtrek/air

validator

  • フィールドタグの設定でバリデートができる
  • Webサーバーの受け口でのバリデーションでお世話になった

https://github.com/go-playground/validator

humanize

  • 数値や時間を人間の読みやすい形式に変換する
  • 数値の適切な場所にカンマを入れるのにお世話になった

https://github.com/dustin/go-humanize

now

  • 時刻操作のUtil関数が提供されている
  • 月初取得とか月末取得とか愚直に書くと長くなるような関数が揃っている

https://github.com/jinzhu/now

copier

  • 構造化データのコピーをしてくれる
  • 単純な値の詰め替えをきたくないケースで使える

https://github.com/jinzhu/copier

testify

  • テスト時に便利な関数が提供される
  • assertionの機能が豊富でテストから条件分岐が減る

https://github.com/stretchr/testify

go-mock

  • interfaceからmockを生成してくれます。
  • 期待する引数、返り値の定義もeasyにできる

https://github.com/golang/mock

resty

  • HTTPクライアント
  • リクエストパラメータのセットや、レスポンスのマッピングなど毎回書くと冗長に感じる処理をeasyに書ける
  • 柔軟なリトライ設定も可能

https://github.com/go-resty/resty

golang-lru

  • LRUキャッシュの実装
  • 操作がスレッドセーフなので多数のgoroutineが動くWebアプリで活躍

https://github.com/hashicorp/golang-lru

godotenv

  • .envから環境変数にロードしてくれる
  • 対象のファイルなども自由に指定可能
  • 個人的にはLocal開発は必須

https://github.com/joho/godotenv

dockertest

  • Dockerコンテナの起動、停止がeasyに書ける
  • ユニットテストやE2Eテストでその場限りのDBコンテナを立てる際に活躍

https://github.com/ory/dockertest

uuid

  • UUID生成、パース処理をしてくれる
  • Google製なので大変安心できる

https://github.com/google/uuid

ulid

  • ULID生成、パース処理をしてくれる
  • テスト用に固定のIDを吐き出させることも可能(現在日時の固定も必要)

https://github.com/oklog/ulid

go-linq

  • LINQ の Go 実装
  • 内部実装の遅延評価が勉強になり面白い

https://github.com/ahmetb/go-linq

dataloader

  • FacebookのDataloaderの Go 実装
  • GraphQL のN+1問題解決に役立つ
  • 遅延評価にchannelを使っている実装が面白い

https://github.com/graph-gophers/dataloader

go-cmp

  • 値の比較が柔軟にできる
  • 差分出力がテストや、デバッグ時になどに有用
  • プライベートフィールドの比較をするか否かの指定や、特定のフィールドを無視する設定が可能

https://github.com/google/go-cmp

さいごに

開発を効率よく進める上で車輪の再発明を防ぐのは大変重要なことです。
もちろんなんでもかんでもライブラリを使うのが正義とは思いませんが、ライセンスや提供されている機能に大きな問題が問題がなければ積極的に使っていくべきと僕は考えます。
「Goで〜ができるライブラリってあったけ?」という場面で本記事が誰かの参考になればと思います。

余談ですが、広く使われているライブラリのコードリーディングは言語仕様やデザインパターンの勉強になります。
勉強会の題材や暇つぶしには最適ですので、まだやったことがない方は是非。

Discussion