Go関連のことを調べてみた

Go関連のことを調べてみた

テスト投稿

これはテスト投稿です。

元記事を表示

GoでSSG(静的サイトジェネレーター)を手作りしてみた

## 目的

この記事([Writing a Static Blog Generator in Go](https://www.zupzup.org/static-blog-generator-go/index.html))を読んでから自分でもやってみたいなと思っていたのでゴリっと作ってみました。

既存のSSGの置き換え等々は全く考えておらず、あくまでも興味駆動の開発になります。

## 作ったもの

https://github.com/K-Sato1995/go-simple-ssg

↑を使用して作った静的サイト

https://go-simple-ssg.vercel.app/

## 構成

やった事としては大枠

– マークダウン(記事のコンテンツ)+テンプレート(HTML)を元に静的なファイルを生成する部分
– CLIで↑を利用して誰でもプロジェクトの骨組みができるようにする部分

だけなので大したことはしていないのですが全体感としては下記のようになりました。

“`
./
├── parser/ (MarkdownをパースしてHTMLに変換する部分)
│ ├

元記事を表示

golang[Go言語]でインポート分のパスを指定する方法。

# 記事作成背景
import分変えたいなって思った時どこを変えたらよいか自分用のメモです。

# 修正内容
go.modのmoduleを変える。
“`go:go.mod
module business←ここ

go 1.15

require (
github.com/go-sql-driver/mysql v1.5.0
github.com/joho/godotenv v1.3.0
)

puts ‘The best way to log and share programmers knowledge.’
“`

元記事を表示

[Go言語] スライスを効率的にソートする方法

## はじめに
Go言語はそのシンプルさと効率の良さで人気を集めていると思っている。特に、スライス(動的配列)の操作はGoの重要な特徴の一つです。今回は、Go言語でスライスをソートする具体的な方法を、実用的な例を交えてご紹介しようと思います。

## サンプルコードと説明
“`go
package main

import (
“fmt”
“sort”
“time”
)

type Article struct {
Title string // 記事のタイトル
CreatedAt time.Time // 記事が作成された日時
}

// Articles は複数のArticleを含むスライスです。
type Articles []Article

// SortByCreatedAt はArticlesをCreatedAtフィールドに基づいて昇順にソートします。
func (a Articles) SortByCreatedAt() {
sort.SliceStable(a, func(i, j int) bool {
return a[i].Cre

元記事を表示

【GO】Gormを使って子テーブルのデータを取得したい

# はじめに
GORMを使って、親と子テーブルのデータを両方取得するのに苦労したので、備忘録として残しておきます。
GORMは[公式ドキュメント](https://gorm.io/ja_JP/docs/index.html)が丁寧に書かれているので、そちらも合わせてご覧いただくと良いかと思います。

# 結論
`preload`を使って、子テーブルのデータを取得しました。
`preload`とは、Eager Loading(イーガーローディング)の一種で、メインのクエリと一緒に関連するデータを予め読み込む機能です。これにより、N+1問題を避けて子テーブルのデータを取得できます。
`JOIN`と`SELECT`を使うことでも子テーブルのデータを取得できたのですが、今回はより簡単に使える`preload`を採用しました。
以下の構造体を例に`Preload`の使い方を簡単に説明します。
“`go
// UserがOrderをhas manyで持つ
type User struct {
Name string
Email string
Orders []Order
}

//

元記事を表示

【Go言語】for文の奇妙な動作

# 奇妙な動作をするfor文

まず、最初に奇妙な動作をするコードの例を出します。
以下のコードでは、for文の中でgoroutineを実行している。 **main** のgoroutineが終了するのを防ぐために `sync.WaitGroup` を使用している。 (WaitGroupを知らない人は[GoのWaitGroupを理解する](https://zenn.dev/yamato0211/articles/e3da679fd8dd6f)を参考)

“`go
func main() {
var wg = &sync.WaitGroup{}
for i := 0; i < 10; i++ { wg.Add(1) go func() { fmt.Println(i) wg.Done() }() } wg.Wait() } ``` [Go Playground](https://go.dev/play/p/x7rCyVdyO3j) これを実行すると、 ```:実行結果 10 10 10 10 ・・・・ 10 10 ``` `i < 9` と設定し

元記事を表示

ポートフォリオをGolang + Graphql + Next.jsで大改造した話

## はじめに

先日ポートフォリオ(http://www.piny940.com )を大改修したため、その記録を残します。

http://www.piny940.com

完成したコードは以下のGithubで公開していますので参考程度にどうぞ。

https://github.com/piny940/portfolio

## 環境
– Next.js 14.1.0
– Golang 1.21.1

## 抱えていた課題
今まで、ポートフォリオ上の「ブログ」や「技術スタック」「プロジェクト」のデータはすべてYAMLファイルで管理していました。
しかし、この方法には次の2つの問題点がありました。
– YAMLファイルに書かれたデータの整合性を保証できない
– データ更新にいちいちYAMLファイルを書き換える必要がある

特に2点目の問題についてはかなり深刻で、現状だとデータを書き換えるのに毎回ファイルを書き換えてPull Requestを出して・・・という作業が必要で、結果的にポートフォリオの更新をさぼってデータが古いまま放置されてしまっているという実情がありました。
また、

元記事を表示

【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 repository

import (
_ “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 endpoint

import “service”

type SomeEndpoint struct {
svc service.SomeServiceInterface
}

func NewSomeEndpoint(svc service.SomeServiceInterface) SomeEndpoint {
return SomeEndpoint{
svc: svc,
}
}
“`

“` golang
package service

type 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 schema

import (
“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 builder

WORKDIR /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

元記事を表示

OTHERカテゴリの最新記事