Skip to main content
Version: 2.8.x(Latest)

Editing a word uses the PUT method, which represents updating a resource.

Add Api


api/words/v1/words.go

type UpdateReq struct {  
g.Meta `path:"words/{id}" method:"put" sm:"Update" tags:"Word"`
Id uint `json:"id" v:"required"`
Word string `json:"word" v:"required|length:1,100" dc:"Word"`
Definition string `json:"definition" v:"required|length:1,300" dc:"Word Definition"`
ExampleSentence string `json:"example_sentence" v:"required|length:1,300" dc:"Example Sentence"`
ChineseTranslation string `json:"chinese_translation" v:"required|length:1,300" dc:"Chinese Translation"`
Pronunciation string `json:"pronunciation" v:"required|length:1,100" dc:"Pronunciation"`
ProficiencyLevel uint `json:"proficiency_level" v:"required|between:1,5" dc:"Proficiency Level, 1 minimum, 5 maximum"`
}

type UpdateRes struct {
}

Implement Logic


During editing, we also need to check if the word is unique. The existing checkWord function is not sufficient, as it checks including itself, so we need to improve it:

  • Add an id field; when the id is not 0, use the combination of id and word for judgment;
  • When id is 0, it represents a new addition, and only word is used for judgment.

internal/logic/words/words.go

package words

...

func Create(ctx context.Context, in *model.WordInput) error {
if err := checkWord(ctx, 0, in); err != nil {
return err
}
...
}

// checkWord does not check itself during an update
func checkWord(ctx context.Context, id uint, in *model.WordInput) error {
db := dao.Words.Ctx(ctx).Where("uid", in.Uid).Where("word", in.Word)
if id > 0 {
db = db.WhereNot("id", id)
}
count, err := db.Count()
if err != nil {
return err
}
if count > 0 {
return gerror.New("Word already exists")
}
return nil
}

Add the update logic:

internal/logic/words/words.go

package words  

...

func Update(ctx context.Context, id uint, in *model.WordInput) error {
if err := checkWord(ctx, id, in); err != nil {
return err
}

db := dao.Words.Ctx(ctx).Where("uid", in.Uid).Data(do.Words{
Word: in.Word,
Definition: in.Definition,
ExampleSentence: in.ExampleSentence,
ChineseTranslation: in.ChineseTranslation,
Pronunciation: in.Pronunciation,
ProficiencyLevel: in.ProficiencyLevel,
}).Where("id", id)
if in.Uid > 0 {
db = db.Where("uid", in.Uid)
}

_, err := db.Update()
if err != nil {
return err
}
return nil
}

...

When Uid is greater than zero, the Uid condition must be added to the ORM chain to prevent unauthorized access, the same applies to subsequent query and delete actions.

Controller Calls Logic


internal/controller/words/words_v1_update.go

package words  

import (
"context"

"star/internal/logic/users"
"star/internal/logic/words"
"star/internal/model"
"star/api/words/v1"
)

func (c *ControllerV1) Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error) {
uid, err := users.GetUid(ctx)
if err != nil {
return nil, err
}
err = words.Update(ctx, req.Id, &model.WordInput{
Uid: uid,
Word: req.Word,
Definition: req.Definition,
ExampleSentence: req.ExampleSentence,
ChineseTranslation: req.ChineseTranslation,
Pronunciation: req.Pronunciation,
ProficiencyLevel: model.ProficiencyLevel(req.ProficiencyLevel),
})
return nil, err
}

API Test


$ curl -X PUT http://127.0.0.1:8000/v1/words/1 \
-H "Authorization: eyJhbGci...5U" \
-H "Content-Type: application/json" \
-d '{
"word": "example_update",
"definition": "A representative form or pattern.",
"example_sentence": "This is an example sentence.",
"chinese_translation": "例子",
"pronunciation": "ɪɡˈzɑːmp(ə)l",
"proficiency_level": 3
}'

{
"code": 0,
"message": "",
"data": null
}

Execute the command to check if the data has been updated correctly:

$ SELECT * FROM words;
iduidworddefinitionexample_sentencechinese_translationpronunciationproficiency_levelcreated_atupdated_at
11example_updateA representative form or pattern.This is an example sentence.例子ɪɡˈzɑːmp(ə)l32024/11/12 15:38:502024/11/12 15:38:50