在這個最後要完善 User Login 的功能
完整的程式碼放在這邊可以做參考,如果真的改到一半不知道怎麼改的話
因為原本的教學大概有點年代,直接複製是沒辦法用的XD
https://github.com/whitefloor/Go-GraphQL
到這一篇就是全部程式碼都寫完了,不過還要找時間看一些進階資料
schema.resolvers.go 加強 CreateLink 錯誤處理以及新增回傳
func (r *mutationResolver) CreateLink(ctx context.Context, input model.NewLink) (*model.Link, error) {
	user := auth.ForContext(ctx)
	if user == nil {
		return &model.Link{}, fmt.Errorf("access denied")
	}
	var link links.Link
	link.User = user
	linkID := link.Save()
	link.Title = input.Title
	link.Address = input.Address
	graphqlUser := &model.User{
		ID:   user.ID,
		Name: user.Username,
	}
	return &model.Link{ID: strconv.FormatInt(linkID, 10), Title: link.Title, Address: link.Address, User: graphqlUser}, nil
}
schema.resolvers.go 從 Database 取得 User 資料
func (r *queryResolver) Links(ctx context.Context) ([]*model.Link, error) {
	var resultLinks []*model.Link
	dbLinks := links.GetAll()
	for _, link := range dbLinks {
		graphqlUser := &model.User{
			ID:   link.User.ID,
			Name: link.User.Username,
		}
		resultLinks = append(resultLinks, &model.Link{ID: link.ID, Title: link.Title, Address: link.Address, User: graphqlUser})
	}
	return resultLinks, nil
}
internal/links/links.go Save method 改寫 Query
func (link Link) Save() int64 {
	//#3
	stmt, err := mig.Db.Prepare("INSERT INTO Links(Title,Address, UserID) VALUES(?,?, ?)")
	if err != nil {
		log.Fatal(err)
	}
	//#4
	res, err := stmt.Exec(link.Title, link.Address, link.User.ID)
		if err != nil {
		log.Fatal(err)
	}
	//#5
	id, err := res.LastInsertId()
	if err != nil {
		log.Fatal("Error:", err.Error())
	}
	log.Print("Row inserted!")
	return id
}
internal/links/links.go 改寫 GetAll funciton
func GetAll() []Link {
	stmt, err := mig.Db.Prepare("select L.id, L.title, L.address, L.UserID, U.Username from Links L inner join Users U on L.UserID = U.ID") // changed
	if err != nil {
		log.Fatal(err)
	}
	defer stmt.Close()
	rows, err := stmt.Query()
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	var links []Link
	var username string
	var id string
	for rows.Next() {
		var link Link
		err := rows.Scan(&link.ID, &link.Title, &link.Address, &id, &username) // changed
		if err != nil {
			log.Fatal(err)
		}
		link.User = &users.User{
			ID:       id,
			Username: username,
		} // changed
		links = append(links, link)
	}
	if err = rows.Err(); err != nil {
		log.Fatal(err)
	}
	return links
}
到這邊我們全部的程式碼已經全部撰寫完成了$ go run server.go 打開 http://localhost:8080/
先使用以下 Query,會收到 access denied
mutation {
  createLink(input: {title: "real link!", address: "www.graphql.org"}){
    user{
      name
    }
  }
}
接著使用 Login 或是 CreateUser 拿到新 Token 後
在網頁下方有可以新增 HTTP Header 的地方,新增 Token 後即可成功 CreateLink
{
  "Authorization": "" // use your own generated token
}

https://www.howtographql.com/graphql-go/8-logged-in-user-object/
https://relay.dev/docs/guides/graphql-server-specification/
https://graphql.org/learn/