- 1. [Golang]go-elasticsearchでレスポンスをmockする方法
- 2. GoのbufconnでモックしたgRPCサーバーを使ってテストをするとUnavailableになる
- 3. Golangにおけるスライスの範囲指定:a[low : high]
- 4. Goの超最小構成を試す
- 5. 【Go】サブスライスは元スライスとメモリを共有する
- 6. 【Go / Protobuf / Node.js】gRPC の双方向ストリーミングを利用してチャットを実装する
- 7. Go の第一印象が Cっぽくてなんか懐かしい、と思った。
- 8. GoでExcelデータを読み込む方法
- 9. Golangの関数におけるポインタレシーバーと値レシーバーの違い
- 10. 【Go】swap関数の作成を通してポインタについて学ぶ
- 11. Kubernetes+Golnag+gRPC+Terraformでクライアントからサーバーに接続する方法
- 12. Go TemplateでCコンパイラを実装する【ELVM】
- 13. Go言語 暗黙的なinterfaceのメリット
- 14. AWSでEC2+RDSでGo+Nginxのアプリケーション構築
- 15. 【VSCode】Goのテストで事前に環境変数をセットする
- 16. GoでDI (依存性注入) を実装する
- 17. API Gatewayを単一Lambda関数と統合する際のハンドラーのルーティング方法
- 18. go言語 単体テストをする
- 19. Go言語でブロックチェーンのシステムを作成する(その3)
- 20. gormのメモ
[Golang]go-elasticsearchでレスポンスをmockする方法
## 本記事でやること
– [go-elasticsearch](https://github.com/elastic/go-elasticsearch)を使ってElasticsearchからのレスポンスをmockする
– レスポンスをmockした単体テストを書く
– 内部実装のコードリーディングを通して何をmockしているのかを理解する## 対象読者
– これから[go-elasticsearch](https://github.com/elastic/go-elasticsearch)を使って実装を始める方
## 使用言語
– Go 1.21.0
## 実装
### 前提
Elasticsearchにあるインデックスに対して検索クエリを実行し結果を返す`Search`メソッドを実装しました。
今回は、この`Search`メソッドが返すレスポンスをmockします。`Search`メソッドは、検索対象のインデックス名と実行するクエリを文字列として受け取り、検索結果をバイト配列で返します。
また、`Search`メソッドは`esapi.SearchRequest`構造
GoのbufconnでモックしたgRPCサーバーを使ってテストをするとUnavailableになる
# TL;DR
grpc v1.63.0でDialContext関数がdeprecatedになったため、NewClient関数に置き換えたことが原因。
targetに与えるURLのスキームとしてpassthroughを明示的に与えることで解決する。
“`go
//v1.63.0以前
conn, err := grpc.DialContext(
context.Background(),
“bufnet”,
grpc.WithContextDialer(dial),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
//v1.63.0以降
conn, err := grpc.NewClient(
“passthrough://bufnet”,
grpc.WithContextDialer(dial),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
“`# 経緯
Goで書いたgRPCサ
Golangにおけるスライスの範囲指定:a[low : high]
`a[low : high]`: スライスの範囲を示します。startからendまでの要素を含みますが、end自体は含みません。つまり、start以上 end未満の要素が含まれます。
例えば、以下のようなスライスがあるとします。
“`go
a := []int{0, 1, 2, 3, 4, 5}
“`この場合、a[1:4]は、インデックス1(含む)からインデックス4(含まず)までの要素を抽出します。つまり、[1, 2, 3]が返されます。
– 範囲指定の際、startの値は含まれ、endの値は含まれないことに注意してください。
– 範囲指定は元のスライスの一部を参照するだけであり、元のデータを変更するわけではありません。https://go.dev/play/p/8twfG2cXA0N
Goの超最小構成を試す
# やること
`docker init`という便利なコマンドを作って環境をDockerで構築、チュートリアルを適当にやっていく
# やっていく
前提:
以下よりgoを環境に入れておく
https://go.dev/dl/
参考:
https://build.yoku.co.jp/articles/8y06pehjpy#section_1_subsection_1
![スクリーンショット 2024-04-08 19.48.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/c8d8b474-5f10-f9aa-0807-484a2ba46026.png)
![スクリーンショット 2024-04-08 19.50.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/9f8ca454-7db9-1da7-2a1f-9b2eb3de6ab1.png)
聞かれたのはこんな感じ
【Go】サブスライスは元スライスとメモリを共有する
## どんな記事?
Go言語において、スライスの一部分を切り出してサブスライスを作成する場合、**データのコピーを作るのではなく2つの変数がメモリを共有することになるため変更を共有する**という記事です。
もしオリジナルとはメモリを共有しない独自のスライスを作成する必要がある場合、`make`と組み込み関数の`copy`を使いましょう。
スライスを一部切り出した場合と、`copy`関数を使用した場合とでどのような違いがあるか説明していきます。## 一部切り出しについて
以下のようにスライスを一部切り出した場合、両者は同じメモリを参照することになります。これはメモリ効率がいいという反面、一方を変えるともう一方にも影響が及ぶことを意味します。
“`go
package mainimport (
“fmt”
)func main() {
original := []int{1, 2, 3, 4, 5}
subSlice1 := original[1:3]
subSlice2 := original[2:4]fmt.Println(“Before:”, origi
【Go / Protobuf / Node.js】gRPC の双方向ストリーミングを利用してチャットを実装する
※ この記事は 2022年10月 に作成したものを一部改稿したものです。
**gRPC** は RPC (Remote Procedure Call) の一種で、Google が自社サービス向けに開発したものをオープンソース化した技術です。
RPC はあるコンピュータ上で動作するプログラムから別の場所にあるプログラムの処理を実行する手法で、1970年代から存在する考え方です。gRPC では、HTTP/2 の「ストリーム」を利用してサーバ – クライアント間で接続を確立することで、HTTP/1.1 のように1つのリクエストに対して1つのレスポンスを返すだけでなく、複数のリクエスト・レスポンスを並行して処理することができます。
そこで本記事では、gRPC の双方向ストリーミングを利用して CLI 上で動作する簡易的なチャットアプリケーションを実装してみようと思います。
## gRPC の特徴
実装に入る前に、APIの構築に最もよく使われる REST との対比を交えて gRPC の特徴について見ていきます。まず通信方式については、REST は先述の通り HTTP/1.1 が主流
Go の第一印象が Cっぽくてなんか懐かしい、と思った。
# 変数型
“`
int int8, int16, int32, int64uint uint8, uint16, uint32, uint64
“`
**符号無し8ビット整数**
とか
で uint8 で byte の別名を表すところもCっぽい。
あれは確か Windows の MFC だったかな。# 構造体
『構造体❣』と来ました。## C
“`
struct Player {
char* string;
int age;
};
typedef struct Palyer;
“`## Go
“`
type Player struct {
name string
age int
}
“`
GoでExcelデータを読み込む方法
Excelに一覧として持っているメールアドレスや会社名などの情報を読み込み、処理に使用するよう構造体へ格納する、ということを行ったため、Goで実装する方法をまとめます。
# GoでExcelの操作をするには
[excelize](https://github.com/qax-os/excelize) というライブラリを使用します。# excelizeのインストール
下記コマンドを実行して、excelizeをインストールします。“`cmd
$ go get github.com/xuri/excelize/v2
“`# Excelファイルを読み込む
Excelファイルを読み込みます。
今回は以下のような、リストを持つファイルをあらかじめ作成しました。ファイル名: 宛先.xlsx
| 会社名 | 担当者名 | メールアドレス |
| ———— | ———- | ————————– |
| 株式会社A | 田中太郎 | tanaka@example.com
Golangの関数におけるポインタレシーバーと値レシーバーの違い
Golang(Go言語)では、関数を定義する際に、ポインタレシーバー(Pointer Receiver)と値レシーバー(Value Receiver)の2つのオプションがあります。これらは、メソッドを構造体に関連付ける方法を定義します。
### 値レシーバー(Value Receiver)
値レシーバーは、関数が特定の型の値をレシーバーとして受け取ることを示します。このような関数は、そのレシーバーが持つ値のコピーに対して動作します。つまり、レシーバーのフィールドの変更は、元のオブジェクトには影響を与えません。値レシーバーを使用することで、メソッドがオブジェクトを変更しないことを保証することができます。
### ポインタレシーバー(Pointer Receiver)
ポインタレシーバーは、関数が特定の型のポインタをレシーバーとして受け取ることを示します。つまり、関数はそのポインタが指すオブジェクト自体を変更することができます。この場合、関数内での変更は元のオブジェクトに影響を与えます。
“`go
package mainimport “fmt”
type Rectang
【Go】swap関数の作成を通してポインタについて学ぶ
## 問題
2つの数字を入れ替えるswap関数を実装します。
swap関数の引数として、2つの数字のメモリアドレスが渡されるものとします。“`go
package main
import “fmt”
func main() {
num1, num2 := 1, 2
swap(&num1, &num2)
fmt.Println(num1, num2) // 2, 1
}
“`:::note info
本記事ではポインタそのものに関する解説はしません。
ポインタに関しては以下の記事が参考になります。
:::https://qiita.com/gold-kou/items/0d1585fb8d687061c890
## 誤答
私が最初に考えた答えは以下の通りです。何が誤りなのか考えてみてください。
“`go
func swap(a, b *int) (a2, b2 *int) {
a2, b2 = b, a
return
}
“`### 誤っている点
#### 1. 返り値がある
`swap(&num1, &num
Kubernetes+Golnag+gRPC+Terraformでクライアントからサーバーに接続する方法
クライアントからサーバーにgRPC接続する際に以下のようなコードを書くと思います。ローカル環境で開発する際はSERVER_URLとしてlocalhost:ポート番号を指定すれば良かったのですが、Kubernetesにデプロイする際に何を指定すればよいのかについて説明します。terraformで構築するものとして説明します。
“`golang:client.go
conn, err := grpc.Dial(os.Getenv(“SERVER_URL”), grpc.WithTransportCredentials(insecure.NewCredentials()))
“`
# 解決法
まず、サーバー側のアプリケーションのサービスを以下のように作ります。「cluster_ip = “None”」とするのが重要です。自分は「type = “NodePort”」としていて色々試してずっとうまくいきませんでし。。。
“`terraform:server_service.tf
resource “kubernetes_service_v1” “server_service” {
Go TemplateでCコンパイラを実装する【ELVM】
# TL; DR
– ELVM のバックエンドにGo `text/template`(以下「Go Template」、処理系は[Gomplate](https://docs.gomplate.ca/))を追加
– C言語(8cc) -> ELVM IR -> Go Template にコンパイル
– 8ccの8cc実装をコンパイルすればGo Templateで8ccコンパイラがつくれる!(セルフホスト)https://github.com/shinh/elvm
# はじめに
~~ご存じの通り~~ Go Templateはチューリング完全[^turing]なので、任意の処理を実装可能です。
といっても brainf\*ck だけでは華が無いので、今回は **C言語のソースコードをGo Template上で実行します**。# 過去の ~~ネタ~~ 記事
Go Templateでプログラミングをする方法については過去の記事をご覧ください。
https://qiita.com/Syuparn/items/4157d13c39b95185acfd
https://qiita.
Go言語 暗黙的なinterfaceのメリット
Go言語の何がいいかって、色々な部分で実践的な感じがする(唐突)
その代表例として今回はGo言語の暗黙的なインターフェースの何がいいかコードを例に説明したいまず初めにGoのインターフェースの例を示します
“`go
type Writer interface {
Write(data string) error
}type File struct {
Name string
}func (f *File) Write(data string) error {
file, _ := os.OpenFile(f.Name, os.O_WRONLY|os.O_CREATE, 0644)
defer file.Close()
file.WriteString(data)
return nil
}
“`これで`File`構造体(クラスみたいなイメージ)は`Writer`インターフェースを実装していることになります
JavaやTypeScriptと違って明示的にimplementsする必要はないんですね
これの何がいいんかって話です
## Javaでの実装
今回は`
AWSでEC2+RDSでGo+Nginxのアプリケーション構築
## 前提条件
– MacOSを対象としている
– LinuxのVPCを対象
– EC2のインスタンスを作成済み、キーペア作成済み
– RDSのインスタンスを作成済み### EC2にSSH接続
#### ダウンロードしたキーペアの移動・権限付与(済みの場合はスキップ)“`
$ mv ~/Downloads/プライベートキーの名前.pem ~/.ssh
$ chmod 400 ~/.ssh/プライベートキーの名前.pem
# プライベートキーの名前は作成時に決められている(例:aws_user.pem)
“`#### SSH接続
“`
$ ssh -i aws_user.pem ec2-user@パブリックIPv4アドレス
# パブリックIPv4アドレスはEC2のインスタンス詳細画面にて確認できる(例:12.34.567.890)
〜省略〜
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘13.231.224.154’ (ECDSA) to th
【VSCode】Goのテストで事前に環境変数をセットする
# はじめに
VSCodeのエディタ上からGoのテストを行う際に、事前に環境変数をセットする方法を共有します。例えば、以下のようなテストコードを想定します。
“`go
func TestEnvVar(t *testing.T) {
// 環境変数から値を取得
envVar := os.Getenv(“MY_ENV_VAR”)// 環境変数が設定されているかをチェック
if envVar == “” {
t.Error(“Environment variable MY_ENV_VAR is not set”)
} else {
fmt.Printf(“MY_ENV_VAR value: %s\n”, envVar)
}
}
“`
環境変数を取得し、値がセットされているかを確認するコードです。しかしながら、VSCodeの`run test`からテストを実行すると、環境変数がテスト実行時に存在しないため、このテストは失敗します。本来であれば、以下のように環境変数がセットされた状態でテストが実行されてほしいです。
“`bash
MY_ENV_VAR=”he
GoでDI (依存性注入) を実装する
# はじめに
Go でいつものオブジェクト指向言語のノリでサービス層をリポジトリの抽象に依存させようとした場面があったのですが、言語の機能として`implements`がなく永遠に頭を抱えてしまったので実装法を記します
# DI とは
あるオブジェクトにおける依存関係をオブジェクトのソースコード内に記述せず全く違うオブジェクトから注入させるシステム開発におけるデザインパターンの一つです
![スクリーンショット 2024-04-02 19.34.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839531/07ac9c26-0839-2a7e-b203-22544863386c.png)
## メリット
DI を行う最大のメリットはテストが容易になることです
例えば、`DB登録を含む処理`をテストしたい時、外部に依存している`DB登録処理`は一旦テストから除外したいとします。そんなとき、`DB登録処理`はある引数を渡したら定数が返ってくるようにする(モック化)と外部サービスに一切依存す
API Gatewayを単一Lambda関数と統合する際のハンドラーのルーティング方法
# はじめに
API GatewayとLambdaの統合には様々な実装パターンがあるせいか、下記の状況下でのルーティングの方法の情報が無かったので投稿します。
# 前提
– すべてのメソッドを単一のLambda関数とプロキシ統合する
– プロキシリソース(`{proxy+}`)は使わない(HTTPルーティングはAPI Gatewayで行う)
– [aws-lambda-web-adapter](https://github.com/awslabs/aws-lambda-web-adapter)や[aws-lambda-go-api-proxy](https://github.com/awslabs/aws-lambda-go-api-proxy)などは、使用しない# 結論
Lambda関数が受け取るeventオブジェクトに含まれる`resource`と`httpMethod`を使用する。
`path`も使えそうですが、実際のパラメータが含まれる値のため、使用しない方が良いでしょう。“` json:event
{
“resource”: “/todo/{id}”,
go言語 単体テストをする
# 1.はじめに
Go言語で単体テストを実施したい
GO言語に標準で含まれている”testing”パッケージを利用してテストコードを書いてみる以前投稿した以下の記事で作成したGoアプリにテストコードを追加する
[Qiitaの最新記事を教えてくれるアレクサスキルを作ろう Alexa X Lambda X Golang ](https://qiita.com/keny-N/items/47b8dd299e65b6ca85bb#:~:text=github%E3%81%AB%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%8C%99%E3%81%92%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%A7%E5%8F%82%E8%80%83%E3%81%AB%E3%81%97%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84)参考
https://pkg.go.dev/testing
# 2.単体テスト
## 2.1 テ
Go言語でブロックチェーンのシステムを作成する(その3)
## はじめに
前回は、Block、Blockchainの作成、hashのハッシュの実装までやりましたが、今回はtransactionsの実装をしていきます。– 前回までの記事
https://qiita.com/jun_11/items/a1adf93ba02292321b25
– バージョン
– Go 1.22.0## 実装
### イメージ図
下の図のPool、transactionsの実装をしていきます。### transactionsの実装
まず、transactionsの実装をしていきます。“`golang
type Transaction struct {
senderBlockchainAddress string
recipie
gormのメモ
## はじめに
gormはGo言語のORMライブラリーです。
gormで、最初見たとき、gormのcrud処理の前に、把握しておいた方がよかったことをメモりました。
・データベース接続箇所(シャーディングによるDBの振り分け例)
・`&gorm.Config{}` について
・structの定義箇所について
・`gorm.Model`の有無## コード例
“`go
package mainimport (
“fmt”“gorm.io/driver/sqlite”
“gorm.io/gorm”
)// User モデル
type User struct {
gorm.Model
Name string
}// シャードされたデータベースへの接続を管理する
var shardMap = map[int]*gorm.DB{}func init() {
// シャードデータベースの初期化
for i := 1; i <= 2; i++ { db, err := gorm.Open(sqlite.Open(fmt.Sprintf("test_shar