
バックエンド開発では、特にデータベースクエリやAPIサーバーの実装を扱う際に、反復的なボイラープレートコードが多くなりがちです。このコードを手動で記述して維持することは、エラーが発生しやすく、時間がかかります。コード生成(codegen)ツールは、宣言的な仕様から型安全で効率的、かつ保守可能なコードを生成することで、これらのタスクを自動化するのに役立ちます。
この記事では、2つの人気のあるcodegenツールを使用して、Goでのバックエンドロジックを簡素化する方法を探ります:
sqlcは、SQLクエリからGoコードを生成するツールです。.sqlファイルにSQLクエリを記述すると、sqlcはそれらのクエリを型安全なパラメータと結果で実行するGo関数を生成します。
sqlc.yamlを設定して、入出力を指定します。sqlc generateを実行してGoコードを生成します。シンプルなusersテーブルがあるとします:
-- schema.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
);そして、メールアドレスでユーザーを取得するクエリ:
-- queries.sql
-- name: GetUserByEmail :one
SELECT id, name, email FROM users WHERE email = $1;sqlc.yaml設定:
version: "1"
packages:
- name: "db"
path: "./db"
queries: "./queries.sql"
schema: "./schema.sql"
engine: "postgresql"実行:
sqlc generateこれにより、次のようなメソッドを持つGoコードが生成されます:
func (q *Queries) GetUserByEmail(ctx context.Context, email string) (User, error)バックエンドで次のように使用できます:
user, err := dbQueries.GetUserByEmail(ctx, "alice@example.com")
if err != nil {
// エラー処理
}
fmt.Println("User:", user.Name)これにより、手動でのSQL文字列処理や行のスキャンが不要になり、コードがよりクリーンで安全になります。
oapi-codegenは、OpenAPI (Swagger) 仕様からGoサーバー(およびクライアント)コードを生成します。インターフェースとリクエスト/レスポンス型を作成するため、ビジネスロジックの実装に集中できます。
oapi-codegenを実行してGoサーバーコードを生成します。シンプルなOpenAPI仕様 api.yaml を考えてみましょう:
openapi: 3.0.0
info:
title: User API
version: 1.0.0
paths:
/users/{email}:
get:
summary: Get user by email
parameters:
- name: email
in: path
required: true
schema:
type: string
responses:
"200":
description: User found
content:
application/json:
schema:
$ref: "#/components/schemas/User"
"404":
description: User not found
components:
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
email:
type: stringサーバーコードを生成:
oapi-codegen -generate types,server -package api -o api.gen.go api.yamlこれにより以下が生成されます:
User構造体)ServerInterface:GetUsersEmail(ctx context.Context, email string) (api.User, error)インターフェースを実装:
type ServerImpl struct {
db *db.Queries
}
func (s *ServerImpl) GetUsersEmail(ctx context.Context, email string) (api.User, error) {
user, err := s.db.GetUserByEmail(ctx, email)
if err != nil {
return api.User{}, err
}
return api.User{
Id: int64(user.ID),
Name: user.Name,
Email: user.Email,
}, nil
}サーバーを接続:
router := api.NewRouter(&ServerImpl{db: dbQueries})
http.ListenAndServe(":8080", router)sqlcとoapi-codegenを併用することで、データベースアクセスとAPIサーバーコードの生成を自動化し、Goでのバックエンド開発を大幅に簡素化できます。このアプローチにより、ボイラープレートが削減され、安全性が向上し、開発が加速するため、最も重要なこと、つまりアプリケーションのコアロジックに集中できるようになります。
© Melvin Laplanche - All rights reserved.