【学習記録】ログインAPIコーディング

今日はログインのAPIをコーディングしていきました。
まずはアプリが一通り動くことを目標にしているので大雑把に実装しておいて、後から仕様を固めていきます。

コミットは以下です。

github.com

入出力用の構造体はdomain/model.goで定義しています。

// RequestParam リクエストパラメータ
type RequestParam struct {
    UserName string `json:"user_name"`
    Password string `json:"password"`
}

// ResponseParam レスポンスデータ
type ResponseParam struct {
    UserID    int    `json:"user_id"`
    UserName  string `json:"user_name"`
    Note      string `json:"note"`
    IconImage string `json:"icond_image"`
}

ユーザー名とパスワードを引数で受け取って、API内部でSQL発行してusersテーブルからユーザーID、ユーザー名、備考欄、アイコン用画像を取得してResponseParam構造体に格納して返す、という設計にしてます。

APISQLを発行するコードは以下のように書きました。

 err := db.Table("users").
        Select(`
            user_id
        , user_name
        , note
        , icon_image`).
        Where(`user_name = ?
        AND user_password = ?`, param.UserName, param.Password).
        Find(&result).Error

    return result, err

GoのORマッパーにはGormを使用しています。

gorm.io

今は現場でGormを使っているので慣れてるから個人開発でもGormを使ってますが、後々は知見広げるために他のORマッパーを試したりGoで生SQLを書く方法に変えたりなども検討しても良いかもなと思ってます。
しばらくはGormで開発します。

APIの入出力の処理はinfra/web/handler.goで書いています。

func Login(c echo.Context) error {
    param := domain.RequestParam{}

    if err := c.Bind(&param); err != nil {
        return err
    }

    userdata, err := service.FetchUserData(param)

    if err != nil {
        return err
    }

    return c.JSON(http.StatusOK, userdata)
}

引数を受け取る構造体を変数paramで初期化して、c.Bindで引数を格納し、処理自体は別の関数で行って、返ってきた値を返す、という設計にしています。

APIをコーディングする時に簡単なテストも書くようにしているので、以下のように書きました。

func TestApi007Test(t *testing.T) {
    apitest.New().
        Handler(router.NewRouter()).
        Post("/login").
        Header("Content-Type", "application/json").
        BodyFromFile("testdata/test001.golden").
        Expect(t).
        Status(http.StatusOK).
        End()
}

使用しているライブラリはapitestというGo言語のテスト用ライブラリです。

github.com

BodyFronFileでAPIへ送るリクエストを書いているgoldenファイルを指定しています。

test001.goldenには以下のようにそのままjsonを記述。

{"user_name":"user1","password":"password1"}

とりあえず正常系のテストケースのみできたので一旦このタスクとしてはOKとしておいて、後からテストケースを増やすタスクを進めます。

パスワードは暗号化してDBに格納したいところですが、ちょっと時間がかかりそうなのでそれも後から実装します。

次はフロントエンドのログイン処理をコーディングしたいと思います。