GOで 構造体に定義したメソッドと埋め込みされたメソッドが同じシグニチャで無限ループに遭遇した

GOで 構造体に定義したメソッドと埋め込みされたメソッドが同じシグニチャで無限ループに遭遇した 以下実装で発生していた type SampleService struct { repository.SampleRepositoryHandler } func (s *SampleService) TargetFunction(ctx context.Context, sampleID, exampleID string) error { err := s.TargetFunction(ctx, sampleID, exampleID) if err != nil { // ... } } それまで異なる名前だったので、メソッド名変更を実施したタイミングで発生した為、気づかなかった ポイント 構造体埋め込み(匿名フィールド)は、委譲(delegation)として機能する 埋め込んだ型のメソッドを、親構造体のメソッドとして呼び出せる s.TargetFunction は SampleService のメソッドと、埋め込んだ SampleRepositoryHandler のメソッド両方を持つ 名前が重複している場合は、親構造体のメソッドが優先される 解決策 埋め込みで呼べたとしても、明示的に記載すべき

2025-08-27 ·  2025-09-17 · 1 分 · 46 文字

Cloud Function から IAM認証で CloudSQL(PostgreSQL) へ接続する

はじめに クラウド環境でのデータベース管理において、セキュリティは日々進化する脅威への対応が求められる重要課題です。特に、以下の課題が顕在化しています: 従来の認証情報(パスワード)の漏洩リスク 認証情報のローテーション管理の煩雑さ アプリケーション展開時の認証情報受け渡しの安全性確保 これらの課題に対し、IAM認証を活用することで、より強固でかつ運用負荷の少ないセキュリティ体制を実現できます。IAM認証のメリットは以下の通りです: 一時的な認証トークンの利用による漏洩リスクの低減 クラウドプロバイダーの統合認証基盤との連携による管理の一元化 きめ細かなアクセス制御とアクセスログの監査対応 本ガイドでは、Cloud FunctionsからCloudSQL(PostgreSQL)へIAM認証で接続する実践的な手順を解説します。この設定により、セキュアかつスケーラブルなデータベースアクセス環境を構築できます。 Cloud Function から CloudSQL(PostgreSQL) へ IAM 認証で接続するために必要な手順 Cloud Function 用 Service Account に必要な権限を付与 PGUSER の作成(IAM認証用) データベースへの権限付与 Cloud Function の実装 Service Account での Cloud Function のデプロイ 具体的な設定手順 1. Cloud Function 用 Service Account に必要な権限を付与 以下の権限が必要: Cloud SQL インスタンス ユーザー Cloud SQL クライアント 今回はコンソールから設定したが、以下のコマンドで設定も可能: gcloud projects add-iam-policy-binding example-project \ --member="serviceAccount:example-function@example-project.iam.gserviceaccount.com" \ --role="roles/cloudsql.instanceUser" gcloud projects add-iam-policy-binding example-project \ --member="serviceAccount:example-function@example-project.iam.gserviceaccount.com" \ --role="roles/cloudsql.client" 2. PGUSER の作成 IAM認証用のユーザーを作成する。 gcloud sql users create example-function@example-project.iam \ --instance=example-project-fdc \ --type=cloud_iam_service_account PostgreSQLの場合、以下の点に注意が必要: ユーザー名から .gserviceaccount.com を除いた形で作成 タイプは cloud_iam_service_account を指定 MySQL の場合は @project-id.iam.gserviceaccount.com を除いた形で作成する模様 Refs: GoogleCloudPlatform/cloud-sql-nodejs-connector: A JavaScript library for connecting securely to your Cloud SQL instances Postgres: For an IAM user account, this is the user’s email address. For a service account, it is the service account’s email without the .gserviceaccount.com domain suffix. MySQL: For an IAM user account, this is the user’s email address, without the @ or domain name. For example, for test-user@gmail.com , set the user field to test-user. For a service account, this is the service account’s email address without the @project-id.iam.gserviceaccount.com suffix. ...

2025-01-29 ·  2025-01-30 · 3 分 · 515 文字

Go モジュールの編成

先日バズってた Go のプロジェクトディレクトリの正式見解というか本家の推奨記事. 気になってたので、読んでみた 以下翻訳結果 ファイルやフォルダのレイアウトに関して、Go を初めて使う開発者によくある質問は「Go プロジェクトをどのように整理すればいいのか」というものです。このドキュメントの目的は、この質問に答えるためのガイドラインを提供することです。このドキュメントを最大限に活用するために、チュートリアルを読み、モジュールソースを管理することで、Goモジュールの基本に精通していることを確認してください。 Go プロジェクトには、パッケージ、コマンドライン・プログラム、またはその 2 つの組み合わせがあります。このガイドはプロジェクトの種類別に構成されています。 基本パッケージ 基本的なGoパッケージは、すべてのコードがプロジェクトのルートディレクトリにあります。プロジェクトは1つのモジュールで構成され、1つのパッケージで構成されます。パッケージ名はモジュール名の最後のパスコンポーネントと一致します。単一のGoファイルを必要とする非常に単純なパッケージの場合、プロジェクトの構造は次のようになります: project-root-directory/ go.mod modname.go modname_test.go [この文書中、ファイル名/パッケージ名は完全に任意です]。 このディレクトリが github.com/someuser/modname のGitHubリポジトリにアップロードされていると仮定すると、 go.mod ファイルのモジュール行には、 module github.com/someuser/modname と書かれているはずです。 modname.go のコードでパッケージを宣言します: package modname // ... パッケージのコードはここ ユーザーは、Goのコードでこのパッケージをインポートすることで、このパッケージに依存することができます: import "github.com/someuser/modname" Goパッケージは複数のファイルに分割することができます: project-root-directory/ go.mod modname.go modname_test.go auth.go auth_test.go hash.go hash_test.go ディレクトリ内のファイルはすべてmodnameパッケージを宣言している。 基本コマンド 基本的な実行可能プログラム(またはコマンドラインツール)は、その複雑さとコードサイズに応じて構成されます。最も単純なプログラムは、 func main が定義された1つのGoファイルで構成されます。より大きなプログラムでは、コードが複数のファイルに分割され、すべて main パッケージを宣言します: project-root-directory/ go.mod auth.go auth_test.go client.go main.go ここで main.go ファイルには func main が含まれているが、これは単なる慣例である。main ファイルは、modname.go(modnameの適切な値に対して)とか、他の名前にすることもできる。 ...

2023-09-24 ·  2023-09-24 · 2 分 · 244 文字

slices.Contains について少し調べた

slices.Contains を使用しようとして、コンパイルエラーになったので、少し中身を追ってみた 以下が、実際の実装部分 slices.go func Contains[S ~[]E, E comparable](s S, v E) bool { return Index(s, v) >= 0 } Genericsを使用していて、E は comparable で S はその E の Sliceかー。 では、S ~[]E の ~ とはなんだろうか? 以下 ChatGPT さんの回答 S ~[]E の表記は、Goの新しいジェネリクス機能において、型Sが型Eのスライスであるという制約を示します。この制約は、ジェネリクス関数やジェネリクス型を定義する際に使用されます。 ~ 演算子は、“型の等価性"を示すために使用されます。具体的には、S が []E という具体的な型であるか、それに等価な型(例えば、型エイリアスなど)である必要があります。 例えば、以下のような型があるとします: type MyInt int type MySlice []MyInt この場合、Contains[MySlice, MyInt] のように関数を呼び出すことができます。なぜなら、MySlice は []MyInt に等価であり、MyInt は int に等価だからです。 この ~ 演算子と型制約は、Goのジェネリクスが提供する強力な型安全性を維持する一方で、柔軟性も提供します。それによって、コンパイル時に型の不一致や他の型関連のエラーを防ぐことができます。 ~ は それに等価な型という制約 comparable な 型の Slice のようなものは許す みたいな感じか ...

2023-09-14 ·  2023-09-23 · 1 分 · 74 文字

GoReleaser を GitHub workflow で設定する最低限の方法

手っ取り早くリポジトリの WorkFlow つかって Go の リリースを実装する為の設定をメモしておく v0.0.1 みたいな形式のタグを打てばリリースされる こんな感じのヤツ 1. goreleaser init で .goreleaser.yaml を生成する デフォルトでこんな感じで生成される # This is an example .goreleaser.yml file with some sensible defaults. # Make sure to check the documentation at https://goreleaser.com before: hooks: # You may remove this if you don't use go modules. - go mod tidy # # you may remove this if you don't need go generate - go generate ./... builds: - env: - CGO_ENABLED=0 goos: - linux - windows - darwin archives: - format: tar.gz # this name template makes the OS and Arch compatible with the results of uname. name_template: >- {{ .ProjectName }}_ {{- title .Os }}_ {{- if eq .Arch "amd64" }}x86_64 {{- else if eq .Arch "386" }}i386 {{- else }}{{ .Arch }}{{ end }} {{- if .Arm }}v{{ .Arm }}{{ end }} # use zip for windows archives format_overrides: - goos: windows format: zip checksum: name_template: 'checksums.txt' snapshot: name_template: "{{ incpatch .Version }}-next" changelog: sort: asc filters: exclude: - '^docs:' - '^test:' # The lines beneath this are called `modelines`. See `:help modeline` # Feel free to remove those if you don't want/use them. # yaml-language-server: $schema=https://goreleaser.com/static/schema.json # vim: set ts=2 sw=2 tw=0 fo=cnqoj 2. .github/workflows/release.yml に以下を設定する name: release on: push: tags: - "v[0-9]+.[0-9]+.[0-9]+" jobs: goreleaser: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 1 - name: Setup Go uses: actions/setup-go@v4 # with: # go-version: 1.20 - name: Run GoReleaser uses: goreleaser/goreleaser-action@v4 with: distribution: goreleaser version: latest args: release --clean # workdir: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 3. Repository の Workflow Permission に書き込み権限をつける リポジトリ Settings - Actions - General に Workflow permissions 項目がある ...

2023-08-09 ·  2023-09-24 · 2 分 · 274 文字