英文:
Appending to an existing list via http request
问题
我正在制作一个使用Echo创建简单REST API的过程中。我有一个变量,它是以下映射,基于我创建的结构体:
type Checklist struct {
ID int `json:"id"`
Title string `json:"title"`
Lines []string `json:"lines"`
AuthorName string `json:"authorName"`
AuthorID int `json:"authorID"`
Tags []Tag `json:"tags"`
}
var (
checklists = map[int]*Checklist{}
checklistSeq = 1
checklistLock = sync.Mutex{}
)
在创建新的检查清单并将其附加到checklists变量之后,如何发送一个请求,将新的行添加到新的检查清单的Lines字段中?
我想到的解决方案是:
func createChecklist(c echo.Context) error {
checklistLock.Lock()
defer checklistLock.Unlock()
newChecklist := &Checklist{
ID: checklistSeq,
Lines: make([]string, 0),
Tags: make([]Tag, 0),
}
if err := c.Bind(newChecklist); err != nil {
return err
}
checklists[newChecklist.ID] = newChecklist
checklistSeq++
return c.JSON(http.StatusOK, newChecklist)
}
func addLine(c echo.Context) error {
checklistLock.Lock()
defer checklistLock.Unlock()
id, _ := strconv.Atoi(c.Param("id"))
checklist := *checklists[id]
line := []string{""}
if err := c.Bind(line); err != nil {
return err
}
checklist.Lines = line
return c.JSON(http.StatusCreated, checklists)
}
然而,当我测试这个处理程序时,它给我返回以下结果:
// 1: 创建一个新的检查清单
$ curl -X POST -H 'Content-Type: application/json' -d '{"title": "test"}' localhost:1234/checklist
>> {"id":1,"title":"test","lines":[],"authorName":"","authorID":0,"tags":[]}
// 2: 检查是否已创建检查清单
$ curl -X GET localhost:1234/checklist
>> {"1":{"id":1,"title":"test","lines":[],"authorName":"","authorID":0,"tags":[]}}
// 3: 尝试创建新行
$ curl -X POST -H 'Content-Type: application/json' -d '{"lines": "test123"}' localhost:1234/checklist/1
>> curl: (52) Empty reply from server
// 4: 确认未创建新行
$ curl -X GET localhost:1234/checklist
>> {"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:
type Checklist struct {
ID int `json:"id"`
Title string `json:"title"`
Lines []string `json:"lines"`
AuthorName string `json:"authorName"`
AuthorID int `json:"authorID"`
Tags []Tag `json:"tags"`
}
var (
checklists = map[int]*Checklist{}
checklistSeq = 1
checklistLock = sync.Mutex{}
)
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:
func createChecklist(c echo.Context) error {
checklistLock.Lock()
defer checklistLock.Unlock()
newChecklist := &Checklist{
ID: checklistSeq,
Lines: make([]string, 0),
Tags: make([]Tag, 0),
}
if err := c.Bind(newChecklist); err != nil {
return err
}
checklists[newChecklist.ID] = newChecklist
checklistSeq++
return c.JSON(http.StatusOK, newChecklist)
}
func addLine(c echo.Context) error {
checklistLock.Lock()
defer checklistLock.Unlock()
id, _ := strconv.Atoi(c.Param("id"))
checklist := *checklists[id]
line := []string{""}
if err := c.Bind(line); err != nil {
return err
}
checklist.Lines = line
return c.JSON(http.StatusCreated, checklists)
}
However, when I test this handler, it gives me the following results:
// 1: Creating a new checklist
$ curl -X POST -H 'Content-Type: application/json' -d '{"title": "test"}' localhost:1234/checklist
>> {"id":1,"title":"test","lines":[],"authorName":"","authorID":0,"tags":[]}
// 2: Check to see the checklist has been created.
$ curl -X GET localhost:1234/checklist
>> {"1":{"id":1,"title":"test","lines":[],"authorName":"","authorID":0,"tags":[]}}
// 3: Attempting to create a new line
$ curl -X POST -H 'Content-Type: application/json' -d '{"lines": "test123"}' localhost:1234/checklist/1
>> curl: (52) Empty reply from server
// 4: Confirming it hasn't been created.
$ curl -X GET localhost:1234/checklist
>> {"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
func addLine(c echo.Context) error {
checklistLock.Lock()
defer checklistLock.Unlock()
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return err
}
// 不要解引用 *Checklist
cl, ok := checklists[id]
if !ok {
return echo.ErrNotFound
}
// 使用与预期JSON相同的结构
var input struct { Lines []string `json:"lines"` }
// 始终传递 c.Bind 的指针
if err := c.Bind(&input); err != nil {
return err
}
// 不要覆盖先前写入的行,使用 append
cl.Lines = append(cl.Lines, input.Lines...)
return c.JSON(http.StatusOK, cl)
}
现在尝试:
$ curl -X POST -H 'Content-Type: application/json' -d '{"lines": ["test123"]}' localhost:1234/checklist/1
英文:
func addLine(c echo.Context) error {
checklistLock.Lock()
defer checklistLock.Unlock()
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return err
}
// do not deref *Checklist
cl, ok := checklists[id]
if !ok {
return echo.ErrNotFound
}
// use same structure as the expected JSON
var input struct { Lines []string `json:"lines"` }
// always pass a pointer to c.Bind
if err := c.Bind(&input); err != nil {
return err
}
// do not overwrite previously written lines, use append
cl.Lines = append(cl.Lines, input.Lines...)
return c.JSON(http.StatusOK, cl)
}
Now try:
$ curl -X POST -H 'Content-Type: application/json' -d '{"lines": ["test123"]}' localhost:1234/checklist/1
(notice that "test123"
is enclosed in brackets)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论