- 1. APIGateway+Lambdaでミドルウェアを使う
- 2. 【Go】OpenAPI Generatorでコード生成時modelにCustom Struct Tagを出力する
- 3. Go の sort.Slice でソートできない
- 4. GoのゲームエンジンEbiten向けのステートマシンライブラリを作った
- 5. 【Go】Ginの.IndentedJSONと.JSONの違い
- 6. gRPCのstream方式でファイルアップロード処理を実装する
- 7. 【Go】GinでURLからパラメーターを受け取る2つの方法
- 8. 並行実行するテストで環境変数を設定しているコードを指摘するGoの静的解析ツールを作った
- 9. goでChatworkにメッセージを送るサンプル
- 10. 【備忘録】Golangでenum風に利用する
- 11. WebTransportでもWarp(超低遅延配信)がしたい!
- 12. gRPCのstream方式でCSV出力処理を実装する
- 13. [go入門]Pythonと比べてgoに親しむ[スクレイピング]
- 14. Lambdaでgoを取り扱う
- 15. Twitter Oauth1.0認証方法メモ [golang]
- 16. google-cloud-go の使ってみた操作まとめ
- 17. LeetCodeのRoman to Integer を解いてみた
- 18. 【備忘録】Golangで日付の操作を実施する。
- 19. GoでCRUD処理のREST APIを作ろう〜Reactを添えて〜
- 20. 自分の得意なプログラミング言語でSymbolブロックチェーンを動かす方法
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 mainimport (
“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 mainimport “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を用いて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 mainimport (
“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言語での実装
**認証画面URLの生成**
“`go
import (
“net/url”“github.com/dghubble/oauth1”
“github.com/dghubble/oauth1/twitter”
)// oauth1のconfig作成
conf := &oauth1.Config{
ConsumerKey: [ConsumerKey],
ConsumerSecret: [Consume
google-cloud-go の使ってみた操作まとめ
前から Google Cloud Storage には興味があったのでラーメンの写真を記録するサービスを作るのに使ってみました。機能ごとにもリンクを貼りますが、ひとまず公式ドキュメントとリポジトリは以下になります。
**実行環境**
“`
go: v1.18
cloud.google.com/go/storage: v1.22.0
“`
https://pkg.go.dev/cloud.google.com/go/storagehttps://github.com/googleapis/google-cloud-go
※ 全体を通してエラーハンドリングは省略しています。
## 事前準備:クライアントの作成
クライアントの作成に使用するため、事前に GCP のアカウント作成と鍵ファイルをダウンロードしておきます。今回はダウンロードした鍵ファイルを引数にとり [WithCredentialsFile] を使用します。(https://pkg.go.dev/google.golang.org/api/option#WithCredentialsFile)
“`
// これ
LeetCodeのRoman to Integer を解いてみた
## LeetCodeを解いた動機
最近転職活動をしているのですが、面接のコーディング試験の出来が良くなくLeetCodeを解くように勧められました。
また個人の課題として開発進捗が遅いことがあって、LeetCodeの答えには擬似プログラミングがあるので合わせて練習したいなと思いました。
## 問題内容
こちら参照
https://leetcode.com/problems/roman-to-integer
## 自分で書いた擬似プログラミング
今回メモを消してしまったため、次回以降記載## 自分で書いたコード
“`golang.go
func romanToInt(s string) int {
symbolArray := map[string]int{
“I”: 1,
“V”: 5,
“X”: 10,
“L”: 50,
“C”: 100,
“D”: 500,
“M”: 1000,
}
var splitS = strings.Split(s, “,”)
returnInt := 0isSkip := false
for i, _
【備忘録】Golangで日付の操作を実施する。
## 日付の操作
“`golang:main.go
package mainimport (
“fmt”
“time”
)func main() {
n := time.Now()// fmt.Println(n.Format(“2006-01-02 15:04:05”))
year := n.Format(“2006”)
month := n.Format(“2006-01”)
day := n.Format(“2006-01-02”)
hour := n.Format(“2006-01-02 15”)
min := n.Format(“2006-01-02 15:04”)
sec := n.Format(“2006-01-02 15:04:05”)
fmt.Println(“year: “, year)
fmt.Println(“month: “, month)
fmt.Println(“day: “, day)
fmt.Println(“hour: “, hour)
fmt.Println(“min: “, min)
fmt.Prin
GoでCRUD処理のREST APIを作ろう〜Reactを添えて〜
# はじめに
– 参考文献にも掲載しています以下記事を自分の勉強用にアレンジしてまとめ直したものになります。こちらの記事の方がハイレベルな実装になっていますが、もう少し簡素化してGoでAPIを作る大枠を理解したいと思ったのが執筆の動機です。そのためフロント側は簡単な説明のみです。ご了承ください。https://dev.classmethod.jp/articles/go-sample-rest-api/
– バックエンド側はDockerを使用していますが、環境構築方法について本稿では触れません。こちらは以下記事をちょろっとカスタムして作っています。
https://zenn.dev/ajapa/articles/443c396a2c5dd1
– 網羅的な説明はしていないので、まずリポジトリをざっと見て処理の流れを追ってもらった上で読み進めていただいた方が読みやすいと思います。README.mdにも起動方法を記載しております。**“`masterブランチ“`は記事よりも手を加えてしまっているので、“`for_qiitaブランチ“`を参照ください。**
https://
自分の得意なプログラミング言語でSymbolブロックチェーンを動かす方法
Symbolブロックチェーンはプログラミング言語を問わずスマートコントラクトが実装できるように設計されています。ところが、現在リリースされているsdkアルファ版はJavascriptとPythonのみサポートです。では、他の言語ではまだアプリ開発できないのでしょうか?と言われればそうでもありません。
**組み込みされたデジタル装置で署名**したかったり、**マルチシグ化した連署者アカウントの署名をサーバ側で機械的に実施**したり、**IoTなどほぼ単一のトランザクションを定期的に実施**したり、複雑なことは必要ないユースケースが実はたくさん眠っているかもしれません。
ここでは、そういった「あとはSymbolブロックチェーンにトランザクション投げるだけなんだが」といった方を対象にトランザクションの作り方を解説します。
なお、トランザクションの送信以外(例えばモザイクの生成やマルチシグの組成など)はウォレットなどを利用して準備する前提で進めます。後記:
Symbol/NEMのコアチームからのSDKについての考え方を転載しておきます。
> 私たちは、コミュニティが(SDKではなく)直