- 1. [Go][AtCoder] bufio.NewScannerの標準入力でハマったこと 最大サイズ
- 2. AWS App RunnerでGolangのサーバーをサクッと立ててみる
- 3. 【Golang】gqlgen、gin、GORMを使ったプロジェクトテンプレート
- 4. GolangのValidationチェック(go-playground編)
- 5. [Golang] ユニットテストにおける正しい後処理の書き方:t.Cleanup()
- 6. Go言語 + Windows Terminalで、任意の文字にハイパーリンクを埋め込むエスケープシーケンス
- 7. Google Compute Engine の startup script で $ go install と インストールされたバイナリを実行する方法
- 8. Goの静的解析ツールblahbrah
- 9. 0-1ナップサック アルゴリズム
- 10. Go の API をフロントサイドから呼び出す
- 11. Go言語のモジュール実装
- 12. golang-migrateチュートリアル(migration編)
- 13. Herokuでスクレイピングしようとしてハマったこと
- 14. E2D(End to end – 1)の考察
- 15. Golangによるパスワードの保存
- 16. Golang-構造体にあるパスワードなどのセキュリティ情報をログに出力しないようにする方法
- 17. Go言語のerrorにエラー情報を付けて分岐する。
- 18. Goでcrontabのようなツールを作ってデーモン化してみた
- 19. aws-sdk-goでcredentialを指定するには
- 20. wails v2でvueテンプレートを作った手順
[Go][AtCoder] bufio.NewScannerの標準入力でハマったこと 最大サイズ
## 概要
最近Golangを書くことが多くなりました。普段はWeb開発ばかりやってますがそれ以外にも前から競プロに興味がありました。
なのでせっかくなのでGolangで始めてみようかなと思い立った矢先、いきなり問題にハマったのです。ただ学びにもなったので備忘録としてこの記事を書いています。
## ハマってしまった問題
僕がハマってしまった問題は下記です。
問題としては入力文字列を昇順にソートして出力するだけのものでシンプルなものです。
https://atcoder.jp/contests/abc242/tasks/abc242_b
僕の提出回答は下記でした。
一見ACになりそうなのですが、結果としてはWAでした。
やっていることとしては間違っておらずでして、
受け取った文字列からstring型のsliceを作成して1語ずつ格納します。
その後, `sort.Strings([]string)`を使ってsliceを昇順にソートします。
最後は`strings.Join`を用いて文字列を作成して出力で完了です。
でも何が原因でWAになってしまうか分からず、
AWS App RunnerでGolangのサーバーをサクッと立ててみる
# AWS App Runnerとは?
コンテナ化されたWebアプリを簡単にデプロイすることができるサービスです。(裏側ではFargateが使われているらしい)
2021年の5月に登場したサービスなので比較的新しいサービスっぽいです。コンテナを動作させる手段としてはAmazon ECSがありますが、それよりもサクッとサーバーを立てたい時に重宝しそうです。
# 料金体系(@東京リージョン)
以下の3つの要素から構成されます。
1. プロビジョニングされるメモリ ・・・ 0.009USD/GB
2. アクティブなコンテナインスタンスのCPUとメモリ・・・0.081 USD/vCPU + 0.009USD/GB
3. ビルド料金・・・0.005 USD/ビルド時間 (分)1vCPU・メモリ2GB・ビルドなしで1ヶ月アクティブに運用すると、**約70ドル**のコストがかかります。
# 2022年2月のアップデートでVPCのトラフィックがサポートに
リリースノートによるとApp RunnerがVPCのリソースにアクセス可能となったそうです。
https://docs.aws.amaz
【Golang】gqlgen、gin、GORMを使ったプロジェクトテンプレート
# はじめに
Goの学習のためgin、gqlgen、GORMを使ってGraphQLのAPIを作成しました。
備忘のためにプロジェクトのテンプレートとその説明を残します。作成したテンプレートは以下に公開しています。
https://github.com/Ruketa/go-gqlgen-gin-template
# 環境
– Golang バージョン 1.17
– 使用ライブラリ、FW
– Gin : Web Framework : https://github.com/gin-gonic/gin
– Gorm : ORM library : https://github.com/go-gorm/gorm
– Gorm PostgreSQL Driver : https://github.com/go-gorm/postgres
– INI : INI file package : https://pkg.go.dev/gopkg.in/ini.v1
– gqlgen : GraphQL library : https://github
GolangのValidationチェック(go-playground編)
#初めに
GolangでのValidationチェックを実施する記事です。#サンプルコード
“`go:main.go
package mainimport (
“fmt”“github.com/go-playground/validator/v10”
)// User contains user information
type User struct {
FirstName string `validate:”required”`
LastName string `validate:”required”`
Age uint8 `validate:”gte=0,lte=130″`
Email string `validate:”required,email”`
FavouriteColor string `validate:”iscolor”` // alias for ‘hexcolor|rgb|rgba|hsl|hsl
[Golang] ユニットテストにおける正しい後処理の書き方:t.Cleanup()
ユニットテストの**後処理**を行う場合、
`defer`は**並列**で動いている**サブテストの終了を待たずに実行**されてしまう問題がある。
全てのサブテストが終了してから後処理を行たいなら `t.Cleanup()` を使おう。
## **`Defer`による後処理の例**
“`go
package mainimport (
“log”
“testing”
)func TestDefer(t *testing.T) {
tcs := map[string]string{
“A”: “1”,
“B”: “2”,
“C”: “3”,
}defer log.Printf(“End”)
for tn, tc := range tcs {
tc := tc
t.Run(tn, func(t *testing.T) {
t.Parallel()
log.Println(tc)
})
}
}
“`そのログの抜粋:
“`bash
2009/11/10 23:00:00 End
2009/11/10 23:00:
Go言語 + Windows Terminalで、任意の文字にハイパーリンクを埋め込むエスケープシーケンス
# 結論
“`golang
package main
import (
“fmt”
)
func main() {
fmt.Println(“\033]8;;https://www.google.com/\aGoogle\033]8;;\aへリンク”)\\->Googleへリンク
}
“`# 参考
[ターミナルエミュレータ内でクリッカブルなリンクを作る方法](https://qiita.com/aosho235/items/335fc2f4b002a8251a2f)
[How to add hyperlinks to a terminal [ Node.js ]](https://stackoverflow.com/questions/69314689/how-to-add-hyperlinks-to-a-terminal-node-js)
[Explicit hyperlinks and context information for your terminal](https://www.uninformativ.de/blog/postings/2018-04-14
Google Compute Engine の startup script で $ go install と インストールされたバイナリを実行する方法
## TL;DR
“`bash
metadata_startup_script = <<-EOF #!/bin/bash TARGET_REPOSITORY_URL=github.com/... # ここは適宜差し替えてください TARGET_BIN_NAME=... # ここも mkdir /home/user export HOME=/home/user cd /usr/local/src wget https://go.dev/dl/go1.17.7.linux-amd64.tar.gz > /dev/null 2>&1
tar -C /usr/local/ -xzf go*.tar.gz > /dev/null 2>&1
GOCACHE=/usr/local/go/cache GOBIN=/usr/local/go/bin GOPATH=/usr/local/go /usr/local/go/bin/go install -v ${TARGET_REPOSITORY_URL}@latest
/us
Goの静的解析ツールblahbrah
Goの静的解析ツールを作ったので紹介したいと思います。
## 作ったもの
– [blahbrah](https://github.com/granddaifuku/blahbrah)### 何ができるのか
– タイトルにもある通り、Goの静的解析をしてくれます
– Brace( “{” や “}” )の前後にある空白行を検知することができます次のコードを例に取ります。
突っ込み所はとてもありますが、一番気になる(?)のは、**レビューで指摘されそうな**、12行目や20行目に存在する空白行ではないでしょうか。
“`main.go
1 package main
2
3 import “fmt”
4
5 type cat struct {
6 name string
7 age int
8 }
9
10 func newCat(name string, age int) cat {
11 return cat{
12
13 name: name,
14 age: age,
15 }
16 }
17
18 func foo(a, b int) int
0-1ナップサック アルゴリズム
# 何が書いてあるか。
0-1ナップサック問題[^1]のアルゴリズムのGo言語実装サンプル
[^1]: 重量を越えないような物の組み合わせのうち、価値が最大になるようにな組み合わせを求める問題。“`go
package main
import (
“fmt”
“math”
)
type Kingyo struct {
weight int
kati int
}
func main(){
var N,x int
fmt.Scanf(“%d %d”, &N,&x)kingyo:=make([]Kingyo,N)
for i:=0;i
Go の API をフロントサイドから呼び出す
API 側に
“`go
http.Handle(“/”, http.FileServer(http.Dir(“static”)))
“`
“static” フォルダに html などを入れる。## 詳しく
main.go に
“`go
http.Handle(“/”, http.FileServer(http.Dir(“static”)))
log.Fatal(http.ListenAndServe(“:8080”, nil))
“`
と書いた場合。(main.go があるフォルダ)/static に index.html を入れる。
“`
go run main.go
“`
などで実行すると、localhost:8080/ で index.html が表示される。
localhost:8080/test.html とかで static/test.html が表示される。“static” フォルダは別フォルダにしても動く。”../test” とかでも問題ない。
“/” を “/top” にして localhost:8080/top にアクセスすると not foun
Go言語のモジュール実装
モジュールの実装方法と実装したモジュールを利用したmainモジュールを実行するところをできるだけ簡略化して紹介します。
## モジュール用の作成
### モジュール用のディレクトリを生成
“`sh
mkdir greetings
cd greetings
“`### モジュールの初期化
[go mod init](https://go.dev/ref/mod#go-mod-init)コマンドで現在のディレクトリをルートとする新しいモジュールを初期化(go.modファイルを生成)します。
※go.modファイルはまだ存在していてはなりません。“`sh
go mod init example.com/greetings
# go: creating new go.mod: module example.com/greetings
“`### モジュールの実装
“`go
package greetingsimport “fmt”
// 大文字から始まる関数はpublic扱いになるので、Hello関数はimportしたモジュールから参照できます。
func
golang-migrateチュートリアル(migration編)
#初めに
golang-migrateのチュートリアルです。#環境
PC:Mac(CPUはintel製)
Go:1.17.6 ←Goのver大事。versionは1.16以降をインストールしてください。
開発エディタ:Visual Studio Code#ディレクトリ構成
“`shell:ディレクトリ構成
~/go/src/test $ tree
.
├── db
│ └── migrations
│ ├── 000001_create_users_table.down.sql
│ └── 000001_create_users_table.up.sql
├── docker-compose.yml
└── go.mod
2 directories, 4 files
“`#go-migrateのインストール
“`shell:golang-migrateのインストール
brew install golang-migrate
“`#事前準備
①DB用意
postgressを用意し、exampleという名のDBを作成する。
②環境依存情報
Herokuでスクレイピングしようとしてハマったこと
## 初めに
Herokuでスクレイピングしてハマったことをまとめてみました。
記事ではGoとagoutiを使用していますが、Pythonとかにも当てはまると思います。
## invalid session id エラーが多発
### 下記エラーが発生
“`
failed to retrieve page HTML: request unsuccessful: invalid session id
failed to retrieve page title: request unsuccessful: invalid session id
“`
### 対策
Chromeのオプションに`–disable-gpu`と`–disable-dev-shm-usage`を指定したら解消しました。
“`golang
options := agouti.ChromeOptions(
“args”, []string{
“–headless”,
“–disable-gpu”,
“–disable-dev-shm-usage”,
})
driver := agout
E2D(End to end – 1)の考察
# はじめに
レイヤードアーキテクチャ、クリーンアーキテクチャ、DIなどのアーキテクチャを使うリポジトリを前提とした話です。gitOps,CIで単体パッケージだけで完結する単体テストを行う際に依存するモジュールをモックすると思います。
その場合はそのソースコードだけでテストが完結するはずです。“`golang:example_unit
func TestFoo(t *testing.T) {
…
mock := gomock.NewBar(ctrl)
…
target := &Foo{bar: mock}
target.Do()
…
}
“`E2Eテストの場合は実際にmain関数相当のものを立ち上げ、Webサーバーなら実際にhttpリクエストを送信してレスポンスの検証等をするために、に依存するDBなど外部ミドルウェアのmockサーバーが起動されlistenするようにクライアントをバインドする構成が多いと思います。
“`golang:example_e2e
func TestE2E(t *testing.T) {
db :=
Golangによるパスワードの保存
パスワードの保存方法として、
平文のパスワードを単方向ハッシュにかけて保存するのが一般的です。
ハッシュアルゴリズムには`SHA-256`、`SHA-1`、`MD5`等があります。
Golang は `crypto` パッケージで簡単に実装することが可能です。
以下、 `sha256` によるの実装例です。
“`go
//import “crypto/sha256”
h := sha256.New()
io.WriteString(h, “my password”)
fmt.Printf(“% x”, h.Sum(nil))
“`# より良い方法
大抵の場合は、暗号化時に使用されたハッシュアルゴリズムが上記のような公開されているものであることが原因で、かつ技術の進歩によりパソコンの計算力も上がり、ハッカーが`rainbow table`を使用することで上記の方法でハッシュされたパスワードをクラックすることが(時間的に)難しく無くなってきたのが現状です。
> `rainbow table` :ハッシュ結果(ダイジェスト)のデータベース
直接的な解決方法の一つは、自
Golang-構造体にあるパスワードなどのセキュリティ情報をログに出力しないようにする方法
構造体をログに出力する際に、パスワードとかのようなセキュリティ情報を出力したくない場合は、方法の一つは `構造体の埋め込み(Embedded)` 特性を利用することです。
構造体の埋め込みの形は、次のような形になります。
“`go
type 埋め込み構造体名 struct {
フィールド名 型名
フィールド名 型名
}type 構造体名 struct {
埋め込み構造体名
フィールド名 型名
}
“`以下のような例で説明しますと、
`RequestSanitized.Password` は `Request.Password` を上書きすることになります。
`Password` を出力したくなければ、あえて`RequestSanitized.Password` を空値にすれば良いです。
“`go
type Request struct {
Name string `json:”user”`
Password string `json:”password”`
}type RequestSanitized struct {
Requ
Go言語のerrorにエラー情報を付けて分岐する。
# この文章について
Go言語の`error`はシンプルで`errors.New(“エラーメッセージ”)`で生成することができます。その一方で、エラー内容に応じて分岐するには工夫が必要です。本記事ではGo言語の`error`でエラー内容に応じて分岐する方法を記載します。
例えば、ユーザ情報を取得するREST APIを作ったときに、
– ユーザが見つからないエラーの場合は、404レスポンス
– データベース接続時に不測のエラーがあった場合は、500レスポンスとしたいと思います。JavaやC#等であれば例外クラスのどれをキャッチしたかで判断できます。しなしながら、Go言語ではどちらの場合であってもシンプルな`error`とだけ変えるので判断できません。そこで判断できるように工夫をしましょう。
# 方法1:Sentinel Error
「Sentinel Error」という単語の和訳が分かりませんので、ここでは「Sentinel Error」と書きます。(知っている方がいましたら教えてください。)
これは`errors.New(エラーメッセージ)`をあらかじめ定義しておき、
Goでcrontabのようなツールを作ってデーモン化してみた
## crontabにGoを動かす処理を登録してみたが動かず
普段業務ではタスクスケジューラにcrontabを使用している。そのためGoでバッチ処理を管理するときも当然のようにcrontabで管理するものだと思っていたが、なぜかcrontabが動作せず、エラーログも残らないという現象に直面。調べてみても、Goをcrontabで実行しようとする人がおらず、代わりにGoのタスクスケジュールライブラリの紹介記事をいくつか発見したため、こちらで実装してみることにした。
## gocronを使用してタスクスケジューリングを行う
Goのタスクスケジュールライブラリはいくつか存在するようだが、
こちらで無限ループなどにして待ち状態を実装する必要がなさそうだったため、今回はgocronを採用。Goのバージョンは1.17.6
“`main.go
package mainimport (
“fmt”
“path/filepath”//”github.com/jasonlvhit/gocron”
“github.com/go-co-op/gocron”
“gith
aws-sdk-goでcredentialを指定するには
# 結論
`Credentials`を指定して、静的な値を入れる。> You can hard-code credentials in your application by passing the access keys to a configuration instance, as shown in the following snippet.
“`:go
aws.Config{
Region: aws.String(cfg.Region),
Credentials: credentials.NewStaticCredentials(
“AWS_ACCESS_KEY_ID”,
“AWS_SECRET_ACCESS_KEY”,
“TOKEN”,)
}
“`# 経緯
アプリケーションをデプロイする際に、dockerコンテナの環境変数と本番環境の環境変数が被っていた。
この環境変数は、ElasticSearchを使うにあたって必要だったので命名を変更。
`AWS_ACCESS_KEY_ID` => `ES_A_K_ID`
`AWS_SECRET_ACCESS
wails v2でvueテンプレートを作った手順
# 要約
wails v2でvueを使えるテンプレートを作った。[これ](https://github.com/woogea/wails_vue_template)
これはその時の作業記録# 動機
マルチプラットフォーム対応のデスクトップアプリケーションをgoで作りたかった。
できるだけ一つのプラットフォームで開発して、他は最低限の確認すればOKとしたかったため、ブラウザエンジン組み込み型にすることにした。
フロントのフレームワークはvueを使いたかったけど、v2には公式テンプレートが用意されていない。
すでにテンプレートを[作ってくれている人はいる](https://github.com/misitebao/wails-template-vue)けど、viteを使っていて慣れなかったのでnpmを使ったものを作ることにした。
あと、wailsの仕組みを理解するのにもいいかなと思った。# wails
比較的アクティブで、構成がシンプルで何をやっているかわかりそうな[wails](https://github.com/wailsapp/wails)を選択した。
v2がbeta