- 1. Goで作成したToDoアプリにRESTful APIを追加してみる
- 2. gomock使っていてimport cycle not allowedになってしまったので self_package フラグで対応した
- 3. go-redisでSADDした時の挙動
- 4. dbpediaの研究 その26
- 5. go-redisでSET 0,-1
- 6. 【Go】goenvを使ってGo1.13.4の環境構築
- 7. go-redisのSMEMBERSの挙動
- 8. Go言語でJSONデータを構造体とのマーシャリング/アンマーシャリングなしにネイティブに操作する
- 9. ぼやきからのアイディア?DeclarativeなGolang API Framework
- 10. golangでの自分のためのお作法まとめ
- 11. pprofのweb viewでパフォーマンス測定
- 12. 構造体のsliceはポインタ定義しない方がハイパフォーマンス
- 13. grpc-gateway enumを含んだリクエスト
- 14. Go言語でディレクトリサーチ
- 15. PostgreSQLへの接続
- 16. Sunriseに参加してきました
- 17. GoでMockを用いてテストする方法
- 18. MacにDockerでGolang環境を作ってみる vol.1 Dockerインストール編
- 19. Wantedly における Go 導入にまつわる技術背景
- 20. protobufのoneofを使う【Go + gRPC】
Goで作成したToDoアプリにRESTful APIを追加してみる
#
[Go x Gin x GORMでToDoアプリを作成してみる](https://qiita.com/hanadaUG/items/0fd5ddc0407c4ab55d0f)で作成したToDoアプリに追加する形で機能拡張や使用したことのない技術を試していきます。
今回はCRUDのRESTful APIを追加します。# 開発環境
– MacBook Pro
– go version : 1.12.9“`terminal:version
$ go version
go version go1.12.9 darwin/amd64
“`# 事前情報
Webフレームワーク : [Gin](https://github.com/gin-gonic/gin)
ORM : [GORM](https://gorm.io/docs)
DB : sqlite3
依存関係管理ツールdep : dep“`terminal:プロジェクト構成
├── Gopkg.lock
├── Gopkg.toml
├── README.md
├── api
│ └── v1
│
gomock使っていてimport cycle not allowedになってしまったので self_package フラグで対応した
## はじめに
[gomock](https://godoc.org/github.com/golang/mock/gomock)を使ってテストモックを管理する際、self_package というフラグを使うことになりました。このフラグに関して利用方法が書いてある記事がネット上に少なかったので書きます。
## Version
“`
$ go version
go version go1.13.1 darwin/amd64
$ cat go.mod | grep mock
github.com/golang/mock v1.3.1
“`## 構成
`domain.go`が`repositories.go`を利用する構成。repositoriesはDBにあるデータとやり取りするためのインターフェースを持っています。
“`
tagservice
├── domain.go
├── domain_test.go
└── repositories.go
“`## やろうとして失敗したこと
自動生成されるモックのファイルを同じ階層に持つのが嫌だったので1
go-redisでSADDした時の挙動
“`go
package mainimport (
“fmt”
“time”
“strconv”
“github.com/go-redis/redis”
)func getRedisClient() (*redis.Client) {
client := redis.NewClient(&redis.Options{
Addr: “localhost:6379”,
Password: “”, // no password set
DB: 0, // use default DB
})
return client
}func main() {
rc := getRedisClient()
ts := strconv.Itoa(int(time.Now().Unix()))
key := “set:
dbpediaの研究 その26
#概要
dbpediaが難解なので、手出してみる。
goで、取得してみた。#サンプルコード
“`
package main
import (
“fmt”
“io/ioutil”
“net/http”
“log”
“net/url”
“strings”
)
func main() {
values := url.Values{}
values.Add(“query”, “SELECT DISTINCT * WHERE { dbpedia-ja:デ・トマソ dbpedia-owl:abstract ?abstract .}”)
values.Encode()
res, err := http.PostForm(“http://ja.dbpedia.org/sparql”, values)
if err != nil {
log.Fatal(err)
}
fmt.Printf(“[status] %d\n”, res.StatusCode)
for k, v := range res.Header {
go-redisでSET 0,-1
“`golang
package mainimport (
“fmt”
“time”
“strconv”
“github.com/go-redis/redis”
)func getRedisClient() (*redis.Client) {
client := redis.NewClient(&redis.Options{
Addr: “localhost:6379”,
Password: “”, // no password set
DB: 0, // use default DB
})
return client
}func setKey(ttl int) {
rc := getRedisClient()
ts := strconv.Itoa(int(time.Now().Unix()))
s
【Go】goenvを使ってGo1.13.4の環境構築
Goはじめよう。
rubyにrbenvあるみたいに
goenvっていうのを入れたらバージョン管理が楽になるらしい。ということで、環境構築はじめましたが一度`go1.11.4`を入れてしまいました。
それから`go version go1.13.4 darwin/amd64`ってターミナルに
表示されるまでにやったことの備忘録。
もしお気づきのことがあれば、コメントいただけると助かります。#### 本トピックの環境
“`
macOS Mojave ver. 10.14.6
Homebrew インストール済
“`#### 参考にしたサイト・記事
– [Go公式](https://golang.org/)
– [goenv installation](https://github.com/syndbg/goenv/blob/master/INSTALL.md)
– [goenvでgoをインストール 〜初心者向け〜](https://qiita.com/yut-kt/items/9f5ac1e788df61f64290)
– [goenvを使ってMacにGo1.12.xの開
go-redisのSMEMBERSの挙動
“`go
package mainimport (
“fmt”
“github.com/go-redis/redis”
)func getRedisClient() (*redis.Client) {
client := redis.NewClient(&redis.Options{
Addr: “localhost:6379”,
Password: “”, // no password set
DB: 0, // use default DB
})
return client
}func main() {
rc := getRedisClient()
//key := “sonzaisurukey”
// ok
key := “sonzaishinaikey”
Go言語でJSONデータを構造体とのマーシャリング/アンマーシャリングなしにネイティブに操作する
#概要
Go言語でJSON データを取り扱う場合、通常は「構造体にアンマーシャリング」→「構造体の状態で計算」→「JSONにマーシャリング」という個人的には面倒だと思われる操作をするのが基本。なので、構造体に都度都度変換するのではなく、JSONで済ませられるならJSONで済ませられるライブラリを使いたい、というのが動機。bitly の go-simplejson というライブラリがあるんだけど、Index や Array の操作、検索には不十分だった(と思った)ので、自分で機能を拡張してみた。
#利用方法
簡単ですが以下に記します。
### ライブラリをクローン“`
% go get github.com/gdaisukesuzuki/go-simplejson
“`### Go言語の中でimport宣言
“`
import (“github.com/gdaisukesuzuki/go-simplejson”
…
)
“`### APIリファレンス
こちらを参照ください
・ https://godoc.org/github.com/gdai
ぼやきからのアイディア?DeclarativeなGolang API Framework
CodeGenに疲れた。
コードからドキュメント起こしてほしい。Swaggoは確かにあるんだけど、ドキュメントコメントで書いちゃったら、コメントと実装の乖離が起きるじゃんって話で、Swagger別に書くのとあんま差分ない。
強いて言えば、SwaggerのYAMLと実装ほど距離が空いてない、てくらい?## こんなふうに書きたい
“`go
package apiimport (
“kyoh86/declarest/decl”
“kyoh86/declarest/declhelper”
)func NewTaskService() decl.Service {
s := decl.Service{
BaseOptions: []decl.Option{
decl.OptionProducer(declhelper.JSONFormatter),
decl.OptionAcceptor(declhelper.JSONFormatter),
decl.OptionDefaultError(declhelper.JSONError),
},
}
golangでの自分のためのお作法まとめ
# 命名規則
– 基本的には、[Effective Go](https://golang.org/doc/effective_go.html#names)に則り記載する。
– 変数やメソッド名は基本的にキャメル・パスカルケースにする。
– ファイル名についてはスネークケースにする。# error handling
– 基本的には、[go blog](https://blog.golang.org/error-handling-and-go)## 参考サイト
pprofのweb viewでパフォーマンス測定
### 概要
pprofでサーバーのパフォーマンス検証する時、
web viewで簡単にボトルネックを特定できます。
### pprofとは
go toolに入っているプロファイラーツール
関数単位でボトルネックになっている処理を特定できます
https://golang.org/pkg/net/http/pprof/
UI上で処理の流れがこんな感じに見れます![pprof.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254185/ee5aa2f6-7b35-c776-4c08-bcd9ab160230.png)
## 使用ツール
1. Go“`
go version
go version go1.13 darwin/amd64
“`2. [graphviz](http://www.graphviz.org/)
dotファイルとかをいい感じに可視化してくれるツール
今回は吐き出されたプロファイルを見やすくしてくれる“` shell
brew install graphviz
構造体のsliceはポインタ定義しない方がハイパフォーマンス
# Goで構造体slice
Goの構造体sliceはいつもポインタで定義していましたが、
要素追加の時毎回allocationが走るので初期化時に構造体のsliceにした方がパフォーマンス的に良いそうです。“` go
package main
import (
“strconv”
“testing”
)
type human struct {
age int
name string
}
func BenchmarkPointerSlice(b *testing.B) {
// 初期化時にslice分のメモリ容量を確保している
people := make([]*human, 0, b.N)
b.ResetTimer()
for i := 0; i < b.N; i++ { people = append(people, &human{ age: i, name: strconv.Itoa(i), }) } } func Ben
grpc-gateway enumを含んだリクエスト
# 概要
grpc-gatewayでenumを含んだリクエストってどのようにすれば良いのだろうか?のメモ## protoファイル
例えば、通知許諾フラグを更新するAPIがあります。“`proto
// ==================== サービス ====================service Notification {
rpc UpdatePermissionFlag(UpdatePermissionFlagRequest) returns (UpdatePermissionFlagResponse) {
option (google.api.http) = {
post: “/api/v1/notification/permission_flag”
body: “*”
};
}// ==================== メッセージ ====================
message UpdatePermissionFlagRequest {
string fcm_registration_t
Go言語でディレクトリサーチ
[学習履歴](https://qiita.com/__init__/items/e0a672f1437badf3eae0)
# はじめに
Go言語で特定のディレクトリ内にあるディレクトおよびファイル名をterminal上に出力する処理を調べた時のメモ。# 関数内呼び出し
ディレクトリサーチプログラムの前に、面白い処理をお見せする。“`main.go
package mainimport “fmt”
func do(start int, end int) {
fmt.Printf(“do(%d, %d) called\n”, start, end)
fmt.Println(start)
if start < end { do(start+1, end) } fmt.Printf("Returning from do (%d, %d) call\n", start, end) } func main() { do(1, 3) } ``` main関数で、do関数を呼び出している。 通常の関数と違う所は、do関数の中で、**do関数自身**を呼び出し
PostgreSQLへの接続
PostgreSQLへの接続を標準の[database/sql]を利用した場合と
ORMのGORMを利用した場合の比較しました。#標準
まずは、標準[database/sql]を利用した場合“`go:main.go
package mainimport (
“database/sql”
“fmt”
“log”
_ “github.com/lib/pq”
)type Sale struct {
Id string
OrderId string
}func main() {
db, err := sql.Open(“postgres”, “postgres://user:pass@host:port/dbname”)
if err != nil {
log.Fatalln(“接続失敗”, err)
}
defer db.Close()// 取得件数を条件[$1]にする
// ?だとエラーが発生
//cmd := “select id, order_id from final_sales where id like $1”
cmd
Sunriseに参加してきました
# Sunriseってなに?
– Voyage Groupさんの大規模サービス構築インターン
– [公式サイト]
(https://voyagegroup.com/internship/sunrise/)# どんなことやったの?
– 計測用のインスタンスを3日間でどれだけリクエストを捌けるように性能を向上させれるかという内容# 印象に残ったこと
– 仮説、検証、考察の一連の業務の流れを体験できた
– ビジネスでは教育現場と違って、新しいこと、興味があることよりも、価値を生み出せることを優先した
– VGさんの実際に業務している時の雰囲気みたいなものを感じることができた# ネタバレ元
– ここに技術的なネタバレ、それ以外のネタバレ両方あるので、注意してください
– [VoyageGroupインターン Sunriseに参加してきました](https://www.slideshare.net/secret/GHN896vPc0gBqp)# 感想
– 楽しかった!!!
– というのも私は技術が好き(多分)で楽しいのでこのサイクルを回すのが楽しくて仕方なかったです
– 逆に合わな
GoでMockを用いてテストする方法
# はじめに
最近GoでMockを用いてテストを行うことが多いのですが,その手法がシンプルで使いやすいので紹介したいと思います.
# 実装
今回はDBからユーザーを全件取得して,指定したユーザーの年齢以上のユーザーのみを抜き取るという処理に対するテストを考えます.(そんなことはDB側で処理すればいいですが,いい例が思いつかなかったので悪しからず)
まずはUserのModel定義をします“`go:user.go
type User struct {
ID int
Name string
Age int
}
“`次にDBに関する実装を行いますが,interfaceとその具体実装の2つに分けて書きます.
“`go:user_db.go
type UserDB interface {
GetAllUsers() ([]User, error)
}type UserDBImpl struct {
}func (db *UserDBImpl) GetAllUsers() ([]User, error) {
// 全Userを返す処理
}
“`ここ
MacにDockerでGolang環境を作ってみる vol.1 Dockerインストール編
DockerもGolangも初心者ですが、とりあえずDockerでGolangを使ってみようと思います。
とりあえず、動かすための環境を作ります。
参考までに環境情報を。
- macOS Mojave(10.14.6)
## 1 Dockerのインストール
Docker for Mac は、以下のURLからGUIでもインストールできます。
でも、~~ちょっとめんどくさいので~~CUIでやってみたいので、CUIで入れてみます。ターミナルで以下のコマンド実行。
### 1.1 Homebrew Cask の確認
Homebrew Cask は Homebrew の拡張機能だそうです。
まずはこれが入っているかの確認。“`
$ brew cask
“`brew cask はGUIでダウンロードするような(chromeとか)を
CUIで入れられるみたい。
※詳しくはこちら参照
https://qiita.com/swallowtail62/items/61244ea3c7d0
Wantedly における Go 導入にまつわる技術背景
(本記事は [Go Conference 2019 Autumn](https://gocon.jp/) にて無料配布した冊子『WANTEDLY TECHBOOK GoCon Edition vol.2』からの掲載です)
配布した冊子の前半では Go の導入にあたってどのような工夫をしてきたのかを紹介しました。そこに書かれていたように、新しいプログラミング言語を導入するにはそれなりの整備コストがかかります。それではなぜそこまでして Go を導入したのでしょうか。本記事では Go を導入した背景について説明していきたいと思います。
## なぜ Go か
### 技術的・事業的背景
どのプログラミング言語を採用するかや、どのようなアーキテクチャを選定するかというようなことは非常に影響範囲の大きい決断になるため、会社全体の技術的・事業的なコンテキストと切り離しては語れません。そこでまずは Wantedly の技術的・事業的な背景について、この後の話をするために必要最低限の部分を紹介したいと思います。
Wantedly というサービスはもともと、一つの Ruby on Rails の
protobufのoneofを使う【Go + gRPC】
[Protocol Buffers](https://developers.google.com/protocol-buffers)のoneofを使って実装しようとしたときに微妙に悩んだので、使用方法を備忘録として残しておきます。
Protocol Buffers、Go、gRpc、どれも触り始めて数ヶ月なので、変な箇所がありましたら指摘していただけると大変助かります。
## oneofとは
あるメッセージで複数のフィールドを定義して、「このフィールドのうち、**最大でどれか1個だけ**がセットされてるよ!」と宣言できる機能です。
“`
message SampleMessage {
oneof test_oneof {
string name = 4;
SubMessage sub_message = 9;
}
}
“`上記のようにメッセージを定義すると、「`SampleMessage`には`name`フィールドか`sub_message`フィールドのどちらかが入っている。どちらのフィールドも入ってない場合もある」ということになります。
ただし、