Code reading

Code reading

2021-03-20
code

Varibales

宣言のタイミング

func(w http.ResponseWriter, r *http.Request) {
    header := r.Header.Get("Authorization")
    // 1: 
    // - tokenStr := r.Header.Get("Authorization")
    // 後にheaderをtokenStrに入れて処理するが、header == ""はheaderに値があるかのチェック
    // まだここではTokenに関する処理を意識していないのでheaderとう命名にしている

    if header == "" {
    // 1:
    // - if tokenStr == ""
        next.ServeHTTP(w, r)
        return
    }

    // 2: 直接ParseToken(header)とせずに、tokenStrに入れて意図をわかりやすく
    tokenStr := header
    username, err := jwt.ParseToken(tokenStr)
    if err != nil {
        next.ServeHTTP(w, r)
        return
    }

    // 3. WithValueまでの処理がひとかたまりそのため、先にuserを作りそれに値を設定している
    user := users.User{Username: username}
    id, err := users.GetUserIdByUsername(username)
    if err != nil {
        next.ServeHTTP(w, r)
        return
    }
    // 3. このタイミングで始めてuserを作ることもできるが前述の理由ですでに作ったuserを利用
    user.ID = strconv.Itoa(id)
    ctx := context.WithValue(r.Context(), userCtxKey, &user)
}

Ref. https://www.howtographql.com/graphql-go/6-authentication/

インスタンス生成後の参照

func (r *mutationResolver) CreateUser(ctx context.Context, input model.NewUser) (string, error) {
    var user users.User
    user.Username = input.Username
    user.Password = input.Password
    user.Create()
    // 入力のinput.Usernameではなく、user.Usernameを使用
    // GenerateTokenしたいのはuserのnameであるため、Createしたuserの値を参照させている
    token, err := jwt.GenerateToken(user.Username)
    ...

変数の中に別の変数を設定する時の宣言順序

func (r *mutationResolver) CreateLink(ctx context.Context, input model.NewLink) (*model.Link, error) {
    // Good
    # linkにuserを含む関係先にlink, userをvar
    var link model.Link
    var user model.User
    link.Address = input.Address
    link.Title = input.Title
    #   linkの生成中にuserを更新して
    user.Name = "test"
    #   linkにセット
    link.User = &user
    return &link, nil

    // Bad
    // var link model.Link
    // link.Address = input.Address
    // link.Title = input.Title
    //
    // # userの宣言を間にいれるとややこしい
    // var user model.User
    // user.Name = "test"
    //
    // link.User = &user
    // return &link, nil
}

Ref. https://www.howtographql.com/graphql-go/3-mutations/

Returns

DB値と返り値用の変数

func (r *queryResolver) Links(ctx context.Context) ([]*model.Link, error) {
    var resultLinks []*model.Link
    var dbLinks []links.Link
    dbLinks = links.GetAll()
    for _, link := range dbLinks {
        resultLinks = append(resultLinks, &model.Link{
            ID:link.ID,
            Title:link.Title,
            Address:link.Address,
        })
    }
    return resultLinks, nil
}

Model

Userの認証はUserに必要な値を設定してAuthをコール

func (user *User) Authenticate() bool {
    stmt, _ := database.Db.Prepare("SELECT Password from Users WHERE Username = ?")
    row := stmt.QueryRow(user.Username)
    var hashedPassword string
    _ = row.Scan(&hashedPassword)
    return CheckPasswordHash(user.Password, hashedPassword)
}