Go関連のことを調べてみた2022年05月29日

Go関連のことを調べてみた2022年05月29日

【gin】goでAPIサーバー

# golangでAPIサーバー
[gin](https://github.com/gin-gonic/gin)というフレームワークを使ってAPIサーバーを建て、CRUD処理を実装します。
プログラム全体は[こちら](https://github.com/shuyaeer/go_api_server)においてあります。

## 環境
MacBook Pro (14-inch, 2021)
Go 1.18.2
gin 1.77

## APIの設計
焼き鳥屋の商品情報を扱うものを想定します。
– 商品一覧の取得
– 単一商品の取得
– 新商品の登録
– 在庫情報の変更
– 商品の削除

これらを実装します。

## ディレクトリとファイル類を作成
“`bash
$ mkdir go_api_server
$ cd go_api_sever
$ touch main.go # プログラムを書くファイルを作成
$ go mod init go_api_server # モジュールを管理するファイルを作成
$ go mod tidy
“`

使用する外部モジュールであるginもこ

元記事を表示

「STEP UP GO」第1回イベントレポート

# 導入

2022年5月28日開催の __「STEP UP GO」__ というメルカリさん主催の学生・第二新卒向けのイベントに参加させていただきました。

5月から7月にかけて行われる全3回の勉強会の第1回では、
前半でGolangの基本情報をメルカリのtenntennさんに紹介していただきつつ、
後半ではメルカリUSに所属されているNSEGAさんとのパネルディスカッションを拝聴しました。

Qiitaの記事にするほど綺麗にまとめられているわけではないですが、
自分が知って勉強になったことなどをメモ書き程度に書き留めておこうと思います!

# 学び
インプットは良質なアウトプットするために行う。
勉強をやみくもにするのではなく、アウトプットが前提にあるべきということを再確認した

# Goについて

* 使っていないimport宣言を許していないのは、ビルドが遅くなる要因を排除する目的があるから
* なんで許さないのか → 開発のスケールしやすくなることをGo自体が目指しているから。
* 言語ごとの開発の背景を学ぶべきである
* 「Goに入ってはGoに従え」

*

元記事を表示

VSCodeを開いたときのgoplsのmoduleに関するエラー

# 環境
Go1.18.2

# 経緯
VSCodeで複数のモジュールを含むworkspaceを開いたときに下記のエラーが表示される

# エラー

“`err
gopls requires a module at the root of your workspace. You can work with multiple modules by opening each one as a workspace folder. Improvements to this workflow will be coming soon, and you can learn more here: https://github.com/golang/tools/blob/master/gopls/doc/workspace.md.
“`

# 解決策
https://github.com/golang/tools/blob/master/gopls/doc/workspace.md#go-workspaces-go-118

を見てくれとあるので確認すると

workspaceのrootディレク

元記事を表示

moqを触ってみる

# はじめに

Goのテスト用モック生成ライブラリ `moq` を触ってみたので紹介したいと思います。

https://github.com/matryer/moq

モック生成は今まで `gomock` しか使ったことが無かったので、gomockとの違いについても見ていきます。

https://github.com/golang/mock

# バージョン

– moq: `v0.2.7`

# 使ってみる

紹介したコードは以下のリポジトリにまとめています。

https://github.com/Syuparn/moqexample

`go generate` でインターフェースからモックが生成されます。

“`go
//go:generate moq -fmt goimports -out employee_moq_test.go . EmployeeRepository

type EmployeeRepository interface {
Get(ctx context.Context, id EmployeeID) (*Employee, error)
}
`

元記事を表示

VRChatでOSCを使ってケモ耳をアナログ時計にした

# はじめに
アバターの耳をアナログ時計にしてみたかったのでしてみました。簡単に手順を紹介します。各種用語の説明についてはリンク先をご覧ください。
# できたもの
アホ毛を引っ張ると両耳で時刻を教えてくれます。アホ毛を固定するとそのまま時刻を表示しつつけ、元の位置に戻すと解除されます。

# 誰向け
– このアホ毛耳時計がどうやって実現されているのかなんとなく知りたい人
– [Avatars 3.0](https://docs.vrchat.com/docs/avatars-30)と[PhysBones](https://docs.vrchat.com/docs/physbones)がちょっとわかる人
– Animatorを組むときにWriteDefaultsの挙動がちょっとわかってる人向け
– [Write Defaults on States](https://docs.vrchat.com/doc

元記事を表示

APIGateway+Lambdaでミドルウェアを使う

# 背景

Go言語でlambdaを使ってサービス提供するときに、複数エンドポイント共通の処理を入れたくなった。
各エンドポイントに共通の処理を書き込むと、可読性が下がるためミドルウェアとして実装してみた。

参考:
https://github.com/mefellows/vesper
https://github.com/aws/aws-lambda-go/blob/main/lambda/handler.go

# 前提

`APIGatewayProxyRequest`と`APIGatewayProxyResponse`を利用している。

# 実装

いろいろと既存実装の制約あって`reflect`を利用してごちゃごちゃしているけど、実行速度考えたらできる限り`reflect`使わないで、エンドポイントのハンドラーの引数を`APIGatewayProxyRequest`、戻り値を`APIGatewayProxyResponse`に限定してあげた方がいいかも。

“` go
type LambdaFunc func(context.Context, events.APIGate

元記事を表示

【Go】OpenAPI Generatorでコード生成時modelにCustom Struct Tagを出力する

## 概要
Goには、OpenAPIで定義したyamlをコード出力するツールがあります。概要については[OpenAPI GeneratorでGoのAPIサーバー/クライアントコードを自動生成する](https://qiita.com/saki-engineering/items/b20d8b6074c4da9664a5)の記事で、解説されています。
出力するコードにはmodelのstructも含まれるのですが、例えば[Ginでバリデーションを使ってみる](https://k01ken.hatenablog.com/entry/2021/07/14/234834)で紹介されているような、Custom Struct Tag(ginだと`binding`)を、出力したいという場合もあると思います。
今回は、OpenAPIでCustom Struct Tagを出力したい場合どうするかというのをメモ書きします。

## 対応方法
[goswaggerのCustom extensions](https://goswagger.io/use/models/schemas.html#custom-ex

元記事を表示

Go の sort.Slice でソートできない

# 現象

sort.Slice の第二引数の結果を、第一引数のスライス以外から算出すると、ソートが期待通りに動かない。

“`go
sort.Slice(dates, func(i, j int) bool {
return times[i].Before(times[j])
})
“`

### 具体例

文字列の日付のスライスをソートを行いたいとします。
ソート処理には sort.Slice を使用します。

“`go
dates := []string{
“2022-05-02”,
“2022-05-03”,
“2022-05-01”,
}

times := make([]time.Time, len(dates))
for i, date := range dates {
d, err := time.Parse(“2006-01-02”, date)
if err != nil {
retur

元記事を表示

GoのゲームエンジンEbiten向けのステートマシンライブラリを作った

# はじめに
Go言語のゲームエンジン[Ebiten](https://ebiten.org/)という薄いライブラリがあります。
しかし、Unity等と違いシンプル・コンパクトにまとまっている思想のため最低限の機能しかなく、シーン管理や状態管理等は自分で実装しなければなりません。
そのため今回、Ebiten向けのステートマシンライブラリを作りました。

# 成果物
[PenguinCabinet/pgfsm](https://github.com/PenguinCabinet/pgfsm)

[awesome-ebiten](https://github.com/sedyh/awesome-ebiten#frameworks)にも載っています。
[issueで丁寧にレビューしてくださった sedyhさん、ありがとうございます](https://github.com/sedyh/awesome-ebiten/issues/2)

# 使い方
チュートリアルをもとに、少し使い方を紹介させていただきます。

詳しくは公式[チュートリアル](https://github.com/Penguin

元記事を表示

【Go】Ginの.IndentedJSONと.JSONの違い

# 概要

GinでAPIを開発するチュートリアルをWeb上で探すと色々出てくるが、JSON形式の文字列をレスポンスとして返す際IndentedJSONメソッドで返している場合とJSONメソッドで返している場合があったため違い何なのか調べた。

# 調査結果

Ginのドキュメントから引用(Google翻訳かけてます)

https://github.com/gin-gonic/gin/blob/master/context.go

JSONメソッド
> JSONは、指定された構造体をJSONとして応答本文にシリアル化します。
また、Content-Typeを「application/json」として設定します。

IndentedJSONメソッド
> IndentedJSONは、指定された構造体をきれいなJSON(インデント+エンドライン)として応答本文にシリアル化します。
また、Content-Typeを「application/json」として設定します。
警告:きれいなJSONを印刷すると、CPUと帯域幅がより多く消費されるため、これは開発目的でのみ使用することをお勧めします

元記事を表示

gRPCのstream方式でファイルアップロード処理を実装する

# はじめに
マイクロサービス方式の開発で選定されることが多いgRPCを用いてクライアントからのファイルアップロード処理を実装してみました。

# gRPCの通信方式

* Unary RPCs
シンプルな通信方式。1つのrequestに対して1つのresponseが返ってくる方式になります。gRPCの通信方式の中で一番REST方式に近いものになると思います。
* Server streaming RPCs
クライアントからの1つのrequestに対して、サーバーから複数のresponseを返すことができる通信方式になります。サーバーからクライアントに向けてサイズの大きいファイルなどを送信したい場合に使うことが多いと思います。
* Client streaming RPCs
クライアントからの複数のrequestに対して、サーバーから1つのresponseを返す通信方式になります。クライアントからサーバーに向けてサイズの大きいファイルなどをアップロードする際に使うことが多いと思います。
* Bidirectional streaming RPCs
クライアントからの複数のreques

元記事を表示

【Go】GinでURLからパラメーターを受け取る2つの方法

# 概要

Ginを使用したAPI開発などでURLからパラメーターを受け取る際、
パラメーターの種類によって受け取り方が異なるのでまとめました。

クエリパラメータ
`http://example.com/user?id=123`

パスパラメータ
`http://example.com/user/123`

# 受け取り方

“`go:クエリパラメータの場合
router.GET(“/user”, func(ctx *gin.Context) {
id := ctx.Query(“id”)
})
“`

“`go:パスパラメータの場合
router.GET(“/user/:id”, func(ctx *gin.Context) {
ctx.Param(“id”)
})
“`

以上です。

元記事を表示

並行実行するテストで環境変数を設定しているコードを指摘するGoの静的解析ツールを作った

本記事では、自分が静的解析の勉強のために作成したツール`parallelenv`の紹介をします。

## 並行実行するテストでは、環境変数を設定してはいけない
Go1.17より、テストごとに環境変数を設定するためのメソッドとして`testing`パッケージに`t.Setenv`が追加されました。Go1.17以前ではテストが終了しても環境変数が破棄できない`os.Setenv`を使用するほかなかったため、かなり便利になりました。

“`go
// v1.17以前
err := os.Setenv(“LANGUAGE”, “go”)

// v1.17以降
t.Setenv(“LANGUAGE”, “go”)
“`

ここで、**テストで環境変数を使用する上で注意があります。**
`t.Parallel`でテストを並行実行するようにしていると、並列で動作した場合にテスト動作中の環境変数の寿命の扱いが破綻してしまい、参照する環境変数の値がめちゃくちゃになってしまいます。

上記のような想定外の動作を防ぐために、`t.Setenv`の中では一つのテスト関数内で`t.Setenv`と`t.P

元記事を表示

goでChatworkにメッセージを送るサンプル

“`golang
package main

import (
“net/http”
“net/url”
“strings”
)

func main() {
roomID := “xxxxxxxxxx”
apiUrl := “https://api.chatwork.com/v2/rooms/” + roomID + “/messages”
apiToken := “xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”
ChatworkMessagePost(apiUrl, apiToken, “testmessage”)
}

func ChatworkMessagePost(apiUrl, apiToken, message string) error {
values := url.Values{}
values.Set(“body”, message)

req, err := http.NewRequest(
“POST”,
apiUrl,
strings.NewReader(values.Encode()),
)

元記事を表示

【備忘録】Golangでenum風に利用する

### Golangでenum風に利用する。
Golangではenum型が提供されていないため、実装を工夫する事でenum風に利用する事ができます。

“`golang:main.go
package main

import “fmt”

type Animal int

const (
Unknown Animal = iota
Dog
Cat
Horse
Lion
Tiger
Rabbit
)

func (e Animal) Names() []string {
return []string{
“unknown”,
“犬”,
“猫”,
“馬”,
“ライオン”,
“トラ”,
“兎”,
}
}

func (e Animal) String() string {
return e.Names()[e]
}

func main() {
fmt.Printf(“動物の名前は? %+v\n”, Dog)
fmt.Printf(“動物の名前は? %+v\n”, Cat)
fmt.Printf(“動物の名前は? %+v\n”, Ti

元記事を表示

WebTransportでもWarp(超低遅延配信)がしたい!

# 1秒未満の超低遅延配信が見れます
[デモサイト](https://demo-webtrans.tokishirazu.llc/warp-demo/index.html)、最新のChromeでのみ動きます。[Big Buck Burmy](https://peach.blender.org/)をストリームで繰り返し配信しています。
[ソースコード](https://github.com/alivelime/sample_webtransport/tree/master/warp-demo) : サーバー側のソースはGoのみです。(aioquicがやっぱり不安定?) 環境構築周りのファイルはないです

既知の問題
– ビットレートは500kです (GPU付きインスタンスは高いから仕方ないよね)
– 同一のブラウザで複数開くと挙動がおかしくなるかもしれません

gRPCのstream方式でCSV出力処理を実装する

# はじめに
マイクロサービス方式の開発で選定されることが多いgRPCを用いてCSV出力処理を実装してみました。

# gRPCの通信方式

* Unary RPCs
シンプルな通信方式。1つのrequestに対して1つのresponseが返ってくる方式になります。gRPCの通信方式の中で一番REST方式に近いものになると思います。
* Server streaming RPCs
クライアントからの1つのrequestに対して、サーバーから複数のresponseを返すことができる通信方式になります。サーバーからクライアントに向けてサイズの大きいファイルなどを送信したい場合に使うことが多いと思います。
* Client streaming RPCs
クライアントからの複数のrequestに対して、サーバーから1つのresponseを返す通信方式になります。クライアントからサーバーに向けてサイズの大きいファイルなどをアップロードする際に使うことが多いと思います。
* Bidirectional streaming RPCs
クライアントからの複数のrequestに対して、サーバーから複数

元記事を表示

[go入門]Pythonと比べてgoに親しむ[スクレイピング]

# goでスクレイピング

、初見の`go`でスクレイピングプログラムを書いてみます。

## 環境
– MacBook Pro 2021 14inc
– macOS Montrey 12.0
– go version 1.182

## インストール
今回はバージョン管理のことは考えず、`homebrew`でインストールします。

“`bash
$ brew install go
“`

インストール確認

“`bash
$ go version
go version go1.18.2 darwin/arm64
“`

作業ディレクトリを用意したら

“`bash
go mod init ディレクトリ名
“`

を実行しておきましょう。モジュールを使用する際に必要になります。

## 通信部分
スクレイピングの最初の工程はurlからhtmlを獲得することです。
goでは組み込みモジュールの`net/http`が用意されています。

“`go
res, err := http.Get(url)
“`

Pythonなら
“`python
requests.get(

元記事を表示

Lambdaでgoを取り扱う

## Functionを作る

“`handler.go
package main

import (
“context”
“fmt”

“github.com/aws/aws-lambda-go/lambda”
)

type MyEvent struct {
Name string `json:”name”`
}

func tes(ctx context.Context, name MyEvent) (string, error) {
return fmt.Sprintf(“Hello %s!”, name.Name), nil
}
func main() {
lambda.Start(tes)
}
“`

## Zipを作る
– LambdaでGoを扱う場合、go buildしたバイナリファイルをzipにしてLambdaFunctionへアップロードする必要がある

“`
go mod init go-lambda
go get github.com/aws/aws-lambda-go/lambda
go mod tidy
GOOS=linux go bui

元記事を表示

Twitter Oauth1.0認証方法メモ [golang]

## Twitter開発者登録
1. プロジェクト作成
1. アプリ作成
1. API KeyとAPI Secretを控えておく(ドキュメントではConsumer KeyとConsumer Secretと記載されている)
1. Setting画面からOAuth1.0aを有効化する
1. App permissionsを変更する(投稿処理はRead and write)
1. Callback URI/Redirect URLを設定する
1. 認証画面でユーザーが認証実行した後に遷移するURL

## Go言語での実装

### ライブラリのインストール
“`bash:bash
# https://github.com/dghubble/oauth1
go get github.com/dghubble/oauth1
“`

**認証画面URLの生成**
“`go:main.go
import (
“net/url”

“github.com/dghubble/oauth1”
“github.com/dghubble/oauth

元記事を表示

OTHERカテゴリの最新記事