- 1. 【GO】コンパイラによるレシーバの暗黙的変換ってなに?
- 2. gorm gen を使用してデータベースから構造体を作成する
- 3. GoでgRPCサーバーを立ててみる3(repository.goの実装)
- 4. Protocol BuffersのOptionをGo側で読み取る方法を考える
- 5. 【Go】JWT認証をGinで必要最低限の実装をした
- 6. goroutineを使用する際に注意すべきこと
- 7. 💩コード紹介(インターフェース)
- 8. 開発環境の整備のためのホットリロード
- 9. ガチャ1000回実行するのに10秒かかるポンコツAPIを改善した話
- 10. GCP Dataplex機能/実装
- 11. entgoで生成されるモデル構造体から`json:”omitempty”`を駆逐したい
- 12. Golang&PostgreSQL:「Dockerfile」「compose.yml」環境構築
- 13. GoでReactをSSRする
- 14. KEDAとEventHubsを使用したKafka ScaledJobsのサンプル
- 15. Go言語のdatabase/sqlパッケージはデータベースドライバーをどのようにして読み込んでいるのか
- 16. fake-clientのRESTClientをIndexerInformerに渡すとpanicする
- 17. GCP Cloud Data fusion機能/実装
- 18. Docker + GolangでTimeZoneがうまく設定できない
- 19. GoでgRPCサーバーを立ててみる2(gRPCのスキーマ定義とコード生成)
- 20. Go で OIDC RP が実装できるライブラリを探す
【GO】コンパイラによるレシーバの暗黙的変換ってなに?
# はじめに
ありし日の自分は以下のコードが正常に動作することに疑問を感じてました。
“`golang
type Dog struct {
Name string
}func (d *Dog) Speak() {
fmt.Printf(“Woof, I am %s\n”, d.Name)
}func main() {
dog1 := &Dog{Name: “hoge”}
dog1.Speak() // => Woof, I am hoge
dog2 := Dog{Name: “fuga”}
dog2.Speak() // => Woof, I am fuga
}
“`
「`*Dog`というポインタ型に対して`Speak()`は定義されているけど、`Dog`という値型には`Speak()`定義されてないのだから、`dog2.Speak()`はpanicするはずでは?」と脳内にはてなマークを浮かべてました。
疑問を先輩にぶつけてみたところ、腑に落ちる説明を頂いたので備忘録としてまとめておきます。# 結論
「コンパイラによる暗黙的変換が行われているから」です。
ポ
gorm gen を使用してデータベースから構造体を作成する
# 背景
最近会社でGolangのプロジェクトに入りAPIを作成しています。その際にDBのデータを受け取る構造体を作成するのが非常に面倒でした。特に、gormタグの作成が面倒でスキーマに応じて変更する必要があります。
これを手作業で作成している時、先輩に`gorm gen`があるから使ってみたらと言われ少し触ってみたのでわかったことを書いていきます。https://gorm.io/gen/database_to_structs.html
# 特定のテーブルのみを作成する
“`go:main.go
users := g.GenerateModel(“users”)
articles := g.GenerateModel(“articles”)
g.ApplyBasic(users, articles)
g.Execute()
“`# スキーマと異なるテーブル名,カラム名にする
“`go:main.go
users := g.GenerateModelAs(“users”, “changedUsers”,
gen.FieldRename(“name”, “changedN
GoでgRPCサーバーを立ててみる3(repository.goの実装)
お疲れ様です。
今日は「repository.goの実装」について部分いたします。
articleサービスにおいてDBとやり取りをするrepository.goの実装を行なっていきます。
今回は簡易的なデータベースとしてsqlite3を使用するので、以下のパッケージをインストールしておきましょう。
“`terminal
go get github.com/mattn/go-sqlite3
“`インストールできたら、忘れずにimportしておきます。
“`article/repository/repository.go
package repositoryimport (
_ “github.com/mattn/go-sqlite3”
)“`
articleサービスでは、以下のようなarticlesテーブルにデータを格納していきます。
| id | author | title | content |
|:———-:|:—————:|:
Protocol BuffersのOptionをGo側で読み取る方法を考える
## はじめに
[Protocol Buffers](https://github.com/protocolbuffers/protobuf)では、Enumを宣言してGoのコードを生成すると、基本的には `string` ↔ `int32` の対応関係が生成される。しかし、この `string` に使える文字種は、[Specification](https://protobuf.com/docs/language-spec#enums)によると、 `[A-Za-z_]` の範囲に限られる。そのため、これ以外の文字種を使いたい場合は、他の方法で表現する必要がある[^1]。
[^1]: 例えば、認可グラントをEnumで表現したい場合、`urn:ietf:params:oauth:grant-type:jwt-bearer` のような値を設定することはできない。
変換ロジックを外部に置くことも出来るが、その場合は各言語で実装することになるため、対応関係に差異が生じる危険性がある。そこで、オプショナルな値をProtocol Buffers側で宣言し、各実装でオプションの値を取得する方法を
【Go】JWT認証をGinで必要最低限の実装をした
## やりたいこと
Ginでユーザーログイン機能を実装し、ログインユーザーだけがアクセス可能なエンドポイントをJWT認証を使って実装したい。## JWT認証の仕組み
### JWTとは
### JWT認証の仕組み## Ginで実装してみる
### “`main.go“`
“`go:main.go
import (
“net/http”
“time”“github.com/gin-gonic/gin”
“github.com/golang-jwt/jwt/v5”
)func main() {
r := gin.Default()r.POST(“/login”, loginHandler)
authGroup := r.Group(“/auth”)
authGroup.Use(authMiddleware)
authGroup.GET(“/”, func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{“message”: “you are authorized”})
})r.Run(“
goroutineを使用する際に注意すべきこと
for文で並行処理をしたい状況はたくさんあると思います。
“`go
var wg sync.WaitGroup
for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() fmt.Println(i) }() } wg.Wait() ``` 上記のコードを実行すると、どのような結果が得られると思いますか? ```shell 5 10 10 10 7 10 10 10 10 10 ``` 実行するごとに、異なる結果が出ると思います。 これは、goroutineの中で変数`i`を表示するときにはすでに、`for`ループが終了してしまっているからです。 これを回避するには、ループのスコープの中で新しい変数を宣言します。 この変更により、各ゴルーチンはそれぞれの`v`の値をキャプチャします。 ```go var wg sync.WaitGroup for i := 0; i < 10; i++ { v := i // 追加 wg.Add(1) go func() { defer wg.Don
💩コード紹介(インターフェース)
# はじめに
自分で書いてしまった、またはどこかで見かけた💩コードをデフォルメして紹介します。
今回はGolangのインターフェースに関する💩コードです。# 今回の💩コード
WEBアプリケーションです。
HTTPリクエスト/レスポンスのハンドリングと、ビジネスロジックを分けるために(多分)、`endpoint`と`service`パッケージが作成されています。“` golang
package endpointimport “service”
type SomeEndpoint struct {
svc service.SomeServiceInterface
}func NewSomeEndpoint(svc service.SomeServiceInterface) SomeEndpoint {
return SomeEndpoint{
svc: svc,
}
}
“`“` golang
package servicetype SomeServiceInterface interface {
CreateRecord() error
開発環境の整備のためのホットリロード
## 概要
EchoのAPI開発環境の整備のためにホットリロードを導入する。
また、WindowsでのDocker環境を使ったため少々特殊な事象が発生したのでそちらについてもまとめる。## ホットリロードの必要性
GoのWebアプリケーションの開発環境において、ホットリロードが欲しくなるケースはある。
それは、一度実行されてしまうと状態を保持してしまうためだ。
何かしらの修正を行った際に、実行しなおさないと修正内容が正しく反映されているか確認がとれない。
開発時もそうだし、バグの検証などでデバックコードを埋め込んだりすることにおいて実行しなおしは効率が下がる要因になりやすい。
そこで、ホットリロードを採用して開発環境において、修正した際に都度再実行(リロード)してもうらようにしてこの問題を解消を目指します。
注意点としては、修正に対して自動で再実行されてしまうので、状態を保持したかった債などは注意が必要になる。特にIDEで自動保存が有効になっていると意図していない状態でリロードされる場合があるので気をつける必要がある。## airの導入
### 前提
今回は以下の環境が
ガチャ1000回実行するのに10秒かかるポンコツAPIを改善した話
# はじめに
今回は駆け出しエンジニアとして、バックエンドの開発で躓いたところがあったので共有したいと思います。
私と同じバックエンド初学者向けの記事ではありますが、経験豊富なエンジニアの方々からのFBにも期待して書いておりますので、是非ともコメントお願いします!!# TL;DL
Goを用いたAPIの処理速度の改善
– BulkInsert
– マスターデータをメモリで保持する# 前提
バックエンドに関する学習の一環で、ガチャAPIの実装を行っていました。概要は、ガチャを回すことで排出されるキャラクターをユーザごとに保管する簡素なアプリケーションのAPIです。テーブルは以下の通りです。
– ユーザテーブル : ユーザ名など
– キャラクターテーブル : キャラクター名
– ポゼッションテーブル : ユーザとキャラクターの中間テーブル
– エミッションテーブル : キャラクターのレアリティを保存している
それでは、実際にガチャを排出するハンドラーを見てみましょう。~~~go
func (gh *GatchaHandler) PlayGatcha(c ec
GCP Dataplex機能/実装
# GCPのCloud Dataplexの概要
Cloud Dataplexは、Google Cloud Platform(GCP)のサービスの一部であり、データレイク環境を構築し、データの管理と利活用を支援します。以下に、Cloud Dataplexの機能と詳細について説明します。
## 概要
Cloud Dataplexは、大量のデータを一元管理するためのプラットフォームです。データを各種データソースから集約し、それを効率的に分析するための統合データエンジンを提供します。以下にCloud Dataplexの主な特徴を示します。– **データソースの統合**: Cloud Dataplexは、様々なデータソース(データベース、データウェアハウス、クラウドストレージなど)からデータを収集し、一元的に管理します。データの流入や変換、統合が容易に行えます。
– **データのバージョン管理**: Cloud Dataplexは、データの更新や変更を追跡し、バージョン管理を行うことができます。過去のバージョンのデータを参照することにより、データの変化を追跡したり、過去の状態に戻したりす
entgoで生成されるモデル構造体から`json:”omitempty”`を駆逐したい
:::note info
**要するに**
entgoで生成されるモデル構造体から`json:”omitempty”`を駆逐するためのライブラリを作成しました。– https://github.com/a10adotapp/entfw
:::# 困ったこと
goのORMに[ent.](https://entgo.io/)を使用し、スキーマファイルからモデル構造体を自動生成する際、
生成される構造体には`json:”omitempty”`のタグが自動で付与されています。例えばこのようなスキーマを作成して、
“` go
package schemaimport (
“entgo.io/ent”
“entgo.io/ent/schema/field”
)// Pet holds the schema definition for the Pets entity.
type Pet struct {
ent.Schema
}// Fields of the Pet.
func (Pet) Fields() []ent.Field {
return []e
Golang&PostgreSQL:「Dockerfile」「compose.yml」環境構築
# Dockerfile
alpineを使うことで、軽量なdocker イメージを利用することができます。
基本的にGolangは、マルチビルドな構成のため、FROMが二つあります。
デフォルトの`GOARCH=amd64`を指定してますが、余裕があればさらに軽量な`GOARCH=arm64`を試してみてください。
“`Dockerfile
### ビルド用ステージ ###
FROM golang:1.21.4-alpine as builderWORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY . .
RUN GOOS=linux GOARCH=amd64 go build -o main .### 開発用ステージ ###
FROM golang:1.21.4-alpine as development# アップデートとvim,gitのインストール
RUN apk update && apk add vim git# sqlcのインストール
RUN go install github
GoでReactをSSRする
## 概要
GoでReactをSSRできそうだったので試してみました。
下記が動作の様子と実施のコードです。![](https://storage.googleapis.com/zenn-user-upload/4f86b0635c6b-20240121.gif)
https://github.com/K-Sato1995/go-ssr-poc
やっている間に良い感じに実現されている下記のプロジェクトも見つけました。
私の現状のPOCだと実現できないことが色々実現されててすごいなと思いました。https://github.com/natewong1313/go-react-ssr
## やりたい事
– Go環境でReactの[renderToString](https://react.dev/reference/react-dom/server/renderToString)でSSRを行う
– 実行結果をブラウザに渡す
– ブラウザでReactの[hydrateRoot](https://react.dev/reference/react-dom/client/hyd
KEDAとEventHubsを使用したKafka ScaledJobsのサンプル
以下は、Kafka ScalerとScaledJobのテスト用サンプルを作成するためのブログの日本語訳です。シンプルなGoクライアントが必要で、メッセージを消費したら終了するものです。Goを使用する理由は、[KEDA](https://keda.sh/)のKafka ScalerがKafka Scalerの実装に[saram](https://github.com/Shopify/sarama)を使用しているからです。そのため、Kafka Scalerの実装を理解するのに役立つと思いました。
# Kafka Broker
Kafka Brokerは、ブローカーを簡単に作成するためにEventHubsとして使用します。EventHubsはKafka APIで使用することができます。
* [Apache KafkaアプリケーションからAzure Event Hubsを使用する](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-for-kafka-ecosystem-overview)
# 設定
## Sar
Go言語のdatabase/sqlパッケージはデータベースドライバーをどのようにして読み込んでいるのか
# 本題
Go言語のdatabase/sqlパッケージがデータベースドライバーをどのようにして読み込み、利用しているか気になったので調べてみました。
## サンプルコード
“`go
import (
“database/sql”
“time”_ “github.com/go-sql-driver/mysql”
)// …
db, err := sql.Open(“mysql”, “user:password@/dbname”)
if err != nil {
panic(err)
}
“`
引用) https://github.com/go-sql-driver/mysqlmysqlの場合はこんな感じで読み込むのですが、`database/sql.Open`関数の第一引数には”mysql”という文字列しか渡されていなく、ドライバーの実装は渡されていないんですよね。
`database/sql.Open`関数の実装を見てみましょう。
“`go
func Open(driverName, dataSourceName string) (*DB, error
fake-clientのRESTClientをIndexerInformerに渡すとpanicする
Kubernetes client-goのIndexerInformerを使った実装で、以下のようにclientsetからRESTClientを取得してcacheを作成しようとしたところ、go testでfake clientを渡した際にclient内部でパニックが発生していた。
“`go
cachedLw := cache.NewListWatchFromClient(clientset.CoreV1().RESTClient(), resource, “”, fields.Everything())
indexer, informer := cache.NewIndexerInformer(cachedLw, &v1.Pod{}, 0, cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
// on create…
},
UpdateFunc: func(old interface{}, new interface{}) {
// on update
GCP Cloud Data fusion機能/実装
# GCPのCloud Data Fusionの概要と機能
## 目次
1. [概要](#概要)
2. [機能/詳細](#機能詳細)
3. [まとめ](#まとめ)## 概要
GCPのCloud Data Fusionは、エンタープライズデータ統合のための完全マネージドなサービスです。データパイプラインの構築、監視、管理が簡素化されます。Cloud Data Fusionは、異種のデータソースを統合して、高度なデータ変換やトランザクションを行うことができます。## 機能/詳細
– **データ統合パイプラインの作成**: Cloud Data Fusionは、直感的なビジュアルユーザーインターフェースを提供し、データパイプラインの作成を簡単にします。ビジュアルドラッグアンドドロップエディタを使用して、異なるデータソースやトランスフォーマーションステップを組み合わせてデータフローを構築できます。– **スケーラビリティと信頼性の向上**: Cloud Data Fusionでは、自動スケーリングがサポートさ
Docker + GolangでTimeZoneがうまく設定できない
# はじめに
どうも僕です。業務でDockerを使うことがあるのですが、`golang`のコンテナで`cron`の実行をする際、タイムゾーンが`UTC`だったので`JST`に変えようとしたところ、結構つまづいたのでメモっておきます。
# 概要
`golang`にてcronを使って毎日特定の時刻に関数を走らせたい!
↓
しかしタイムゾーンがUTCだ!!
↓
どうにかせんといかん。# 結論
先に結論を言うと、 Dockerfileに次のコードを追加する。“`Dockerfile
FROM golang:1.19WORKDIR /usr/src
# これを追加↓
ADD https://github.com/golang/go/raw/master/lib/time/zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip
“`そしてコード
“`go:sample.go
package mainimport (
“fmt”
“log”
“os”
“time”
)func main() {
os.Seten
GoでgRPCサーバーを立ててみる2(gRPCのスキーマ定義とコード生成)
こんにちは。
金です。
今日は「gRPCのスキーマ定義」について部分いたします。# 事前準備
まずは、以下のようにディレクトリとファイルを作成します。
“`
.
└─ article
├── client ─ client.go
├── repository ─ repository.go
├── server ─ server.go
├── service – service.go
└── article.proto
“`また、ルート配下でgo moduleの初期化を行なっておきましょう。
“`terminal
go mod init
“`### .protoファイルの記述
.protoファイルにgRPCのスキーマ定義を記述していきます。
実装するarticleサービスの仕様はprotoファイルのservice部分で定義しているように、CRUD+全取得ができるものになっています。“`article/article.proto
syntax = “proto3”;package article;
option go_p
Go で OIDC RP が実装できるライブラリを探す
## はじめに
OIDC RP を実装する場合以下のようなことをする必要があります。
※ 認可コードグラントです。– ディスカバリ構成の管理
– 認可エンドポイントの生成
– トークンエンドポイントへのアクセス
– トークンの検証etc …
OIDC はカッチリ仕様が決まっていますし、そこまで複雑な実装にもならないと思いますが、ライブラリがあるなら頼りたいものです。
本記事では Go で OIDC RP をライブラリを用いて実装するにあたり候補となるライブラリを調査し実際に使ってみたのでご紹介します。## ライブラリ
調べたところ候補となるライブラリは以下の2つがありました。
(ほかにもあったら教えていただきたいです。)https://github.com/zitadel/oidc
https://github.com/coreos/go-oidc
どちらもライセンスは `Apache-2.0 license` です。
本記事執筆で参照しているそれぞれのライブラリのバージョンは
– `zitadel/oidc` : [v3.10.0](https://