GoLang バックエンドを使い始める

この記事の一部は機械翻訳を使ってるよ

Go バックエンドのシンプルな (非技術的なフレームワーク) 実装

~~皆さんご存知のとおり、~~バックエンド開発は一般的にインターフェース指向開発、つまり CRUD エンジニアです。この記事では、Go を使用して、データベースからデータを読み取り、JSON データを返す方法について説明します。

データベース

この例では、MySQL データベースのカテゴリ テーブルからカテゴリ名と ID を読み取ります。テーブル構造は次のとおりです。

DROP TABLE IF EXISTS categories ;
CREATE TABLE categories (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description VARCHAR(255)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

プロジェクト構造

この例のプロジェクト構造は次のようになります。

project/
├── database/       // データベースパッケージ
│   └── database.go // データベース接続
├── handler/        // ハンドラパッケージ
│   └── category.go // カテゴリ関連のインターフェース
├── model/          // データモデルパッケージ
│   ├── category.go // カテゴリテーブルモデル
│   └── response.go // レスポンスデータモデル
├── router/         // ルーティングパッケージ
│   └── router.go   // ルーティング設定
├── utils           // ツールキット
│   └── response.go // 統合レスポンス
├── main.go         // プログラムエントリ

次にディレクトリについて説明します

database

このパッケージはデータベースへの接続を管理します

// database.go
package database

import (
    "database/sql"
    "fmt"
    "log"

    _ "github.com/go-sql-driver/mysql"
)

var DB *sql.DB

func InitDB() {
    var err error

    dsn := "username:password@tcp(address:3306)/name?charset=utf8"
    DB, err = sql.Open("mysql", dsn)
    if err != nil {
        log.Fatalf("Failed to open database: %v", err)
    }

    // Test Connect
    err = DB.Ping()
    if err != nil {
        log.Fatalf("Failed to ping database: %v", err)
    }

    fmt.Println("Successfully connected Database!")
}

handler

このパッケージは、特定の処理のロジック(3 層アーキテクチャの service に似ています)を処理して、データベース処理も階層化できます(Mapper に似ています)が、これは単なる簡単な例です、それだけです〜

// category.go
package handler

import (
    "net/http"
    "project/database"
    "project/model"
    "project/utils"
)

func GetCategories(w http.ResponseWriter, r *http.Request) {
    // Select Database
    rows, err := database.DB.Query("select id,name from categories")
    if err != nil {
        http.Error(w, "Failed to query Categories", http.StatusInternalServerError)
        return
    }
    defer rows.Close()

    // analyze data
    var categories []model.Category
    for rows.Next() {
        var category model.Category
        err = rows.Scan(&category.Id, &category.Name)
        if err != nil {
            utils.JSONResponse(w, http.StatusInternalServerError, "Failed to analyze Categories", nil)
            //http.Error(w, "Failed to analyze Categories", http.StatusInternalServerError)
            return
        }
        categories = append(categories, category)
    }

    // return JSON
    //w.Header().Set("Content-Type", "application/json")
    //json.NewEncoder(w).Encode(categories)
    utils.JSONResponse(w, http.StatusOK, "", categories)
}

コメントアウトされた内容は統合レスポンスインターフェースには適用されず、JSON が直接返されます。

model

ここでのデータモデルは、一般的にフロントエンドから受け取るもの、データベースから受け取るもの、フロントエンドに返すものの 3 つに分けられます。これは単純な例なので、細かくは説明していません。

// category.go
package model

type Category struct {
    Id          int    `json:"id"`
    Name        string `json:"name"`
    Description string `json:"description"`
}

応答のデータモデルは

package model

type Response struct {
    Code int         `json:"code"`
    Msg  string      `json:"msf"`
    Data interface{} `json:"data"`
}

router

このパッケージはルーティング、つまり、どのパスにアクセスして対応する処理ロジックを指定するかを管理します(3 層アーキテクチャの controller に似ています)

// router.go
package router

import (
    "github.com/gorilla/mux"
    "project/handler"
)

func InitRouter() *mux.Router {
    router := mux.NewRouter()
    router.HandleFunc("/categories", handler.GetCategories).Methods("GET")
    return router
}

utils

このパッケージはツールクラスであり、一般的なツールを定義するために使用されます

// response.go
package utils

import (
    "encoding/json"
    "log"
    "net/http"
    "project/model"
)

func JSONResponse(w http.ResponseWriter, code int, message string, data interface{}) {
    w.Header().Set("Content-Type", "application/json; charset=utf-8")
    w.WriteHeader(http.StatusOK)
    err := json.NewEncoder(w).Encode(model.Response{Code: code, Msg: message, Data: data})
    if err != nil {
        log.Fatal(err)
        return
    }
}

main

プログラムエントリー

// main.go
package main

import (
    "log"
    "net/http"
    "project/database"
    "project/router"
)

func main() {
    // init Database
    database.InitDB()

    // Init Router
    r := router.InitRouter()

    // start
    log.Println("Starting server on port 8848")
    log.Fatal(http.ListenAndServe(":8848", r))
}

go run main.go を実行すると、プログラムはポート 8848 をリッスンします。

This post is licensed under CC BY-NC-SA 4.0 by the author.
最終更新 2025-01-28 21:30 +0900

Hugo で構築されています。 | テーマ StackJimmy によって設計されています。