通过HTTP请求向现有列表追加数据

huangapple go评论121阅读模式
英文:

Appending to an existing list via http request

问题

我正在制作一个使用Echo创建简单REST API的过程中。我有一个变量,它是以下映射,基于我创建的结构体:

  1. type Checklist struct {
  2. ID int `json:"id"`
  3. Title string `json:"title"`
  4. Lines []string `json:"lines"`
  5. AuthorName string `json:"authorName"`
  6. AuthorID int `json:"authorID"`
  7. Tags []Tag `json:"tags"`
  8. }
  9. var (
  10. checklists = map[int]*Checklist{}
  11. checklistSeq = 1
  12. checklistLock = sync.Mutex{}
  13. )

在创建新的检查清单并将其附加到checklists变量之后,如何发送一个请求,将新的行添加到新的检查清单的Lines字段中?

我想到的解决方案是:

  1. func createChecklist(c echo.Context) error {
  2. checklistLock.Lock()
  3. defer checklistLock.Unlock()
  4. newChecklist := &Checklist{
  5. ID: checklistSeq,
  6. Lines: make([]string, 0),
  7. Tags: make([]Tag, 0),
  8. }
  9. if err := c.Bind(newChecklist); err != nil {
  10. return err
  11. }
  12. checklists[newChecklist.ID] = newChecklist
  13. checklistSeq++
  14. return c.JSON(http.StatusOK, newChecklist)
  15. }
  16. func addLine(c echo.Context) error {
  17. checklistLock.Lock()
  18. defer checklistLock.Unlock()
  19. id, _ := strconv.Atoi(c.Param("id"))
  20. checklist := *checklists[id]
  21. line := []string{""}
  22. if err := c.Bind(line); err != nil {
  23. return err
  24. }
  25. checklist.Lines = line
  26. return c.JSON(http.StatusCreated, checklists)
  27. }

然而,当我测试这个处理程序时,它给我返回以下结果:

  1. // 1: 创建一个新的检查清单
  2. $ curl -X POST -H 'Content-Type: application/json' -d '{"title": "test"}' localhost:1234/checklist
  3. >> {"id":1,"title":"test","lines":[],"authorName":"","authorID":0,"tags":[]}
  4. // 2: 检查是否已创建检查清单
  5. $ curl -X GET localhost:1234/checklist
  6. >> {"1":{"id":1,"title":"test","lines":[],"authorName":"","authorID":0,"tags":[]}}
  7. // 3: 尝试创建新行
  8. $ curl -X POST -H 'Content-Type: application/json' -d '{"lines": "test123"}' localhost:1234/checklist/1
  9. >> curl: (52) Empty reply from server
  10. // 4: 确认未创建新行
  11. $ curl -X GET localhost:1234/checklist
  12. >> {"1":{"id":1,"title":"test","lines":[],"authorName":"","authorID":0,"tags":[]}}

所以这个函数实际上不起作用,因为既没有从POST请求到适当的路由返回预期的响应,也没有将行添加到字段中。

英文:

I'm in the process of making a simple REST API using Echo. I have a variable which is the following map, based on this struct I've made:

  1. type Checklist struct {
  2. ID int `json:"id"`
  3. Title string `json:"title"`
  4. Lines []string `json:"lines"`
  5. AuthorName string `json:"authorName"`
  6. AuthorID int `json:"authorID"`
  7. Tags []Tag `json:"tags"`
  8. }
  9. var (
  10. checklists = map[int]*Checklist{}
  11. checklistSeq = 1
  12. checklistLock = sync.Mutex{}
  13. )

After creating a new checklist and appending it to the checklists variable, how can I send a request which appends a new line in the Lines field of the new checklist?

The solution I thought up was this:

  1. func createChecklist(c echo.Context) error {
  2. checklistLock.Lock()
  3. defer checklistLock.Unlock()
  4. newChecklist := &Checklist{
  5. ID: checklistSeq,
  6. Lines: make([]string, 0),
  7. Tags: make([]Tag, 0),
  8. }
  9. if err := c.Bind(newChecklist); err != nil {
  10. return err
  11. }
  12. checklists[newChecklist.ID] = newChecklist
  13. checklistSeq++
  14. return c.JSON(http.StatusOK, newChecklist)
  15. }
  16. func addLine(c echo.Context) error {
  17. checklistLock.Lock()
  18. defer checklistLock.Unlock()
  19. id, _ := strconv.Atoi(c.Param("id"))
  20. checklist := *checklists[id]
  21. line := []string{""}
  22. if err := c.Bind(line); err != nil {
  23. return err
  24. }
  25. checklist.Lines = line
  26. return c.JSON(http.StatusCreated, checklists)
  27. }

However, when I test this handler, it gives me the following results:

  1. // 1: Creating a new checklist
  2. $ curl -X POST -H 'Content-Type: application/json' -d '{"title": "test"}' localhost:1234/checklist
  3. >> {"id":1,"title":"test","lines":[],"authorName":"","authorID":0,"tags":[]}
  4. // 2: Check to see the checklist has been created.
  5. $ curl -X GET localhost:1234/checklist
  6. >> {"1":{"id":1,"title":"test","lines":[],"authorName":"","authorID":0,"tags":[]}}
  7. // 3: Attempting to create a new line
  8. $ curl -X POST -H 'Content-Type: application/json' -d '{"lines": "test123"}' localhost:1234/checklist/1
  9. >> curl: (52) Empty reply from server
  10. // 4: Confirming it hasn't been created.
  11. $ curl -X GET localhost:1234/checklist
  12. >> {"1":{"id":1,"title":"test","lines":[],"authorName":"","authorID":0,"tags":[]}}

So the function doesn't actually work, since neither the expected response comes back from pinging the POST to the appropriate route or the line is actually added to the field.

答案1

得分: 0

  1. func addLine(c echo.Context) error {
  2. checklistLock.Lock()
  3. defer checklistLock.Unlock()
  4. id, err := strconv.Atoi(c.Param("id"))
  5. if err != nil {
  6. return err
  7. }
  8. // 不要解引用 *Checklist
  9. cl, ok := checklists[id]
  10. if !ok {
  11. return echo.ErrNotFound
  12. }
  13. // 使用与预期JSON相同的结构
  14. var input struct { Lines []string `json:"lines"` }
  15. // 始终传递 c.Bind 的指针
  16. if err := c.Bind(&input); err != nil {
  17. return err
  18. }
  19. // 不要覆盖先前写入的行,使用 append
  20. cl.Lines = append(cl.Lines, input.Lines...)
  21. return c.JSON(http.StatusOK, cl)
  22. }

现在尝试:

  1. $ curl -X POST -H 'Content-Type: application/json' -d '{"lines": ["test123"]}' localhost:1234/checklist/1
英文:
  1. func addLine(c echo.Context) error {
  2. checklistLock.Lock()
  3. defer checklistLock.Unlock()
  4. id, err := strconv.Atoi(c.Param("id"))
  5. if err != nil {
  6. return err
  7. }
  8. // do not deref *Checklist
  9. cl, ok := checklists[id]
  10. if !ok {
  11. return echo.ErrNotFound
  12. }
  13. // use same structure as the expected JSON
  14. var input struct { Lines []string `json:"lines"` }
  15. // always pass a pointer to c.Bind
  16. if err := c.Bind(&input); err != nil {
  17. return err
  18. }
  19. // do not overwrite previously written lines, use append
  20. cl.Lines = append(cl.Lines, input.Lines...)
  21. return c.JSON(http.StatusOK, cl)
  22. }

Now try:

  1. $ curl -X POST -H 'Content-Type: application/json' -d '{"lines": ["test123"]}' localhost:1234/checklist/1

(notice that "test123" is enclosed in brackets)

huangapple
  • 本文由 发表于 2023年3月3日 16:04:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75624560.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定